#ifndef _NSREATTR_ // -*-c++-*-
#define _NSREATTR_
//----------------------------------------------------------------------
//  nsrEAttr.h
//   Header file that handles UDF extended attributes
//
//      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.
//
//  CLASSES:
//    EARegistryEntry
//    EARegistry
//    EAView
//    ShortEAView
//    LongEAView
//    EAViewItem
//    ShortEAViewItem
//    EAViewHeaderItem
//    LongEAViewItem
//    GroupOfShortsEAViewItem
//    EASpace
//    EmbeddedEASpace
//    ExternalEASpace
//  
//----------------------------------------------------------------------
// $Source: /projects/HMS/nsr/udfCore/ss/nsrEAttr.h,v $
// $Revision: 1.11 $ $Author: hmgr $
// $State: Exp $    $Locker:  $
// $Date: 96/05/21 23:18:13 $
//



// Define some symbols to control compilation of code for printing and testing.
#define ENABLE_PRINTING
//#define DEBUG_EA__GENERAL
#if defined DEBUG_EA__GENERAL
#define DEBUG_EA__TRACK_DISK_ALLOCATION
//#define DEBUG_EA__BASIC_DISK_SPACE_TRACE
//#define DEBUG_EA__VERBOSE_DISK_SPACE_TRACE
#endif

// Forward references:
class EAViewItem;
class ShortEAViewItem;
class LongEAViewItem;
class GroupOfShortsEAViewItem;
class EASpace;
class Node;

// Define the maximum number of entries in the EA Registry:
#define EA_REGISTRY__MAX_ENTRIES    64

// Define a structure and size for the data that keeps track of the disk sectors that are
// allocated, for testing.
#if defined DEBUG_EA__TRACK_DISK_ALLOCATION
struct ABT {
    UINT32      startBlock;
    UINT32      endBlock;
};
#define MAX_ALLOC_TAB_ENTRIES     256
#endif

// Declare some static null objects, to be returned in error cases where a reference must be
// returned, but the values in the object itself are not meaningful.  If you can think of a
// better way to do this, you're welcome to do it!
static ByteArray        nullBA;
static LogExtentList    *nullLEL;




//----------------------------------------------------------------------
// ENUM: EAPlc
//
//  Definitions of the various restrictions on which EA space (embedded or external) an
//  extended attribute may be in.
//
// DEFINITIONS:
//  0    ea_MayBeInEitherSpace
//  1    ea_MustBeInEmbeddedSpace
//  2    ea_ShouldBeInEmbeddedSpace
//  3    ea_MustBeInExternalSpace
//  4    ea_ShouldBeInExternalSpace
//
// USES:
//
// ABUSES:
//
// NOTES:
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------
enum EAPlc {
    ea_MayBeInEitherSpace = 0,
    ea_MustBeInEmbeddedSpace,
    ea_ShouldBeInEmbeddedSpace,
    ea_MustBeInExternalSpace,
    ea_ShouldBeInExternalSpace
};




//----------------------------------------------------------------------
// ENUM: EACategory
//
//  Definitions of the various categories of extended attributes.
//
// DEFINITIONS:
//  0    ea_InvalidCategory
//  1    ea_ISOCategory
//  2    ea_ImplUseCategory
//  3    ea_ApplUseCategory
//
// USES:
//
// ABUSES:
//
// NOTES:
//  IMPORTANT: For the EAViewItem::compareForInsertion method to work correctly,
//  these items must be in the order ea_ISOCategory, ea_ImplUseCategory, ea_ApplUseCategory
//  (see OSTA 3.3.4).
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------
enum EACategory {
    ea_InvalidCategory = 0,
    ea_ISOCategory,
    ea_ImplUseCategory,
    ea_ApplUseCategory
};




//----------------------------------------------------------------------
// ENUM: EASpaceType
//
//  Definitions of the various classes of EA space.
//
// DEFINITIONS:
//  0    NoEASpaceType
//  1    EmbeddedEASpaceType
//  2    ExternalEASpaceType
//
// USES:
//  Returned by the isA() methods of the various EA space classes.
//
// ABUSES:
//
// NOTES:
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------
enum EASpaceType {
    NoEASpaceType = 0,              // EAViewItems that are not in any
                                    // EASpace have this type 
    EmbeddedEASpaceType,
    ExternalEASpaceType
};




//----------------------------------------------------------------------
// ENUM: EAViewItemType
//
//  Definitions for the various classes of EA view items.
//
// DEFINITIONS:
//  1    EAViewHeaderItemType
//  2    ShortEAViewItemType
//  3    LongEAViewItemType
//  4    GroupOfShortsEAViewItemType
//
// USES:
//  Returned by the isA() methods of the various EA view item classes.
//
// ABUSES:
//
// NOTES:
//  IMPORTANT: For the EAViewItem::compareForInsertion method to work
//  correctly, EAViewHeaderItemType must be before any others, and
//  ShortEAViewItemType must be before LongEAViewItemType (see OSTA
//  3.3.4).  Other than these rules, the relative order of
//  GroupOfShortsEAViewItemType with any other entry has no
//  significance.
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------
enum EAViewItemType {
    EAViewHeaderItemType = 1,
    ShortEAViewItemType = 2,
    LongEAViewItemType = 3,
    GroupOfShortsEAViewItemType = 4
};




//----------------------------------------------------------------------
// ENUM: EARegistrySymbols
//
//  Definitions for all regKeys--the keys to EARegistry entries.
//
// DEFINITIONS:
//  0    ea_InvalidKey
//  1    ea_Hdr_Key
//  2    ea_ISO_CharSetInfo_Key
//  3    ea_ISO_AltPermissions_Key
//  4    ea_ISO_FileTimes_Key
//  5    ea_ISO_InfoTimes_Key
//  6    ea_ISO_DeviceSpec_Key
//  7    ea_ISO_Default_Key
//  8    ea_Impl_FreeSpace_Key
//  9    ea_Impl_OS2ExtAtt_Key
//  10   ea_Impl_OS2EALen_Key
//  11   ea_Impl_MacVolInfo_Key
//  12   ea_Impl_MacFinderInfo_Key
//  13   ea_Impl_MacUniqueIDTable_Key
//  14   ea_Impl_MacResourceFork_Key
//  15   ea_Impl_Default_Key
//  16   ea_Appl_Default_Key
//  17   ea_Appl_HPNovellAttr_Key
//  18   ea_Appl_HPNovellTrustee_Key
//  19   ea_Appl_HPICBTable_Key
//
// USES:
//  Used as values for the keys to all EARegistry entries.
//
// ABUSES:
//
// NOTES:
//  Value 0 (ea_InvalidKey) is never used as a key to the EA
//  registry--it is used to indicate an invalid regKey value.
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------
enum EARegistrySymbols {
    ea_InvalidKey = 0,              // not a "real" entry
    ea_Hdr_Key,
    ea_ISO_CharSetInfo_Key,
    ea_ISO_AltPermissions_Key,
    ea_ISO_FileTimes_Key,
    ea_ISO_InfoTimes_Key,
    ea_ISO_DeviceSpec_Key,
    ea_ISO_Default_Key,
    ea_Impl_FreeSpace_Key,
    ea_Impl_OS2ExtAtt_Key,
    ea_Impl_OS2EALen_Key,
    ea_Impl_MacVolInfo_Key,
    ea_Impl_MacFinderInfo_Key,
    ea_Impl_MacUniqueIDTable_Key,
    ea_Impl_MacResourceFork_Key,
    ea_Impl_Default_Key,
    ea_Appl_Default_Key,
    ea_Appl_HPNovellAttr_Key,
    ea_Appl_HPNovellTrustee_Key,
    ea_Appl_HPICBTable_Key
};


// !!! ------------------------ temporary EA Inspector ----------------------------
// !!! Temporary kludge of an EA inspector, until the real one is working.  It has
// !!! almost the same interface.
// !!! There are four problems with the existing EA inspector:
// !!! (1) The Borland compiler can't live with enums with values > 65535.
// !!! (2) We need some way to ensure that there is enough valid data in the caller's buffer
// !!!     for each of several checks, for any of the various descriptors.
// !!! (3) All attrID String objects are returned with a length of 23.  They fail == comparisons
// !!!     with String objects that have the exact length of their character strings.
// !!! (4) The error() method checks for attrLen >= padded length (minAttrLen).  The test should
// !!!     be attrLen >= fixedLen + varyingLen (without padding).

class SAIEAInspector {
private:
    UINT32          attrType_;
    UINT8           attrSubtype_;
    UINT32          attrLen_;
    String          attrID_;
    UINT32          fixedLen_;
    UINT32          varyingLen_;
    Error           error_;
        
public:
    SAIEAInspector(void) :
        attrType_((UINT32)NSR::ea_Unknown),
        attrSubtype_(1),
        attrLen_(0),
        attrID_(String()),
        fixedLen_(0),
        varyingLen_(0)  {}
    void fromISO(CONST_BYTE_PTR rbp, UINT32 len=1000);  // default len is > any descriptor length
    Error error( void )         const   { return error_; }
    void  clear(void);
    UINT32 attrType()           const   { return attrType_; }
    UINT8  attrSubtype()        const   { return attrSubtype_; }
    UINT32 attrLen()            const   { return attrLen_; }
    String attrID()             const   { return attrID_; }
    UINT32 fixedLen()           const   { return fixedLen_; }
    UINT32 varyingLen()         const   { return varyingLen_; }
    UINT32 minAttrLen()         const   { return ((((varyingLen_+fixedLen_) + 3) / 4) * 4); }

private:
    void setupAttrLength (CONST_BYTE_PTR rbp);
    void setupvaryingLength (CONST_BYTE_PTR rbp);
    void setupId (CONST_BYTE_PTR rbp);
};



//----------------------------------------------------------------------
// CLASS: EARegistryEntry     --CJB
//
//  Class which holds all information for one kind of EA.  The
//  combination of EA Type, EA SubType and EA String uniquely identify
//  an entry.
//
// PUBLIC DATA MEMBERS:
//    (none)
//
// PUBLIC METHODS:
//    EARegistryEntry()         - Constructor.
//    ~EARegistryEntry()        - Destructor.
//    regKey()                  - Getter for regKey_.
//    eaType()                  - getter for eaType_.
//    eaSubType()               - Getter for eaSubType_.
//    eaString()                - Getter for eaString_.
//    eaPlacement()             - Getter for eaPlacement_.
//    eaMultInstAllwd()         - Getter for eaMultInstAllwd_.
//    eaCritical()              - Getter for eaCritical_.
//    eaDefaultKey()            - Tells if this entry's regKey is one
//                                of the default values. 
//    eaCategory()              - Static method to get EACategory (it
//                                is computed at run time).  
//
// USAGE NOTES:
//  Notice that there are only "getter" methods--all values are set at
//  construction time, and are effectively read only after that.
// 
//----------------------------------------------------------------------
// COLLABORATORS:  
//
// PRIVATE METHODS:
//    (none)
//
// IMPLEMENTATION NOTES:
//
//----------------------------------------------------------------------
class EARegistryEntry : public RWCollectable {

private:
    UINT32      regKey_;
    UINT32      eaType_;
    UINT8       eaSubType_;
    String      eaString_;
    EAPlc       eaPlacement_;
    Boolean     eaMultInstAllwd_;
    Boolean     eaCritical_;


public:
    // INLINE: EARegistryEntry::EARegistryEntry()
    EARegistryEntry(UINT32 regKey,
                    UINT32 eaType,
                    UINT8 eaSubType,
                    String eaString,
                    EAPlc eaPlacement,
                    Boolean eaMultInstAllwd,
                    Boolean eaCritical) :
            regKey_(regKey),
            eaType_(eaType),
            eaSubType_(eaSubType),
            eaString_(eaString),
            eaPlacement_(eaPlacement),
            eaMultInstAllwd_(eaMultInstAllwd),
            eaCritical_(eaCritical) {}

    // INLINE: EARegistryEntry::EARegistryEntry()
    EARegistryEntry(void) :                                             
            regKey_(ea_InvalidKey),
            eaType_(0),
            eaSubType_(0),
            eaString_(String()),
            eaPlacement_(ea_MayBeInEitherSpace),
            eaMultInstAllwd_(False),
            eaCritical_(False) {}

    // The default copy constructor is OK.

    // INLINE: EARegistryEntry::regKey()
    UINT32      regKey(void)            const { return regKey_;    }

    // INLINE: EARegistryEntry::eaType()
    UINT32      eaType(void)            const { return eaType_;    }

    // INLINE: EARegistryEntry::eaSubType()
    UINT8       eaSubType(void)         const { return eaSubType_; }

    // INLINE: EARegistryEntry::eaString()
    String      eaString(void)          const { return eaString_;  }

    // INLINE: EARegistryEntry::eaPlacement()
    EAPlc       eaPlacement(void)       const { return eaPlacement_; }

    // INLINE: EARegistryEntry::eaMultInstAllwd()
    Boolean     eaMultInstAllwd(void)   const { return eaMultInstAllwd_; }

    // INLINE: EARegistryEntry::eaCritical()
    Boolean     eaCritical(void)        const { return eaCritical_; }

    // INLINE: EARegistryEntry::eaDefaultKey()
    Boolean     eaDefaultKey(void)      const {
        if (regKey_ == (UINT32)ea_ISO_Default_Key   ||
            regKey_ == (UINT32)ea_Impl_Default_Key  ||
            regKey_ == (UINT32)ea_Appl_Default_Key)
            return True;
        else return False;
    }

    static EACategory eaCategory(UINT32 eaType, UINT8 eaSubType);

    // INLINE: EARegistryEntry::eaCategory()
    EACategory  eaCategory(void) const {
        return eaCategory(eaType_, eaSubType_);
    }

}; // EARegistryEntry

//----------------------------------------------------------------------
// METHOD: EARegistryEntry::EARegistryEntry  --CJB
//  
//  Constructor.
//
// ARGS:
//  UINT32  regKey          IN  the key to this entry
//  UINT32  eaType          IN  the type for this entry
//  UINT8   eaSubType       IN  the subtype for this entry
//  String  eaString        IN  the id string for this entry
//  EAPlc   eaPlacement     IN  the placement rule for this entry
//  Boolean eaMultInstAllwd IN  true if multiple instances allowed for
//                              this entry 
//  Boolean eaCritical      IN  true if this entry is critical to
//                              applications
//
// RETURNS:
//  (none)
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  Constructs an EARegistryEntry object.
// 
// ERRORS:
//  (none)
// 
// NOTES:
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------

//----------------------------------------------------------------------
// METHOD: EARegistryEntry::EARegistryEntry  --CJB
//  
//  Constructor.
//
// ARGS:
//  (none)
//
// RETURNS:
//  (none)
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  Constructs an EARegistryEntry object.
// 
// ERRORS:
//  (none)
// 
// NOTES:
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------

//----------------------------------------------------------------------
// METHOD: EARegistryEntry::regKey  --CJB
//  
//  Getter method for regKey_.
//
// ARGS:
//  (none)
//
// RETURNS:
//  UINT32 -- returns regKey_
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  (none)
// 
// ERRORS:
//  (none)
// 
// NOTES:
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------

//----------------------------------------------------------------------
// METHOD: EARegistryEntry::eaType  --CJB
//  
//  Getter method for eaType_.
//
// ARGS:
//  (none)
//
// RETURNS:
//  UINT32 -- returns eaType_
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  (none)
// 
// ERRORS:
//  (none)
// 
// NOTES:
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------

//----------------------------------------------------------------------
// METHOD: EARegistryEntry::eaSubType  --CJB
//  
//  Getter method for eaSubType_.
//
// ARGS:
//  (none)
//
// RETURNS:
//  UINT8 -- returns eaSubType_
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  (none)
// 
// ERRORS:
//  (none)
// 
// NOTES:
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------

//----------------------------------------------------------------------
// METHOD: EARegistryEntry::eaString  --CJB
//  
//  Getter method for eaString_.
//
// ARGS:
//  (none)
//
// RETURNS:
//  String -- returns eaString_
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  (none)
// 
// ERRORS:
//  (none)
// 
// NOTES:
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------

//----------------------------------------------------------------------
// METHOD: EARegistryEntry::eaPlacement  --CJB
//  
//  Getter method for eaPlacement_.
//
// ARGS:
//  (none)
//
// RETURNS:
//  EAPlc -- eaPlacement_
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  (none)
// 
// ERRORS:
//  (none)
// 
// NOTES:
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------

//----------------------------------------------------------------------
// METHOD: EARegistryEntry::eaMultInstAllwd  --CJB
//  
//  Getter method for eaMultInstAllwd_.
//
// ARGS:
//  (none)
//
// RETURNS:
//  Boolean -- returns eaMultInstAllwd_
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  (none)
// 
// ERRORS:
//  (none)
// 
// NOTES:
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------

//----------------------------------------------------------------------
// METHOD: EARegistryEntry::eaCritical  --CJB
//  
//  Getter method for eaCritical_.
//
// ARGS:
//  (none)
//
// RETURNS:
//  Boolean -- returns eaCritical_
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  (none)
// 
// ERRORS:
//  (none)
// 
// NOTES:
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------

//----------------------------------------------------------------------
// METHOD: EARegistryEntry::eaDefaultKey  --CJB
//  
//  Getter method for eaDefaultKey.
//
// ARGS:
//  (none)
//
// RETURNS:
//  Boolean -- returns eaDefaultKey (calculated from regKey).
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  (none)
// 
// ERRORS:
//  (none)
// 
// NOTES:
//  The return value indicates whether this EARegistryEntry's regKey is one
//  of the default regKeys.
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------

//----------------------------------------------------------------------
// METHOD: EARegistryEntry::eaCategory  --CJB
//  
//  Getter method for eaCategory.
//
// ARGS:
//  (none)
//
// RETURNS:
//  EACategory -- returns eaCategory (calculated from eaType and eaSubType).
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  (none)
// 
// ERRORS:
//  (none)
// 
// NOTES:
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------




//----------------------------------------------------------------------
// CLASS: EARegistry     --CJB
//
//  Class to allow access to all EARegistryEntry objects.  One object
//  exists for each kind of EA that the system knows about.
//
// PUBLIC DATA MEMBERS:
//    (none)
//
// PUBLIC METHODS:
//    EARegistry()              - Constructor.
//    ~EARegistry()             - Destructor.
//    add ()                    - Enters an EARegistryEntry into the
//                                registry. 
//    at ()                     - Fetches an entry by regKey.
//    find ()                   - Fetches an entry by EAType,
//                                EASubType and EAString. 
//    getFirstKey ()            - Returns one regKey value.
//    getNextKey ()             - After a call to getFirstKey,
//                                successive calls to this method
//                                return successive regKey values.
//
// USAGE NOTES:
//    The function of the registry is to associate EA information with
//    regKeys.
//    It is used for the following purposes:
//      (1) Determining which EAs are understood and which are not.
//          The system can still do simple operations on unknown kinds
//          of EAs by using the default EARegistryEntries.
//      (2) Compressing the View items, to not lug this all around.
//          By allowing users to specify the key, they are free to use
//          enums or constants of their choice--ie., named symbols for
//          each EA.
// 
//----------------------------------------------------------------------
// COLLABORATORS:  
//
// PRIVATE METHODS:
//    (none)
//
// IMPLEMENTATION NOTES:
//  All member variables and all methods of this class are static.
//  Therefore a "this" pointer is not needed to access this class.
//  The class is set up with an initial set of entries in the .cpp
//  module.  Additional entries may be added, but the initial entries
//  cannot be modified or deleted (there are no methods provided to do
//  that).
//
//----------------------------------------------------------------------
class EARegistry {

private:
    static UINT32               numEntries_;
    static EARegistryEntry      eaRegistryEntries_[EA_REGISTRY__MAX_ENTRIES];


public:
    // INLINE: EARegistry::EARegistry()
    EARegistry (void) {}

    // Enters an EARegistryEntry into the registry.
    static void add (const EARegistryEntry & eare, Error & err);

    // Fetches an entry by regKey.
    static const EARegistryEntry * at (UINT32 regKey, Error & err);

    // Fetches an entry by EAType, EASubType and EAString.
    static UINT32 find (UINT32 eaType, UINT8 eaSubType, String &eaString, Error & err );

    // Returns the first or succeeding regKeys.
    static UINT32 getFirstKey (Error & err);
    static UINT32 getNextKey (UINT32 previousKey, Error & err);

}; // EARegistry

//----------------------------------------------------------------------
// METHOD: EARegistry::EARegistry  --CJB
//  
//  Constructor.
//
// ARGS:
//  (none)
//
// RETURNS:
//  (none)
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  Constructs an EARegistry object.
// 
// ERRORS:
//  (none)
// 
// NOTES:
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------




//----------------------------------------------------------------------
// CLASS: EAView     --CJB
//
//  Abstract base class for classes that maintain lists of EAViewItems.
//
// PUBLIC DATA MEMBERS:
//    (none)
//
// PUBLIC METHODS:
//    EAView()                  - Constructor.
//    ~EAView()                 - Destructor.
//    copy_ ()                  - Method to do the actual work of the copy constructor and
//                                assignment operator.
//    operator= ()              - Assignment operator.
//    error()                   - Returns error state of the object.
//    clear()                   - Removes all entries and resets object to same state it had
//                                immediately after construction.
//    numEntries()              - Returns the number of entries in the view.
//    length()                  - Returns the combined length that all EAs in the view will have
//                                when they are written to their ByteArray or LogExtentList.
//    myEASpace()               - Getter and setter methods for myEASpace_, which points to EASpace
//                                object that holds this EAView.
//    toISO()                   - Writes the data of this item to a buffer in its ISO form (for
//                                ShortEAViews and their derived classes only).
//    toDisk()                  - Writes the data of this item to the disk (for LongEAViews and
//                                their derived classes only).
//    eaViewBA()                - Returns a reference to the ByteArray (for ShortEAViews and
//                                their derived classes only).
//    at()                      - Returns a pointer to an item at a specified index in this view.
//    removeAt()                - Removes an item from the view and returns a pointer to it.
//    removeAndDestroyAt()      - Removes an item from the view and calls its destructor.
//    parentGOSViewItem()       - Getter and setter methods for parentGOSViewItem_, which points
//                                to the parent (only if the parent is a GroupOfShortsEAViewItem).
//    findIndex()               - Returns the index of a specified item, relative to this view.
//    last()                    - Returns the last item in this view.
//    setPaddingToMin ()        - For every item in this view, sets the attribute length to the end
//                                of the valid data, rounded up to the next four byte boundary.
//    removeAllMyExtents ()     - Moves all extents held by the items in this view, to the trash list.
//    removeCallersDuplicateExtents () - Removes all extents from sourceList that are also in this EA
//                                view, and adds them to targetList.
//    countDiskSpace()          - For testing. Returns the total number of disk sectors held by
//                                all the items in this view.
//    printAllocatedBlocks()    - For testing. Prints a list of all disk sectors held by the
//                                items in this view. 
//    printList ()              - Prints all the EAs in this view.
//
// USAGE NOTES:
//  User notes go here.
//
//----------------------------------------------------------------------
// COLLABORATORS:  
//
// PRIVATE METHODS:
//    putIntoList ()            - Does the low level details of adding an item to this view's list.
//
// IMPLEMENTATION NOTES:
//
//----------------------------------------------------------------------
class EAView {

protected:
    RWOrdered       *list_;                 // list of eaViewItems
    EAViewItem      *parentGOSViewItem_;    // GOS view item that contains this view, or NULL if none
    EASpace         *myEASpace_;            // EASpace that contains this view, or NULL if none
    Error           error_;

    
public:
    // INLINE: EAView::EAView()
    EAView(EASpace *myEASpace) :
            parentGOSViewItem_(NULL),
            myEASpace_(myEASpace),
            error_(error_None)  { list_ = new RWOrdered(); }

    // INLINE: EAView::EAView()
    EAView(const EAView & x) {              // copy constructor
        copy_(x, error_);
    }

    virtual ~EAView(void);

    // INLINE: EAView::error()
    Error error(void)                                   const   { return error_; }

    void  copy_ (const EAView & x, Error & err);

    // INLINE: EAView::operator=()
    EAView& operator= (const EAView &x) {
        copy_(x, error_); 
        return *this;
    }

    void clear(void);

    UINT16 numEntries(void)                             const;

    UINT32 length(void)                                 const;

    // INLINE: EAView::myEASpace()
    void myEASpace(EASpace * myEASpace)                         { myEASpace_ = myEASpace; }

    // INLINE: EAView::myEASpace()
    EASpace * myEASpace(void)                           const   { return myEASpace_; }

    // INLINE: EAView::toISO()
    void toISO(Error & err)                             const   { err = error_None; }

    // INLINE: EAView::toDisk()
    void toDisk(SpaceResource & space, Error & err)     const   { err = error_None; }

    // INLINE: EAView::ByteArray()
    virtual ByteArray& eaViewBA(void)                   const   { return nullBA; }

    EAViewItem * at(INT16 index, Error & err) const;

    virtual EAViewItem * removeAt(INT16 index, Error & err);

    // INLINE: EAView::removeAndDestroyAt()
    virtual void removeAndDestroyAt(INT16 index, Error & err)   { delete this->removeAt(index, err); }

    // INLINE: EAView::parentGOSViewItem()
    void parentGOSViewItem(EAViewItem * parentGOSViewItem)      { parentGOSViewItem_ = parentGOSViewItem; }

    // INLINE: EAView::parentGOSViewItem()
    EAViewItem * parentGOSViewItem(void)                const   { return parentGOSViewItem_; }
    
    virtual INT16 findIndex(const EAViewItem* itemToFind) const = 0;

    EAViewItem * last(void)                             const;

    void setPaddingToMin (UINT32 blockSize, Error & err);

    // INLINE: EAView::removeAllMyExtents()
    virtual void removeAllMyExtents (Boolean GOSOnly, LogExtentList & targetList,
                                     Error & err)                                            { err = error_None; }

    // INLINE: EAView::removeCallersDuplicateExtents()
    virtual void removeCallersDuplicateExtents (LogExtentList & sourceList,
                                                LogExtentList & targetList, Error & err)                { err = error_None; }

#if defined DEBUG_EA__GENERAL
    // INLINE: EAView::countDiskSpace()
    virtual UINT32 countDiskSpace(UINT32 blockSize)     const   { return 0; }

    // INLINE: EAView::printAllocatedBlocks()
    virtual void printAllocatedBlocks(void)             const   {}
#endif

#if defined ENABLE_PRINTING
    virtual void printList (INT16 indent=0) const;
#endif


protected:
    virtual void putIntoList (EAViewItem * eavi, INT16 index, Error & err);

}; // EAView

//----------------------------------------------------------------------
// METHOD: EAView::EAView  --CJB
//  
//  Constructor.
//
// ARGS:
//  const EASpace*          myEASpace       IN  pointer to EA space object that contains this EA view
//
// RETURNS:
//  (none)
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  Constructs an EAView object.
// 
// ERRORS:
//  (none)
// 
// NOTES:
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------

//----------------------------------------------------------------------
// METHOD: EAView::EAView  --CJB
//  
//  Copy constructor.
//
// ARGS:
//  const EAView&           x               IN  source object to copy
//
// RETURNS:
//  (none)
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  An EAView object is constructed which is a copy of x.
// 
// ERRORS:
//  (call error() to get the object's error status.)
//  error_Null_pointer
//  error_EA_Invalid_EA_type
//  error_No_free_store
// 
// NOTES:
//  If x is the same as this, nothing is done--ie., we don't copy to ourself.
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------

//----------------------------------------------------------------------
// METHOD: EAView::error  --CJB
//  
//  Gets the error state of this object.
//
// ARGS:
//  (none)
//
// RETURNS:
//  Error -- returns an Error object containing the error state of this object.
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  (none)
// 
// ERRORS:
//  (none)
// 
// NOTES:
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------

//----------------------------------------------------------------------
// METHOD: EAView::operator=  --CJB
//  
//  Assignment operator.
//
// ARGS:
//  const EAView&           x               IN  source object to copy
//
// RETURNS:
//  (none)
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  Assigns a copy of the source object into the specified object.
// 
// ERRORS:
//  (call error() to get the object's error status.)
//  error_Null_pointer
//  error_EA_Invalid_EA_type
//  error_No_free_store
// 
// NOTES:
//  If x is the same as this, nothing is done--ie., we don't assign to ourself.
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------

//----------------------------------------------------------------------
// METHOD: EAView::myEASpace  --CJB
//  
//  Getter method for myEASpace_.
//
// ARGS:
//  (none)
//
// RETURNS:
//  EASpace* -- returns a pointer to the EA space object that contains this EA view.
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  (none)
// 
// ERRORS:
//  (none)
// 
// NOTES:
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------

//----------------------------------------------------------------------
// METHOD: EAView::myEASpace  --CJB
//  
//  Setter method for myEASpace_.
//
// ARGS:
//  EASpace*                myEASpace       IN  pointer to EA space object that contains this EA view
//
// RETURNS:
//  (none)
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  This EA view's myEASpace_ variable is updated to the new value.
// 
// ERRORS:
//  (none)
// 
// NOTES:
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------

//----------------------------------------------------------------------
// METHOD: EAView::toISO  --CJB
//  
//  Writes data of all items in our list to the caller's ByteArray (applies to
//  short EA view objects only).
//
// ARGS:
//  Error&                  err             OUT error status
//
// RETURNS:
//  (none)
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  Data of all items in our list are written to the caller's ByteArray.
// 
// ERRORS:
//  (none)
// 
// NOTES:
//  This is a placeholder method.  The real functionality is done by the
//  method for the ShortEAView class.
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------

//----------------------------------------------------------------------
// METHOD: EAView::toDisk  --CJB
//  
//  Writes data of all items in our list to the caller's extent list
//
// ARGS:
//  SpaceResource&          space           IN  space resource object, for allocation of disk space
//  Error&                  err             OUT error status
//
// RETURNS:
//  (none)
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  Data of all items in our list are written to the caller's extent list.
// 
// ERRORS:
//  (none)
// 
// NOTES:
//  This is a placeholder method.  The real functionality is done by the
//  method for the LongEAView class.
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------

//----------------------------------------------------------------------
// METHOD: EAView::eaViewBA  --CJB
//  
//  Returns a reference to our internal ByteArray.
//
// ARGS:
//  (none)
//
// RETURNS:
//  ByteArray& -- returns a reference to our internal ByteArray.
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  (none)
// 
// ERRORS:
//  (none)
// 
// NOTES:
//  This is a placeholder method.  The real functionality is done by the
//  method for the ShortEAView class.
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------

//----------------------------------------------------------------------
// METHOD: EAView::removeAndDestroyAt  --CJB
//  
//  Removes a selected EA view item from this EA view, and calls it's destructor.
//
// ARGS:
//  INT16                   index           IN  index into this EA view, of item to operate on
//  Error&                  err             OUT error status
//
// RETURNS:
//  (none)
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  The item is removed from our lists, and it is destroyed.
// 
// ERRORS:
//  (none)
// 
// NOTES:
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------

//----------------------------------------------------------------------
// METHOD: EAView::parentGOSViewItem  --CJB
//  
//  Getter method for parentGOSViewItem_.
//
// ARGS:
//  (none)
//
// RETURNS:
//  EAViewItem* -- returns a pointer to this view's parent GroupOfShorts EA view item object,
//  or NULL if there is none (applies only to short EA view items).
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  (none)
// 
// ERRORS:
//  (none)
// 
// NOTES:
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------

//----------------------------------------------------------------------
// METHOD: EAView::parentGOSViewItem  --CJB
//  
//  Setter method for parentGOSViewItem_.
//
// ARGS:
//  EAViewItem*             parentGOSViewItem IN pointer to this view's parent EA view item object
//
// RETURNS:
//  (none)
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  This EA view's parentGOSViewItem_ variable is updated to the new value.
// 
// ERRORS:
//  (none)
// 
// NOTES:
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------

//----------------------------------------------------------------------
// METHOD: EAView::removeAllMyExtents  --CJB
//  
//  Moves all extents held by the items in this view, to the specified target list.
//
// ARGS:
//  Boolean                 GOSOnly         IN  indicates we should operate on GOS items only
//  LogExtentList&          targetList      IN  target list to move log extents to
//  Error&                  err             OUT error status
//
// RETURNS:
//  (none)
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  All logical extents of all items in this EA view are removed from their respective
//  LogExtentLists, and appended to the target list.
// 
// ERRORS:
//  error_Required_object_not_present
//  error_No_free_store
//  error_Null_pointer;
// 
// NOTES:
//  This is a placeholder method.  The real functionality is done by the
//  method for the LongEAView class.
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------

//----------------------------------------------------------------------
// METHOD: EAView::removeCallersDuplicateExtents  --CJB
//  
//  This method removes all extents from sourceList that are also in this EA view,
//  and adds them to targetList.
//
// ARGS:
//  LogExtentList&          sourceList      IN/OUT extent list to remove extents from
//  LogExtentList&          targetList      IN/OUT extent list to move extents into
//  Error&                  err             OUT error status
//
// RETURNS:
//  (none)
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  The specified extents are moved from sourceList to targetList.
// 
// ERRORS:
//  error_Required_object_not_present
//  error_No_free_store
//  error_Null_pointer;
// 
// NOTES:
//  This is a placeholder method.  The real functionality is done by the
//  method for the LongEAView class.
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------

//----------------------------------------------------------------------
// METHOD: EAView::countDiskSpace  --CJB
//  
//  For testing. Returns the total number of disk blocks held by all the items
//  in this view.
//
// ARGS:
//  UINT32                  blockSize       IN  size of a block on the media
//
// RETURNS:
//  UINT32 -- returns the total number of blocks for all items in this EA view.
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  (none)
// 
// ERRORS:
//  (none)
// 
// NOTES:
//  This method is for testing only, and will not appear in the final product.
//  This is a placeholder method.  The real functionality is done by the
//  method for the LongEAView class.
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------

//----------------------------------------------------------------------
// METHOD: EAView::printAllocatedBlocks  --CJB
//  
//  For testing. Prints a list of all disk blocks held by the items in this view.
//
// ARGS:
//  (none)
//
// RETURNS:
//  (none)
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  (none)
// 
// ERRORS:
//  (none)
// 
// NOTES:
//  This method is for testing only, and will not appear in the final product.
//  This is a placeholder method.  The real functionality is done by the
//  method for the LongEAView class.
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------




//----------------------------------------------------------------------
// CLASS: ShortEAView     --CJB
//
//  Derived class (from the EAView class) that maintains lists of ShortEAViewItems.
//
// PUBLIC DATA MEMBERS:
//    (none)
//
// PUBLIC METHODS:
//    ShortEAView()             - Constructor.
//    ~ShortEAView()            - Destructor.
//    toISO()                   - Translates the data of this object to its ISO form.
//    eaViewBA()                - Returns a reference to the ByteArray.
//    insertAt()                - Inserts an item into this view at a specified index.
//    removeAt()                - Removes an item from the view and returns a pointer to it.
//    findIndex()               - Returns the index of a specified item, relative to this view.
//    printList ()              - Prints all the EAs in this view.
//
// USAGE NOTES:
//  User notes go here.
// 
//----------------------------------------------------------------------
// COLLABORATORS:  
//
// PRIVATE METHODS:
//    (none)
//
// IMPLEMENTATION NOTES:
//
//----------------------------------------------------------------------
class ShortEAView : public EAView {

private:
    ByteArray       &   eaViewBA_;
        

public:
    // INLINE: ShortEAView::ShortEAView()
    ShortEAView (ByteArray & ba, EASpace *myEASpace, EAViewItem *parentGOSViewItem) :
            EAView(myEASpace),
            eaViewBA_(ba) { parentGOSViewItem_ = parentGOSViewItem; }

    // The default copy constructor is OK.

    // INLINE: ShortEAView::~ShortEAView()
    virtual ~ShortEAView() {}

    void toISO(Error & err)                         const;

    // INLINE: ShortEAView::eaViewBA()
    ByteArray & eaViewBA(void)                      const   { return eaViewBA_; }

    void insertAt(ShortEAViewItem * seavi, INT16 index, Error & err);

    // INLINE: ShortEAView::removeAt()
    EAViewItem * removeAt(INT16 index, Error & err) { return EAView::removeAt(index, err); }

    INT16 findIndex(const EAViewItem* itemToFind)   const;

#if defined ENABLE_PRINTING
    void printList (INT16 indent=0)                 const;
#endif
  
}; // ShortEAView

//----------------------------------------------------------------------
// METHOD: ShortEAView::ShortEAView  --CJB
//  
//  Constructor.
//
// ARGS:
//  ByteArray&              ba              IN  caller's ByteArray, updated by toISO()
//  const EASpace*          myEASpace       IN  EA space object that contains this EA view
//  EAViewItem*             parentGOSViewItem IN EA pointer to GOS EA view item containing this view
//
// RETURNS:
//  (none)
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  Constructs a ShortEAView object.
// 
// ERRORS:
//  (none)
// 
// NOTES:
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------

//----------------------------------------------------------------------
// METHOD: ShortEAView::~ShortEAView  --CJB
//  
//  Destructor.
//
// ARGS:
//  (none)
//
// RETURNS:
//  (none)
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  The ShortEAView object is destroyed; all memory is deallocated.
// 
// ERRORS:
//  (none)
// 
// NOTES:
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------

//----------------------------------------------------------------------
// METHOD: ShortEAView::eaViewBA  --CJB
//  
//  Returns a reference to our internal ByteArray.
//
// ARGS:
//  (none)
//
// RETURNS:
//  ByteArray& -- returns a reference to our internal ByteArray.
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  (none)
// 
// ERRORS:
//  (none)
// 
// NOTES:
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------

//----------------------------------------------------------------------
// METHOD: ShortEAView::removeAt  --CJB
//  
//  Removes an item from the view and returns a pointer to it.
//
// ARGS:
//  INT16                   index           IN  index into this EA view
//  Error&                  err             OUT error status
//
// RETURNS:
//  EAViewItem* -- returns a pointer to the specified EA view item and
//  removes it from this EA view. Returns NULL if there is any problem.
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  The specified EA view item is removed from this EA view.
// 
// ERRORS:
//  error_Required_object_not_present
//  error_Index_out_of_bounds
// 
// NOTES:
//  This method does not delete the returned object--It is the
//  caller's responsibility to do that.
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------




//----------------------------------------------------------------------
// CLASS: LongEAView     --CJB
//
//  Derived class (from the EAView class) that maintains lists of LongEAViewItems.
//
// PUBLIC DATA MEMBERS:
//    (none)
//
// PUBLIC METHODS:
//    LongEAView()              - Constructor.
//    ~LongEAView()             - Destructor.
//    toDisk()                  - Translates the data of this object to its on-disk form.
//    insertAt()                - Inserts an item into this view at a specified index.
//    findIndex()               - Returns the index of a specified item, relative to this view.
//    removeAllMyExtents ()     - Moves all extents held by the items in this view, to the trash list.
//    removeCallersDuplicateExtents () - Removes all extents from sourceList that are also in this EA
//                                view, and adds them to targetList.
//    countDiskSpace()          - For testing. Returns the total number of disk sectors held by
//                                all the items in this view.
//    printAllocatedBlocks()    - For testing. Prints a list of all disk sectors held by the
//                                items in this view. 
//    printList ()              - Prints all the EAs in this view.
//
// USAGE NOTES:
//  User notes go here.
// 
//----------------------------------------------------------------------
// COLLABORATORS:  
//
// PRIVATE METHODS:
//    (none)
//
// IMPLEMENTATION NOTES:
//
//----------------------------------------------------------------------
class LongEAView : public EAView {

public:
    // INLINE: LongEAView::LongEAView()
    LongEAView (EASpace *myEASpace) :
            EAView(myEASpace) {}

    // The default copy constructor is OK.

    // INLINE: LongEAView::~LongEAView()
    virtual ~LongEAView() {}

    void toDisk(SpaceResource & space, Error & err)     const;

    void insertAt(LongEAViewItem * leavi, INT16 index, Error & err);

    INT16 findIndex(const EAViewItem* itemToFind)       const;

    void removeAllMyExtents (Boolean GOSOnly, LogExtentList & targetList,
                             Error & err);

    void removeCallersDuplicateExtents (LogExtentList & sourceList,
                                        LogExtentList & targetList, Error & err);

#if defined DEBUG_EA__GENERAL
    UINT32 countDiskSpace(UINT32 blockSize)             const;

    void printAllocatedBlocks(void)                     const;
#endif

#if defined ENABLE_PRINTING
    void printList (INT16 indent=0)                     const;
#endif
        
}; // LongEAView

//----------------------------------------------------------------------
// METHOD: LongEAView::LongEAView  --CJB
//  
//  Constructor.
//
// ARGS:
//  const EASpace*          myEASpace       IN  EA space object that contains this EA view
//
// RETURNS:
//  (none)
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  Constructs a LongEAView object.
// 
// ERRORS:
//  (none)
// 
// NOTES:
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------

//----------------------------------------------------------------------
// METHOD: LongEAView::~LongEAView  --CJB
//  
//  Destructor.
//
// ARGS:
//  (none)
//
// RETURNS:
//  (none)
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  The LongEAView object is destroyed; all memory is deallocated.
// 
// ERRORS:
//  (none)
// 
// NOTES:
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------




//----------------------------------------------------------------------
// CLASS: EAViewItem     --CJB
//
//  Abstract base class for all EA view item classes.  These items hold all the information
//  that is kept, for one extended attribute.
//
// PUBLIC DATA MEMBERS:
//    (none)
//
// PUBLIC METHODS:
//    EAViewItem()              - Constructor.
//    ~EAViewItem()             - Destructor.
//    error()                   - Returns error state of the object.
//    copy_ ()                  - Method to do the actual work of the copy constructor and
//                                assignment operator.
//    operator= ()              - Assignment operator.
//    eaType()                  - getter for eaType_ (determined by value of regKey_).
//    eaSubType()               - Getter for eaSubType_ (determined by value of regKey_)
//    eaString()                - Getter for eaString_ (determined by value of regKey_)
//    eaPlacement()             - Getter for eaPlacement_ (determined by value of regKey_)
//    eaMultInstAllwd()         - Getter for eaMultInstAllwd_ (determined by value of regKey_)
//    eaCritical()              - Getter for eaCritical_ (determined by value of regKey_)
//    eaCategory()              - Static method to get EACategory (it is computed at run time,
//                                determined by value of regKey_) 
//    eaDefaultKey()            - Tells if this entry's regKey is one of the default values
//                                (determined by value of regKey_)
//    toISO()                   - Writes the data of this item to a buffer in its ISO form (for
//                                ShortEAViewItems only).
//    toDisk()                  - Writes the data of this item to the disk (for LongEAViewItems only).
//    ReadWriteEAByteArray()    - Returns a reference to the ByteArray (for ShortEAViewItems only),
//                                and marks the containing EAView dirty.
//    ReadOnlyEAByteArray()     - Returns a const reference to the ByteArray (for ShortEAViewItems only).
//    ReadWriteEALogExtentList() - Returns a reference to the extent list (for LongEAViewItems only),
//                                and marks the containing EA space dirty.
//    ReadOnlyEALogExtentList() - Returns a const reference to the extent list (for LongEAViewItems
//                                only).
//    numEntries()              - Returns the number of entries in the view.  This can be greater
//                                than one for GroupOfShortsEAViewItems; for all others it is
//                                always one.
//    length()                  - Returns the length that this item will have when it is written
//                                to its ByteArray or LogExtentList.
//    location()                - Setter method for location_ (for EAViewHeaderItems only).
//    regKey()                  - Getter and setter methods for regKey_.
//    parentView()              - Getter and setter methods for parentView_.
//    offset()                  - Returns the offset of this item's data, relative to its EAView.
//    overallOffset()           - Returns the offset of this item's data, relative to the
//                                containing EASpace.
//    EASpaceType()             - Returns the EASpaceType of the containing EASpace.
//    myIndex()                 - Returns the index of this item, relative to the containing EASpace.
//    findIndex()               - Returns the index of a specified item, relative to this view (for
//                                GroupOfShortsEAViewItems only).
//    at()                      - Returns a pointer to an item at a specified index in this view (for
//                                GroupOfShortsEAViewItems only).
//    setPaddingToMin ()        - Sets the attribute length to the end of the valid data, rounded up
//                                to the next four byte boundary.
//    insertAt()                - Inserts an item into this item at a specified index (for
//                                GroupOfShortsEAViewItems only).
//    removeAt()                - Removes an item from the view and returns a pointer to it (for
//                                GroupOfShortsEAViewItems only).
//    removeAndDestroyAt()      - Removes an item from the view and calls its destructor (for
//                                GroupOfShortsEAViewItems only).
//    findPadItemOffset()       - Returns the offset, relative to this item, where padding must be
//                                added during the toDisk() call (for GroupOfShortsEAViewItems only).
//    splitItem ()              - Splits this item, at a specified index, into two items (for
//                                GroupOfShortsEAViewItems only).
//    combineWithNextItem ()    - Combines this item with the next item (for GroupOfShortsEAViewItems
//                                only)
//    removeAllMyExtents ()     - Moves all extents held by this item, to targetList.
//    removeCallersDuplicateExtents () - Removes all extents from sourceList that are also in this EA
//                                view item, and adds them to targetList.
//    countDiskSpace()          - For testing. Returns the total number of disk sectors held by
//                                this item.
//    printAllocatedBlocks()    - For testing. Prints a list of all disk sectors held by this item.
//    compareForInsertion()     - Compares this item to a specifed item. Used to determine the
//                                insertion point when adding items to the EAView's list.
//    printItem ()              - Prints data about this item.
//
// USAGE NOTES:
//  User notes go here.
// 
//----------------------------------------------------------------------
// COLLABORATORS:  
//
// PRIVATE METHODS:
//    myTopLevelEAView ()       - Returns the highest level EAView that contains this item.
//    myEASpace()               - Getter method for myEASpace_, which points to the EASpace
//                                object that holds this item.
//
// IMPLEMENTATION NOTES:
//
//----------------------------------------------------------------------
class EAViewItem : public RWCollectable {

protected:
    UINT32          regKey_;
    EAView          *parentView_;   // view that contains this item, or NULL if not in a view
    Error           error_;
        

public:
    // INLINE: EAViewItem::EAViewItem()
    EAViewItem(void) :
            regKey_(ea_InvalidKey),
            parentView_(NULL),
            error_(error_None) {}

    // INLINE: EAViewItem::EAViewItem()
    EAViewItem(const EAViewItem & x) {      // copy constructor
        copy_(x, error_);
    }

    // INLINE: EAViewItem::~EAViewItem()
    virtual ~EAViewItem(void) {}

    // INLINE: EAViewItem::error()
    Error error(void)                                           const   { return error_; }

    void  copy_ (const EAViewItem & x, Error & err);

    // INLINE: EAViewItem::operator=()
    EAViewItem& operator= (const EAViewItem &x) {
        copy_(x, error_); 
        return *this;
    }

    UINT32      eaType(Error &err)                              const;

    UINT8       eaSubType(Error &err)                           const;

    String      eaString(Error &err)                            const;

    EAPlc       eaPlacement(Error &err)                         const;

    Boolean     eaMultInstAllwd(Error &err)                     const;

    Boolean     eaCritical(Error &err)                          const;

    EACategory  eaCategory(Error &err)                          const;

    Boolean     eaDefaultKey(Error &err)                        const;

    // INLINE: EAViewItem::toDisk()
    virtual void toDisk (SpaceResource & space, Error & err)            { err = error_None; }

    // INLINE: EAViewItem::toISO()
    virtual void toISO (Error & err)                                    { err = error_None; }
        
    // INLINE: EAViewItem::ReadWriteEAByteArray()
    virtual ByteArray & ReadWriteEAByteArray(void)                      { return nullBA; }

    // INLINE: EAViewItem::ReadOnlyEAByteArray()
    virtual const ByteArray & ReadOnlyEAByteArray(void)         const   { return nullBA; }

    // INLINE: EAViewItem::ReadWriteEALogExtentList()
    virtual LogExtentList & ReadWriteEALogExtentList(void)      const   { return *nullLEL; }

    // INLINE: EAViewItem::ReadOnlyEALogExtentList()
    virtual const LogExtentList & ReadOnlyEALogExtentList(void) const   { return *nullLEL; }

    // INLINE: EAViewItem::numEntries()
    virtual UINT16 numEntries(void)                             const   { return 1; }

    virtual UINT32 length(void)                                 const = 0;

    // INLINE: EAViewItem::EAViewItem()
    virtual void location(UINT32 location)                              {}

    // INLINE: EAViewItem::regKey()
    UINT32 regKey(void)                                         const   { return regKey_; }

    // INLINE: EAViewItem::regKey()
    void regKey(UINT32 regKey)                                          { regKey_ = regKey; }

    // INLINE: EAViewItem::parentView()
    void parentView(EAView *parentView)                                 { parentView_ = parentView; }

    // INLINE: EAViewItem::parentView()
    EAView * parentView(void)                                   const   { return parentView_; }

    UINT32 offset(void)                                         const;

    UINT32 overallOffset(void)                                  const;

    EASpaceType EASpaceType(void)                               const;

    INT16 myIndex(void)                                         const;

    virtual INT16 findIndex(const EAViewItem* itemToFind)       const;

    virtual const EAViewItem * at(INT16 index, Error & err)     const;

    virtual EAViewItem * at(INT16 index, Error & err);
  
    virtual void setPaddingToMin (UINT32 blockSize, Error & err) = 0;

    // INLINE: EAViewItem::EAViewItem()
    virtual void insertAt(ShortEAViewItem * seavi, INT16 index,
                          Error & err)                                                    { err = error_None; }

    // INLINE: EAViewItem::insertAt()
    virtual EAViewItem * removeAt(INT16 index, Error & err)             { err = error_None; return NULL; }

    // INLINE: EAViewItem::removeAndDestroyAt()
    virtual void  removeAndDestroyAt(INT16 index, Error & err)          { err = error_None; }

    // INLINE: EAViewItem::findPadItemOffset()
    virtual UINT32 findPadItemOffset(Error & err)               const   { err = error_None; return 0; }

    // INLINE: EAViewItem::splitItem()
    virtual GroupOfShortsEAViewItem * splitItem (INT16 startIndexOfSecondItem,
                                                 Error & err)                                                    { err = error_None; return NULL; }

    // INLINE: EAViewItem::combineWithNextItem()
    virtual void combineWithNextItem (EAViewItem * nextItem,
                                      Error & err) { err = error_None; }

    // INLINE: EAViewItem::removeAllMyExtents()
    virtual void removeAllMyExtents (LogExtentList & targetList,
                                     Error & err) { err = error_None; }

    // INLINE: EAViewItem::removeCallersDuplicateExtents()
    virtual void removeCallersDuplicateExtents (LogExtentList & sourceList,
                                                LogExtentList & targetList,
                                                Error & err) {
        err = error_None;
    }

#if defined DEBUG_EA__GENERAL
    // INLINE: EAViewItem::countDiskSpace()
    virtual UINT32 countDiskSpace(UINT32 blockSize)             const   { return 0; }

    // INLINE: EAViewItem::printAllocatedBlocks()
    virtual void printAllocatedBlocks(void)                     const   {}
#endif

    INT16 compareForInsertion(const EAViewItem * a) const;

#if defined ENABLE_PRINTING
    virtual void printItem (INT16 index, Boolean compositeList, INT16 indent) const = 0;
#endif


protected:
    EAView *  myTopLevelEAView (void)                           const;

    EASpace *  myEASpace (void)                                 const;
  
}; // EAViewItem

//----------------------------------------------------------------------
// METHOD: EAViewItem::EAViewItem  --CJB
//  
//  Constructor.
//
// ARGS:
//  (none)
//
// RETURNS:
//  (none)
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  Constructs an EAViewItem object.
// 
// ERRORS:
//  (none)
// 
// NOTES:
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------

//----------------------------------------------------------------------
// METHOD: EAViewItem::EAViewItem  --CJB
//  
//  Copy constructor.
//
// ARGS:
//  const EAViewItem&       x               IN  source object to copy
//
// RETURNS:
//  (none)
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  An EAViewItem object is constructed which is a copy of x.
// 
// ERRORS:
//  (call error() to get the object's error status.)
//  error_Null_pointer
//  error_EA_Invalid_EA_type
//  error_No_free_store
// 
// NOTES:
//  If x is the same as this, nothing is done--ie., we don't copy to ourself.
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------

//----------------------------------------------------------------------
// METHOD: EAViewItem::~EAViewItem  --CJB
//  
//  Destructor.
//
// ARGS:
//  (none)
//
// RETURNS:
//  (none)
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  The EAViewItem object is destroyed; all memory is deallocated.
// 
// ERRORS:
//  (none)
// 
// NOTES:
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------

//----------------------------------------------------------------------
// METHOD: EAViewItem::error  --CJB
//  
//  Gets the error state of this object.
//
// ARGS:
//  (none)
//
// RETURNS:
//  Error -- returns an Error object containing the error state of this object.
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  (none)
// 
// ERRORS:
//  (none)
// 
// NOTES:
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------

//----------------------------------------------------------------------
// METHOD: EAViewItem::operator=  --CJB
//  
//  Assignment operator.
//
// ARGS:
//  const EAViewItem&       x               IN  source object to copy
//
// RETURNS:
//  (none)
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  Assigns a copy of the source object into the specified object.
// 
// ERRORS:
//  (call error() to get the object's error status.)
//  error_Null_pointer
//  error_EA_Invalid_EA_type
//  error_No_free_store
// 
// NOTES:
//  If x is the same as this, nothing is done--ie., we don't assign to ourself.
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------

//----------------------------------------------------------------------
// METHOD: EAViewItem::toDisk  --CJB
//  
//  Writes the data of this item to its local LogExtentList.
//
// ARGS:
//  SpaceResource&          space           IN  pointer to space resource object, for allocations
//  Error&                  err             OUT error status
//
// RETURNS:
//  (none)
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  The local extent list of this item is updated with the item's current data.
// 
// ERRORS:
//  (only error_None for this placeholder method)
// 
// NOTES:
//  This is a placeholder method.  The real functionality is done by the
//  method for the GroupOfShortsEAViewItem class.
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------

//----------------------------------------------------------------------
// METHOD: EAViewItem::toISO  --CJB
//  
//  Writes the data of this item into the caller's ByteArray at the appropriate offset.
//
// ARGS:
//  Error&                  err             OUT error status
//
// RETURNS:
//  (none)
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  The caller's ByteArray is updated to contain the current data of this item
//  at the appropriate offset.
// 
// ERRORS:
//  (only error_None for this placeholder method)
// 
// NOTES:
//  This is a placeholder method.  The real functionality is done by the
//  method for the ShortEAViewItem class.
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------

//----------------------------------------------------------------------
// METHOD: EAViewItem::ReadWriteEAByteArray  --CJB
//  
//  Returns a reference to the ByteArray, and marks the containing EA space dirty.
//
// ARGS:
//  (none)
//
// RETURNS:
//  ByteArray& -- returns a reference to the ByteArray of this item.
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  (none)
// 
// ERRORS:
//  (none)
// 
// NOTES:
//  This is a placeholder method.  The real functionality is done by the
//  method for the ShortEAViewItem class.
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------

//----------------------------------------------------------------------
// METHOD: EAViewItem::ReadOnlyEAByteArray  --CJB
//  
//  Returns a const reference to the ByteArray.
//
// ARGS:
//  (none)
//
// RETURNS:
//  const ByteArray& -- returns a const reference to the ByteArray of this item.
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  (none)
// 
// ERRORS:
//  (none)
// 
// NOTES:
//  This is a placeholder method.  The real functionality is done by the
//  method for the ShortEAViewItem class.
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------

//----------------------------------------------------------------------
// METHOD: EAViewItem::ReadWriteEALogExtentList  --CJB
//  
//  Returns a reference to this item's extent list, and marks the containing
//  EA space dirty.
//
// ARGS:
//  (none)
//
// RETURNS:
//  LogExtentList& -- returns a reference to the LogExtentList of this item.
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  (none)
// 
// ERRORS:
//  (none)
// 
// NOTES:
//  This is a placeholder method.  The real functionality is done by the
//  method for the LongEAViewItem class.
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------

//----------------------------------------------------------------------
// METHOD: EAViewItem::ReadOnlyEALogExtentList  --CJB
//  
//  Returns a const reference to this item's extent list.
//
// ARGS:
//  (none)
//
// RETURNS:
//  const LogExtentList& -- returns a const reference to the LogExtentList
//  of this item.
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  (none)
// 
// ERRORS:
//  (none)
// 
// NOTES:
//  This is a placeholder method.  The real functionality is done by the
//  method for the LongEAViewItem class.
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------

//----------------------------------------------------------------------
// METHOD: EAViewItem::numEntries  --CJB
//  
//  Returns the number of entries in this view item.
//
// ARGS:
//  (none)
//
// RETURNS:
//  UINT16 -- returns the number of entries in this EA view item
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  (none)
// 
// ERRORS:
//  (none)
// 
// NOTES:
//  The number of entries can be greater than one for GroupOfShortsEAViewItems;
//  for all others it is handled by this method and is always one.
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------

//----------------------------------------------------------------------
// METHOD: EAViewItem::location  --CJB
//  
//  Setter method for location_.
//
// ARGS:
//  UINT32                  location        IN  logical block number where header is to be written
//
// RETURNS:
//  (none)
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  This item's location_ variable is updated to the new value.
// 
// ERRORS:
//  (none)
// 
// NOTES:
//  This is a placeholder method.  The real functionality is done by the
//  method for the EAViewHeaderItem class.
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------

//----------------------------------------------------------------------
// METHOD: EAViewItem::regKey  --CJB
//  
//  Getter method for regKey_.
//
// ARGS:
//  (none)
//
// RETURNS:
//  UINT32 -- returns the value of this item's regKey.
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  (none)
// 
// ERRORS:
//  (none)
// 
// NOTES:
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------

//----------------------------------------------------------------------
// METHOD: EAViewItem::regKey  --CJB
//  
//  Setter method for regKey_.
//
// ARGS:
//  UINT32                  regKey      IN  new regKey value
//
// RETURNS:
//  (none)
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  This item's regKey_ variable is updated to the new value.
// 
// ERRORS:
//  (none)
// 
// NOTES:
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------

//----------------------------------------------------------------------
// METHOD: EAViewItem::parentView  --CJB
//  
//  Getter method for parentView_.
//
// ARGS:
//  (none)
//
// RETURNS:
//  EAView* -- returns the value of this item's parentView (a pointer to
//  the EA view that contains this EA view item, or NULL if none.
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  (none)
// 
// ERRORS:
//  (none)
// 
// NOTES:
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------

//----------------------------------------------------------------------
// METHOD: EAViewItem::parentView  --CJB
//  
//  Setter method for parentView_.
//
// ARGS:
//  EAView*                 parentView  IN  pointer to this item's parent EA view
//
// RETURNS:
//  (none)
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  This item's parentView_ variable is updated to the new value.
// 
// ERRORS:
//  (none)
// 
// NOTES:
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------

//----------------------------------------------------------------------
// METHOD: EAViewItem::insertAt  --CJB
//  
//  Inserts an item into this item at a specified index.
//
// ARGS:
//  ShortEAViewItem*        seavi           IN  pointer to short EA view item to be inserted
//  INT16                   index           IN  index into this EA view item's subview
//  Error&                  err             OUT error status
//
// RETURNS:
//  (none)
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  The subview's internal list, and any other applicable member variables, are
//  updated to include the specified EA view item.
// 
// ERRORS:
//  (only error_None for this placeholder method)
// 
// NOTES:
//  (1) This is a placeholder method.  The real functionality is done by the
//  method for the GroupOfShortsEAViewItem class.
//  (2) The EA view item is not copied--it is put directly into the subview's list.
//  The implications of this are (1) The EA view item must be constructed
//  using the "new" operator, not on the stack; (2) This EA view item assumes
//  responsiblity for deleting the item.  This is done because the interface
//  presented to the eventual user (in the external EA space class) does a copy;
//  this interface can in a way be consdered internal.
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------

//----------------------------------------------------------------------
// METHOD: EAViewItem::removeAt  --CJB
//  
//  Removes an item from the view and returns a pointer to it.
//
// ARGS:
//  INT16                   index           IN  index into this EA view
//  Error&                  err             OUT error status
//
// RETURNS:
//  EAViewItem* -- returns a pointer to the item that was removed, or NULL
//  if there was a problem.
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  The subview and all other applicable member variables are updated to
//  indicate that the specified item is removed.
// 
// ERRORS:
//  (only error_None for this placeholder method)
// 
// NOTES:
//  (1) This is a placeholder method.  The real functionality is done by the
//  method for the GroupOfShortsEAViewItem class.
//  (2) This method does not delete the returned object--It is the
//  caller's responsibility to do that.
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------

//----------------------------------------------------------------------
// METHOD: EAViewItem::removeAndDestroyAt  --CJB
//  
//  Removes a selected EA view item from this EA view item, and calls it's destructor.
//
// ARGS:
//  INT16                   index           IN  index into this EA view item, of item to operate on
//  Error&                  err             OUT error status
//
// RETURNS:
//  (none)
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  The item is removed from our lists, and it is destroyed.
// 
// ERRORS:
//  (only error_None for this placeholder method)
// 
// NOTES:
//  This is a placeholder method.  The real functionality is done by the
//  method for the GroupOfShortsEAViewItem class.
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------

//----------------------------------------------------------------------
// METHOD: EAViewItem::findPadItemOffset  --CJB
//  
//  Returns the offset, relative to this item, to the first point where
//  padding will be added during the toDisk() call.
//
// ARGS:
//  Error&                  err             OUT error status
//
// RETURNS:
//  UINT32 -- returns the offset, relative to this EA view item, to the first
//  point where padding will be added.  Returns zero if this item has no
//  pad item, or if there is a problem.
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  (none)
// 
// ERRORS:
//  (only error_None for this placeholder method)
// 
// NOTES:
//  (1) This is a placeholder method.  The real functionality is done by the
//  method for the GroupOfShortsEAViewItem class.
//  (2) Notice that no padding is carried in this item or its subview.  It is
//  only added to the data written out by the toDisk() method--even then it
//  is not put into this item or its subview.  If you need to know where
//  and how much padding will be added by toDisk(), see the
//  determinePaddingNeeded() method of this class.
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------

//----------------------------------------------------------------------
// METHOD: :EAViewItem::splitItem  --CJB
//  
//  Splits this item, at a specified index, into two items.
//
// ARGS:
//  INT16                   startIndexOfSecondItem IN   index before which to split this item
//  Error&                  err             OUT error status
//
// RETURNS:
//  GroupOfShortsEAViewItem* -- returns a pointer to the new second
//  GroupOfShortsEAViewItem, or NULL if no split was done.
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  This GroupOFShorts EA view item is split into two items.  Our lists and
//  all member variables are updated to reflect this.
// 
// ERRORS:
//  (only error_None for this placeholder method)
// 
// NOTES:
//  (1) This is a placeholder method.  The real functionality is done by the
//  method for the GroupOfShortsEAViewItem class.
//  (2) Does not split the item if startIndexOfNewItem is zero or is greater
//  than the highest index in our subView.
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------

//----------------------------------------------------------------------
// METHOD: EAViewItem::combineWithNextItem  --CJB
//  
//  Combines this item with the next item.
//
// ARGS:
//  EAViewItem*             nextItem        IN  pointer to the next item in the EA space
//  Error&                  err             OUT error status
//
// RETURNS:
//  (none)
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  If the conditions are met, this GroupOfShorts EA view item is combined with
//  the next one.  Our lists and all applicable member variables are updated to
//  reflect this.
// 
// ERRORS:
//  (only error_None for this placeholder method)
// 
// NOTES:
//  (1) This is a placeholder method.  The real functionality is done by the
//  method for the GroupOfShortsEAViewItem class.
//  (2) Does nothing unless nextItem (1) is not NULL and (2) is a GroupOfShortsEAViewItem.
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------

//----------------------------------------------------------------------
// METHOD: EAViewItem::removeAllMyExtents  --CJB
//  
//  This method removes all extents from myLocalExtList_ and adds them to targetList.
//
// ARGS:
//  LogExtentList&          targetList      IN  extent list to move extents into
//  Error&                  err             OUT error status
//
// RETURNS:
//  (none)
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  All extents are moved from myLocalExtList_ to targetList.
// 
// ERRORS:
//  (only error_None for this placeholder method)
// 
// NOTES:
//  This is a placeholder method.  The real functionality is done by the
//  method for the LongEAViewItem class.
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------

//----------------------------------------------------------------------
// METHOD: EAViewItem::removeCallersDuplicateExtents  --CJB
//  
//  This method removes all extents from sourceList that are also in myLocalExtList_,
//  and adds them to targetList.
//
// ARGS:
//  LogExtentList&          sourceList      IN/OUT extent list to remove extents from
//  LogExtentList&          targetList      IN/OUT extent list to move extents into
//  Error&                  err             OUT error status
//
// RETURNS:
//  (none)
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  The specified extents are moved from sourceList to targetList.
// 
// ERRORS:
//  (only error_None for this placeholder method)
// 
// NOTES:
//  This is a placeholder method.  The real functionality is done by the
//  method for the LongEAViewItem class.
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------

//----------------------------------------------------------------------
// METHOD: EAViewItem::countDiskSpace  --CJB
//  
//  For testing. Returns the total number of disk blocks held by this item.
//
// ARGS:
//  UINT32                  blockSize       IN  size of a block on the media
//
// RETURNS:
//  UINT32 -- returns the total number of blocks for this item.
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  (none)
// 
// ERRORS:
//  (none)
// 
// NOTES:
//  (1) This method is for testing only, and will not appear in the final product.
//  (2) This is a placeholder method.  The real functionality is done by the
//  method for the LongEAViewItem class.
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------

//----------------------------------------------------------------------
// METHOD: EAViewItem::printAllocatedBlocks  --CJB
//  
//  For testing. Prints a list of all disk blocks held by this item.
//
// ARGS:
//  (none)
//
// RETURNS:
//  (none)
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  (none)
// 
// ERRORS:
//  (none)
// 
// NOTES:
//  (1) This method is for testing only, and will not appear in the final product.
//  (2) This is a placeholder method.  The real functionality is done by the
//  method for the LongEAViewItem class.
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------



//----------------------------------------------------------------------
// CLASS: ShortEAViewItem     --CJB
//
//  Derived class (from the EAViewItem class) for short EA View items (those with attribute
// lengths less than block size).
//
// PUBLIC DATA MEMBERS:
//    (none)
//
// PUBLIC METHODS:
//    ShortEAViewItem()         - Constructor.
//    ~ShortEAViewItem()        - Destructor.
//    length()                  - Returns the length that this item will have when it is written
//                                to its ByteArray.
//    ReadWriteEAByteArray()    - Returns a reference to the ByteArray, and marks the containing
//                                EA space dirty.
//    ReadOnlyEAByteArray()     - Returns a const reference to the ByteArray.
//    printItem ()              - Prints data about this item.
//    isA()                     - Returns the EAViewItemType of this class.
//    setPaddingToMin ()        - Sets the attribute length to the end of the valid data, rounded up
//                                to the next four byte boundary.
//    toISO()                   - Writes the data of this item to a buffer in its ISO form.
//
// USAGE NOTES:
//  User notes go here.
// 
//----------------------------------------------------------------------
// COLLABORATORS:  
//
// PRIVATE METHODS:
//    (none)
//
// IMPLEMENTATION NOTES:
//
//----------------------------------------------------------------------
class ShortEAViewItem : public EAViewItem {

protected:
    ByteArray       myLocalBA_;

    
public:
    // INLINE: ShortEAViewItem::ShortEAViewItem()
    ShortEAViewItem(void) {
        myLocalBA_ = ByteArray();
    }

    // INLINE: ShortEAViewItem::ShortEAViewItem()
    ShortEAViewItem(const ByteArrayRef & bar) {
        myLocalBA_ = ByteArray((CONST_BYTE_PTR)bar, bar.length());
    }

    // The default copy constructor is OK.

    // INLINE: ShortEAViewItem::ShortEAViewItem()
    virtual ~ShortEAViewItem() {}

    // INLINE: ShortEAViewItem::ShortEAViewItem()
    UINT32 length(void)                                 const   { return myLocalBA_.length(); }

    virtual ByteArray & ReadWriteEAByteArray(void);

    // INLINE: ShortEAViewItem::ShortEAViewItem()
    virtual const ByteArray & ReadOnlyEAByteArray(void) const   { return myLocalBA_; }

#if defined ENABLE_PRINTING
    void printItem (INT16 index, Boolean compositeList, INT16 indent) const;
#endif


    // Methods meant to be called only by member functions of this class and its derived classes,
    // and by their friends.

    // INLINE: ShortEAViewItem::ShortEAViewItem()
    RWClassID isA(void)                                 const   { return (RWClassID)ShortEAViewItemType; }

    void setPaddingToMin (UINT32 blockSize, Error & err);

    void toISO (Error & err);

}; // ShortEAViewItem

//----------------------------------------------------------------------
// METHOD: ShortEAViewItem::ShortEAViewItem  --CJB
//  
//  Constructor.
//
// ARGS:
//  (none)
//
// RETURNS:
//  (none)
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  Constructs a ShortEAViewItem object.
// 
// ERRORS:
//  (none)
// 
// NOTES:
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------

//----------------------------------------------------------------------
// METHOD: ShortEAViewItem::ShortEAViewItem  --CJB
//  
//  Constructor.
//
// ARGS:
//  const ByteArrayRef&     bar             IN  refers to data to copy into this item's ByteArray
//
// RETURNS:
//  (none)
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  Constructs a ShortEAViewItem object.
// 
// ERRORS:
//  (none)
// 
// NOTES:
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------

//----------------------------------------------------------------------
// METHOD: ShortEAViewItem::~ShortEAViewItem  --CJB
//  
//  Destructor.
//
// ARGS:
//  (none)
//
// RETURNS:
//  (none)
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  The ShortEAViewItem object is destroyed; all memory is deallocated.
// 
// ERRORS:
//  (none)
// 
// NOTES:
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------

//----------------------------------------------------------------------
// METHOD: ShortEAViewItem::length  --CJB
//  
//  Returns the length of the data for this EA view item.
//
// ARGS:
//  (none)
//
// RETURNS:
//  UINT32 -- returns the length of the data for this EA view item.
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  (none)
// 
// ERRORS:
//  (none)
// 
// NOTES:
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------

//----------------------------------------------------------------------
// METHOD: ShortEAViewItem::ReadOnlyEAByteArray  --CJB
//  
//  Returns a const reference to the ByteArray.
//
// ARGS:
//  (none)
//
// RETURNS:
//  const ByteArray& -- returns a const reference to the ByteArray of this item.
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  (none)
// 
// ERRORS:
//  (none)
// 
// NOTES:
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------

//----------------------------------------------------------------------
// METHOD: ShortEAViewItem::isA  --CJB
//  
//  Returns the enumerated type of this EA view item.
//
// ARGS:
//  (none)
//
// RETURNS:
//  RWClassID -- returns the enumerated type (ShortEAViewItemType) of this item.
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  (none)
// 
// ERRORS:
//  (none)
// 
// NOTES:
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------




//----------------------------------------------------------------------
// CLASS: EAViewHeaderItem     --CJB
//
//  Derived class (from the ShortEAViewItem class) that contains information for the EA Header.
//  There is only one header in an EA space.
//
// PUBLIC DATA MEMBERS:
//    (none)
//
// PUBLIC METHODS:
//    EAViewHeaderItem()        - Constructor.
//    ~EAViewHeaderItem()       - Destructor.
//    isA()                     - Returns the EAViewItemType of this class.
//    toISO()                   - Writes the data of this item to a buffer in its ISO form (for
//                                ShortEAViewItems only).
//    implOffset()              - Getter and setter methods for implOffset_, the offset to the first
//                                implementation use EA.
//    applOffset()              - Getter and setter methods for applOffset_, the offset to the first
//                                application use EA.
//    location()                - Setter method for location_, the logical block number where the
//                                EA header is written.
//    setPaddingToMin ()        - Sets the attribute length to the end of the valid data, rounded up
//                                to the next four byte boundary.
//    printItem ()              - Prints data about this item.
//
// USAGE NOTES:
//  User notes go here.
// 
//----------------------------------------------------------------------
// COLLABORATORS:  
//
// PRIVATE METHODS:
//    (none)
//
// IMPLEMENTATION NOTES:
//
//----------------------------------------------------------------------
class EAViewHeaderItem : public ShortEAViewItem {

private:
    UINT32          implOffset_;
    UINT32          applOffset_;
    UINT32          location_;


public:
    // Methods meant to be called only by member functions of this class and its derived classes,
    // and by their friends.

    // INLINE: EAViewHeaderItem::EAViewHeaderItem()
    EAViewHeaderItem(const ByteArrayRef & bar, UINT32 location) :
            ShortEAViewItem(bar),
            implOffset_(0),
            applOffset_(0),
            location_(location) {}

    // The default copy constructor is OK.

    // INLINE: EAViewHeaderItem::~EAViewHeaderItem()
    virtual ~EAViewHeaderItem() {}

    // INLINE: EAViewHeaderItem::isA()
    RWClassID isA(void)                             const   { return (RWClassID)EAViewHeaderItemType; }

    void toISO (Error & err);

    // INLINE: EAViewHeaderItem::implOffset()
    UINT32 implOffset(void)                         const   { return implOffset_; }

    // INLINE: EAViewHeaderItem::implOffset()
    void implOffset(UINT32 offset)                          { implOffset_ = offset; }

    // INLINE: EAViewHeaderItem::applOffset()
    UINT32 applOffset(void)                         const   { return applOffset_; }

    // INLINE: EAViewHeaderItem::applOffset()
    void applOffset(UINT32 offset)                          { applOffset_ = offset; }

    // INLINE: EAViewHeaderItem::location()
    void location(UINT32 location)                          { location_ = location; }

    // INLINE: EAViewHeaderItem::setPaddingToMin()
    void setPaddingToMin (UINT32 blockSize, Error & err)    { err = error_None; }

#if defined ENABLE_PRINTING
    void printItem (INT16 index, Boolean compositeList, INT16 indent) const;
#endif

}; // EAViewHeaderItem

//----------------------------------------------------------------------
// METHOD: EAViewHeaderItem::EAViewHeaderItem  --CJB
//  
//  Constructor.
//
// ARGS:
//  const ByteArrayRef&     bar             IN  data to copy into this item's ByteArray
//  UINT32                  location        IN  disk logical block number where this item is to be written
//
// RETURNS:
//  (none)
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  Constructs an EAViewHeaderItem object.
// 
// ERRORS:
//  (none)
// 
// NOTES:
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------

//----------------------------------------------------------------------
// METHOD: EAViewHeaderItem::~EAViewHeaderItem  --CJB
//  
//  Destructor.
//
// ARGS:
//  (none)
//
// RETURNS:
//  (none)
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  The EAViewHeaderItem object is destroyed; all memory is deallocated.
// 
// ERRORS:
//  (none)
// 
// NOTES:
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------

//----------------------------------------------------------------------
// METHOD: EAViewHeaderItem::isA  --CJB
//  
//  Returns the enumerated type of this EA view item.
//
// ARGS:
//  (none)
//
// RETURNS:
//  RWClassID -- returns the enumerated type (EAViewHeaderItemType) of this item.
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  (none)
// 
// ERRORS:
//  (none)
// 
// NOTES:
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------

//----------------------------------------------------------------------
// METHOD: EAViewHeaderItem::implOffset  --CJB
//  
//  Getter method for implOffset_.
//
// ARGS:
//  (none)
//
// RETURNS:
//  UINT32 -- returns the current value of implOffset_.
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  (none)
// 
// ERRORS:
//  (none)
// 
// NOTES:
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------

//----------------------------------------------------------------------
// METHOD: EAViewHeaderItem::implOffset  --CJB
//  
//  Setter method for implOffset_.
//
// ARGS:
//  UINT32                  implOffset      IN  new value for implOffset_.
//
// RETURNS:
//  (none)
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  This EA view item's implOffset_ variable is updated to the new value.
// 
// ERRORS:
//  (none)
// 
// NOTES:
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------

//----------------------------------------------------------------------
// METHOD: EAViewHeaderItem::applOffset  --CJB
//  
//  Getter method for applOffset_.
//
// ARGS:
//  (none)
//
// RETURNS:
//  UINT32 -- returns the current value of applOffset_.
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  (none)
// 
// ERRORS:
//  (none)
// 
// NOTES:
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------

//----------------------------------------------------------------------
// METHOD: EAViewHeaderItem::applOffset  --CJB
//  
//  Setter method for applOffset_.
//
// ARGS:
//  UINT32                  applOffset      IN  new value for applOffset_.
//
// RETURNS:
//  (none)
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  This EA view item's applOffset_ variable is updated to the new value.
// 
// ERRORS:
//  (none)
// 
// NOTES:
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------

//----------------------------------------------------------------------
// METHOD: EAViewHeaderItem::location  --CJB
//  
//  Setter method for location_.
//
// ARGS:
//  UINT32                  location        IN  new value for location_.
//
// RETURNS:
//  (none)
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  This EA view item's location_ variable is updated to the new value.
// 
// ERRORS:
//  (none)
// 
// NOTES:
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------




//----------------------------------------------------------------------
// CLASS: LongEAViewItem     --CJB
//
//  Derived class (from the EAViewItem class) for long EA View items (those with attribute
// lengths equal to or greater than block size).
//
// PUBLIC DATA MEMBERS:
//    (none)
//
// PUBLIC METHODS:
//    LongEAViewItem()          - Constructor.
//    ~LongEAViewItem()         - Destructor.
//    length()                  - Returns the length that this item will have when it is written
//                                to its LogExtentList.
//    ReadWriteEALogExtentList() - Returns a reference to the extent list, and marks
//                                the containing EA space dirty.
//    ReadOnlyEALogExtentList() - Returns a const reference to the extent list.
//    setPaddingToMin ()        - Sets the attribute length to the end of the valid data, rounded up
//                                to the next four byte boundary.
//    removeAllMyExtents ()     - Moves all extents held by this item, to the trash list.
//    removeCallersDuplicateExtents () - Removes all extents from sourceList that are also in this EA
//                                view item, and adds them to targetList.
//    countDiskSpace()          - For testing. Returns the total number of disk sectors held by
//                                this item.
//    printAllocatedBlocks()    - For testing. Prints a list of all disk sectors held by this item.
//    printItem ()              - Prints data about this item.
//    isA()                     - Returns the EAViewItemType of this class.
//
// USAGE NOTES:
//  User notes go here.
// 
//----------------------------------------------------------------------
// COLLABORATORS:  
//
// PRIVATE METHODS:
//    (none)
//
// IMPLEMENTATION NOTES:
//
//----------------------------------------------------------------------
class LongEAViewItem : public EAViewItem {

protected:
    LogExtentList   myLocalExtList_;


public:
    // INLINE: LongEAViewItem::LongEAViewItem()
    LongEAViewItem(const LogExtentList& eaExtList) :    
            myLocalExtList_(LogExtentList(eaExtList)) {
                error_ = myLocalExtList_.error();
    }

    // The default copy constructor is OK.

    // INLINE: LongEAViewItem::~LongEAViewItem()
    virtual ~LongEAViewItem(void) {}

    // INLINE: LongEAViewItem::length()
    UINT32 length(void)                                     const   { return myLocalExtList_.infoLen(); }

    LogExtentList & ReadWriteEALogExtentList(void)          const;

    // INLINE: LongEAViewItem::ReadOnlyEALogExtentList()
    const LogExtentList & ReadOnlyEALogExtentList(void)     const   { return myLocalExtList_; }

    // INLINE: LongEAViewItem::setPaddingToMin()
    void setPaddingToMin (UINT32 blockSize, Error & err)            { err = error_None; }

    // INLINE: LongEAViewItem::removeAllMyExtents()
    void removeAllMyExtents (LogExtentList & targetList, Error & err) {
        ExternalEASpace::moveExtentsFromSourceToTarget(myLocalExtList_, targetList, err);
    }

    // INLINE: LongEAViewItem::removeCallersDuplicateExtents()
    void removeCallersDuplicateExtents (LogExtentList & sourceList,
                                        LogExtentList & targetList, Error & err) {
        ExternalEASpace::moveExtentsFromSourceToTarget(sourceList, myLocalExtList_, targetList, err);
    }

#if defined DEBUG_EA__GENERAL
    // INLINE: LongEAViewItem::countDiskSpace()
    UINT32 countDiskSpace(UINT32 blockSize)                 const   { return myLocalExtList_.blockMultLen() / blockSize; }

    void printAllocatedBlocks(void)                         const;
#endif

#if defined ENABLE_PRINTING
    void printItem (INT16 index, Boolean compositeList, INT16 indent) const;
#endif


    // Methods meant to be called only by member functions of this class and its derived classes,
    // and by their friends.

    // INLINE: LongEAViewItem::isA()
    RWClassID isA(void)                                     const   { return (RWClassID)LongEAViewItemType; }

}; // LongEAViewItem

//----------------------------------------------------------------------
// METHOD: LongEAViewItem::LongEAViewItem  --CJB
//  
//  Constructor.
//
// ARGS:
//  const LogExtentList&    eaExtList       IN  data to copy into this item's extent list
//
// RETURNS:
//  (none)
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  Constructs a LongEAViewItem object.
// 
// ERRORS:
//  (call error() to get the object's error status.)
//  error_No_free_store
// 
// NOTES:
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------

//----------------------------------------------------------------------
// METHOD: LongEAViewItem::~LongEAViewItem  --CJB
//  
//  Destructor.
//
// ARGS:
//  (none)
//
// RETURNS:
//  (none)
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  The LongEAViewItem object is destroyed; all memory is deallocated.
// 
// ERRORS:
//  (none)
// 
// NOTES:
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------

//----------------------------------------------------------------------
// METHOD: LongEAViewItem::length  --CJB
//  
//  Returns the length of the data for this EA view item.
//
// ARGS:
//  (none)
//
// RETURNS:
//  UINT32 -- returns the length of the data for this EA view item.
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  (none)
// 
// ERRORS:
//  (none)
// 
// NOTES:
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------

//----------------------------------------------------------------------
// METHOD: LongEAViewItem::ReadOnlyEALogExtentList  --CJB
//  
//  Returns a const reference to this item's extent list.
//
// ARGS:
//  (none)
//
// RETURNS:
//  const LogExtentList& -- returns a const reference to the LogExtentList
//  of this item.
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  (none)
// 
// ERRORS:
//  (none)
// 
// NOTES:
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------

//----------------------------------------------------------------------
// METHOD: LongEAViewItem::setPaddingToMin  --CJB
//  
//  For every item in this item's subview, sets the attribute length to the end of
//  the valid data, rounded up to the next four byte boundary.
//
// ARGS:
//  UINT32                  blockSize       IN  length of a block on the media
//  Error&                  err             OUT error status
//
// RETURNS:
//  (none)
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  The padding of all items in this item's subview is modified as necessary.
// 
// ERRORS:
//  (only error_None for this placeholder method)
// 
// NOTES:
//  (1) This is a placeholder method.  The real functionality is done by the
//  method for the GroupOfShortsEAViewItem class.
//  (2) This method sets every item in this item's/sub view to its minimum length (ie.,
//  padded up to the next four byte boundary past the end of its data).  It also
//  guarantees that all data concerned with length is consistent in each item.
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------

//----------------------------------------------------------------------
// METHOD: LongEAViewItem::removeAllMyExtents  --CJB
//  
//  This method removes all extents from myLocalExtList_ and adds them to targetList.
//
// ARGS:
//  LogExtentList&          targetList      IN  extent list to move extents into
//  Error&                  err             OUT error status
//
// RETURNS:
//  (none)
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  All extents are moved from myLocalExtList_ to targetList.
// 
// ERRORS:
//  error_Required_object_not_present
//  error_No_free_store
//  error_Null_pointer;
// 
// NOTES:
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------

//----------------------------------------------------------------------
// METHOD: LongEAViewItem::removeCallersDuplicateExtents  --CJB
//  
//  This method removes all extents from sourceList that are also in myLocalExtList_,
//  and adds them to targetList.
//
// ARGS:
//  LogExtentList&          sourceList      IN/OUT extent list to remove extents from
//  LogExtentList&          targetList      IN/OUT extent list to move extents into
//  Error&                  err             OUT error status
//
// RETURNS:
//  (none)
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  The specified extents are moved from sourceList to targetList.
// 
// ERRORS:
//  error_Required_object_not_present
//  error_No_free_store
//  error_Null_pointer;
// 
// NOTES:
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------

//----------------------------------------------------------------------
// METHOD: LongEAViewItem::countDiskSpace  --CJB
//  
//  For testing. Returns the total number of disk blocks held by this item.
//
// ARGS:
//  UINT32                  blockSize       IN  size of a block on the media
//
// RETURNS:
//  UINT32 -- returns the total number of blocks for this item.
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  (none)
// 
// ERRORS:
//  (none)
// 
// NOTES:
//  This method is for testing only, and will not appear in the final product.
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------

//----------------------------------------------------------------------
// METHOD: LongEAViewItem::isA  --CJB
//  
//  Returns the enumerated type of this EA view item.
//
// ARGS:
//  (none)
//
// RETURNS:
//  RWClassID -- returns the enumerated type (LongEAViewItemType) of this item.
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  (none)
// 
// ERRORS:
//  (none)
// 
// NOTES:
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------




//----------------------------------------------------------------------
// CLASS: GroupOfShortsEAViewItem     --CJB
//
//  Derived class (from the LongEAViewItem class) that maintains a sublist of
//  short EA View items.
//
// PUBLIC DATA MEMBERS:
//    (none)
//
// PUBLIC METHODS:
//    GroupOfShortsEAViewItem() - Constructor.
//    ~GroupOfShortsEAViewItem()- Destructor.
//    copy_ ()                  - Method to do the actual work of the copy constructor and
//                                assignment operator.
//    operator= ()              - Assignment operator.
//    isA()                     - Returns the EAViewItemType of this class.
//    toDisk()                  - Writes the data of this item to the disk.
//    length()                  - Returns the length that this item will have when it is written
//                                to its LogExtentList.
//    numEntries()              - Returns the number of entries in the view.  This can be greater
//                                than one for GroupOfShortsEAViewItems; for all others it is one.
//    findIndex()               - Returns the index of a specified item, relative to this view.
//    setPaddingToMin ()        - Sets the attribute length to the end of the valid data, rounded up
//                                to the next four byte boundary.
//    determinePaddingNeeded ()`- Returns the amount and kind of padding needed to round this
//                                group of short items up to a block boundary.
//    findPadItemOffset()       - Returns the offset, relative to this item, where padding must be
//                                added during the toDisk() call.
//    at()                      - Returns a pointer to an item at a specified index in this view.
//    insertAt()                - Inserts an item into this item at a specified index.
//    removeAt()                - Removes an item from the view and returns a pointer to it.
//    removeAndDestroyAt()      - Removes an item from the view and calls its destructor.
//    splitItem ()              - Splits this item, at a specified index, into two items.
//    combineWithNextItem ()    - Combines this item with the next item.
//    printAllocatedBlocks()    - For testing. Prints a list of all disk sectors held by this item.
//    printItem ()              - Prints data about this item.
//
// USAGE NOTES:
//  User notes go here.
// 
//----------------------------------------------------------------------
// COLLABORATORS:  
//
// PRIVATE METHODS:
//    (none)
//
// IMPLEMENTATION NOTES:
//
//----------------------------------------------------------------------
class GroupOfShortsEAViewItem : public LongEAViewItem {

private:
    ByteArray               eaSubViewBA_;
    ShortEAView *           subView_;
    UINT32                  blockSize_;


public:
    // Methods meant to be called only by member functions of this class and its derived classes,
    // and by their friends.

    GroupOfShortsEAViewItem(UINT32 blockSize);

    // INLINE: GroupOfShortsEAViewItem::GroupOfShortsEAViewItem()
    GroupOfShortsEAViewItem(const GroupOfShortsEAViewItem & x) :    // copy constructor
            LongEAViewItem(x.myLocalExtList_) {
                copy_(x, error_);
    }

    // INLINE: GroupOfShortsEAViewItem::~GroupOfShortsEAViewItem()
    virtual ~GroupOfShortsEAViewItem(void)                  { if (subView_) delete subView_; subView_ = NULL; }

    void  copy_ (const GroupOfShortsEAViewItem & x, Error & err);

    // INLINE: GroupOfShortsEAViewItem::operator=()
    GroupOfShortsEAViewItem& operator= (const GroupOfShortsEAViewItem &x) {
        copy_(x, error_); 
        return *this;
    }

    // INLINE: GroupOfShortsEAViewItem::isA()
    RWClassID   isA(void)                           const   { return (RWClassID)GroupOfShortsEAViewItemType; }

    void toDisk (SpaceResource & space, Error & err);

    UINT32 length(void)                             const;

    UINT16 numEntries(void)                         const;

    INT16 findIndex(const EAViewItem* itemToFind)   const;

    void setPaddingToMin (UINT32 blockSize, Error & err);

    void determinePaddingNeeded (UINT32 &growLastItemLen,
                                 UINT32 &freeSpaceEALen, Error & err)        const;

    UINT32 findPadItemOffset(Error & err)           const;

    const EAViewItem * at(INT16 index, Error & err) const;

    EAViewItem * at(INT16 index, Error & err);
  
    void insertAt(ShortEAViewItem * seavi, INT16 index, Error & err);

    EAViewItem * removeAt(INT16 index, Error & err);

    // INLINE: GroupOfShortsEAViewItem::removeAndDestroyAt()
    void  removeAndDestroyAt(INT16 index, Error & err) { delete this->removeAt(index, err); }

    GroupOfShortsEAViewItem * splitItem (INT16 startIndexOfNewItem, Error & err);

    void combineWithNextItem (EAViewItem * nextItem, Error & err);

#if defined DEBUG_EA__GENERAL
    void printAllocatedBlocks(void)                         const;
#endif

#if defined ENABLE_PRINTING
    void printItem (INT16 index, Boolean compositeList, INT16 indent) const;
#endif

}; // GroupOfShortsEAViewItem

//----------------------------------------------------------------------
// METHOD: GroupOfShortsEAViewItem::GroupOfShortsEAViewItem  --CJB
//  
//  Copy constructor.
//
// ARGS:
//  const GroupOfShortsEAViewItem& x        IN  source object to copy
//
// RETURNS:
//  (none)
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  A GroupOfShortsEAViewItem object is constructed which is a copy of x.
// 
// ERRORS:
//  (call error() to get the object's error status.)
//  error_Null_pointer
//  error_EA_Invalid_EA_type
//  error_No_free_store
// 
// NOTES:
//  If x is the same as this, nothing is done--ie., we don't copy to ourself.
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------

//----------------------------------------------------------------------
// METHOD: GroupOfShortsEAViewItem::~GroupOfShortsEAViewItem  --CJB
//  
//  Destructor.
//
// ARGS:
//  (none)
//
// RETURNS:
//  (none)
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  The GroupOfShortsEAViewItem object is destroyed; all memory is deallocated.
// 
// ERRORS:
//  (none)
// 
// NOTES:
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------

//----------------------------------------------------------------------
// METHOD: GroupOfShortsEAViewItem::operator=  --CJB
//  
//  Assignment operator.
//
// ARGS:
//  const GroupOfShortsEAViewItem& x        IN  source object to copy
//
// RETURNS:
//  (none)
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  Assigns a copy of the source object into the specified object.
// 
// ERRORS:
//  (call error() to get the object's error status.)
//  error_Null_pointer
//  error_EA_Invalid_EA_type
//  error_No_free_store
// 
// NOTES:
//  If x is the same as this, nothing is done--ie., we don't assign to ourself.
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------

//----------------------------------------------------------------------
// METHOD: GroupOfShortsEAViewItem::isA  --CJB
//  
//  Returns the enumerated type of this EA view item.
//
// ARGS:
//  (none)
//
// RETURNS:
//  RWClassID -- returns the enumerated type (GroupOfShortsEAViewItemType) of this item.
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  (none)
// 
// ERRORS:
//  (none)
// 
// NOTES:
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------

//----------------------------------------------------------------------
// METHOD: GroupOfShortsEAViewItem::removeAndDestroyAt  --CJB
//  
//  Removes a selected EA view item from this EA view item, and calls it's destructor.
//
// ARGS:
//  INT16                   index           IN  index into this EA view item, of item to operate on
//  Error&                  err             OUT error status
//
// RETURNS:
//  (none)
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  The item is removed from our lists, and it is destroyed.
// 
// ERRORS:
//  error_Required_object_not_present
//  error_Index_out_of_bounds
// 
// NOTES:
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------




//----------------------------------------------------------------------
// CLASS: EASpace     --CJB
//
//  Abstract base class for the EASpace classes.  These classes are the highest level
//  classes, and are the ones that users have their main interaction with.
//  These classes convert the separate physical lists used in the various EAView and
//  EAViewItem classes, into an abstraction called the EA space.
//
// PUBLIC DATA MEMBERS:
//    (none)
//
// PUBLIC METHODS:
//    EASpace()                 - Constructor.
//    ~EASpace()                - Destructor.
//    error()                   - Returns error state of the object.
//    length()                  - Returns the total data length this EA space will have when it is
//                                written to its ByteArray or LogExtentList.  It includes the
//                                length of the header.
//    numEntries()              - Returns the total number of items in this EA space, not including
//                                the header.
//    bytesAvailable()          - Returns the remaining number of bytes available for use (for
//                                embedded EA space only).
//    at()                      - Fetches an item by (virtual) index.
//    insert ()                 - Inserts an item into the EA space.  Ordering is done automatically,
//                                according to the ISO and OSTA rules.
//    putIntoTrashList ()       - Puts an extent list into our internal "trash list".  It is not
//                                actually deallocated by this method.
//    findNextMatch()           - Returns the first or next item with a specified regKey.
//    findFirstPadItemOffset()  - Returns the offset of the first EA free space item (for external
//                                EA space only).
//    printCompositeList ()     - Prints the virtual list of items in this EA space.
//    printPhysicalLists ()     - Prints the various underlying physical lists in this EA space.
//    isA()                     - Returns the EASpaceType of this class.
//    dirty ()                  - Setter method for dirty_, which indicates if data needs to be
//                                written in the toDisk() method.
//
// USAGE NOTES:
//  When specifying an intem in the EA space by an index, a distinction is made between
//  "physical index", which includes all items, and "virtual index" where the header is
//  hidden and item zero is the first non-header item.  Only virtual indices are used in
//  the public interface.
// 
//----------------------------------------------------------------------
// COLLABORATORS:  
//
// PRIVATE METHODS:
//    findNextOfThisCategory()  - Returns the first or next item of a specified EACategory (see
//                                EARegistryEntry::eaCategory()).
//    privateAt()               - Fetches an EAViewItem by physical index of the EASpace.
//    privateRemoveAt()         - Removes an EAViewItem by physical index of the EASpace,
//                                returning a pointer to the removed item.
//    privateInsert ()          - Does the actual work of inserting an item into the EA space.
//    createHeader ()           - Creates a header item, and inserts it into the EA space.
//    updateHeaderOffsets ()    - Updates the offsets that the header item keeps, to the first
//                                implementation and application use EAs.
//    updateHeaderLocation ()   - Updates the location that the header item keeps, of the
//                                logical block number where it is to be written on disk.
//
// IMPLEMENTATION NOTES:
//
//----------------------------------------------------------------------
class EASpace {

protected:
    LogicalVolume&  logicalVolume_;
    UINT32          blockSize_;
    Boolean         dirty_;
    Error           error_;


private:
    static NSR::UINT32   numInstances;

        
public:
    EASpace (LogicalVolume& logicalVolume);

    // The default copy constructor is OK.

    virtual ~EASpace(void);

    // INLINE: EASpace::error()
    Error error(void)               const   { return error_; }

    virtual UINT32 length(void)     const = 0;

    virtual UINT32 numEntries(void) const = 0;

    // INLINE: EASpace::bytesAvailable()
    virtual INT32 bytesAvailable(Node& myNode, Error& err) const { err = error_None; return 0; }

    virtual const EAViewItem * at(INT16 index, Error & err) const = 0;

    virtual const EAViewItem * insert (const ShortEAViewItem & seavi, Error & err) = 0;

    // INLINE: EASpace::putIntoTrashList()
    void putIntoTrashList (LogExtentList& sourceList, Error & err)  { err = error_None; }

    const EAViewItem * findNextMatch(UINT32 regKey, INT16  *index, Error & err) const;

    // INLINE: EASpace::findFirstPadItemOffset()
    virtual UINT32  findFirstPadItemOffset(Error & err) const { err = error_None; return 0; }

#if defined ENABLE_PRINTING
    void printCompositeList (INT16 indent=0) const;

    virtual void printPhysicalLists (INT16 indent=0) const = 0;
#endif


    // Methods meant to be called only by member functions of this class and its derived classes,
    // and by their friends.

    // INLINE: EASpace::isA()
    virtual EASpaceType isA(void)   const   { return NoEASpaceType; }

    // INLINE: EASpace::dirty()
    void dirty (Boolean newValue)           { dirty_ = newValue; }


protected:
    const EAViewItem * findNextOfThisCategory(EACategory category, INT16  * index, Error & err) const;
    
    virtual const EAViewItem * privateAt(INT16 index, Error & err) const = 0;

    virtual EAViewItem * privateAt(INT16 index, Error & err) = 0;

    virtual EAViewItem * privateRemoveAt(INT16 index, Error & err) = 0;

    virtual const EAViewItem * privateInsert(const NSR::ShortEAViewItem & seavi, UINT32 regKey,
                                             Error & err) = 0;

    void  createHeader (UINT32 location, Error & err);

    void updateHeaderOffsets (Error & err) const;

    void updateHeaderLocation (UINT32 location, Error & err) const;
    
}; // EASpace

//----------------------------------------------------------------------
// METHOD: EASpace::error  --CJB
//  
//  Gets the error state of this object.
//
// ARGS:
//  (none)
//
// RETURNS:
//  Error -- returns an Error object containing the error state of this object.
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  (none)
// 
// ERRORS:
//  (none)
// 
// NOTES:
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------

//----------------------------------------------------------------------
// METHOD: EASpace::bytesAvailable  --CJB
//  
//  Returns the remaining number of bytes available for use in the embedded
//  EA space of the NSR file node.
//
// ARGS:
//  Node&                   myNode          IN  the NSR file node
//  Error&                  err             OUT error status
//
// RETURNS:
//  INT32 -- returns the remaining number of bytes available in the embedded
//  EA space of the NSR file node. A negative number indicates a deficit--ie.,
//  the data will fail to fit by that many bytes.  Zero indicates that the
//  data will just fit.
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  (none)
// 
// ERRORS:
//  (only error_None for this placeholder method)
// 
// NOTES:
//  (1) This is a placeholder method.  The real functionality is done by the
//  method for the EmbeddedEASpace class.
//  (2) This EA space does not have to be formally associated with the NSR file
//  node in any way--it could have been constructed and populated via inserts
//  and removes without ever havin done a fromISO().  In that case this method
//  returns the hypothetical number of bytes available if the caller were to
//  do a toISO() call.
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------

//----------------------------------------------------------------------
// METHOD: EASpace::putIntoTrashList  --CJB
//  
//  Moves all extents from the source list into the trash list.  Checks for
//  the extents already existing in the trash list and does not insert duplicates,
//  although they are removed from the source list.
//
// ARGS:
//  LogExtentList&          sourceList      IN  extent list to put into the trash list
//  Error&                  err             OUT error status
//
// RETURNS:
//  (none)
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  All extents are removed from the source list, and moved to the trash list.
// 
// ERRORS:
//  (only error_None for this placeholder method)
// 
// NOTES:
//  This is a placeholder method.  The real functionality is done by the
//  method for the ExternalEASpace class.
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------

//----------------------------------------------------------------------
// METHOD: EASpace::findFirstPadItemOffset  --CJB
//  
//  Returns the offset, relative to this EA space, to the first point where
//  an EA free space item will be added during the toDisk() call.
//
// ARGS:
//  Error&                  err             OUT error status
//
// RETURNS:
//  UINT32 -- returns the offset, relative to this entire EA space, where
//  the data of the first EA free space item will be put by the toDisk() call.
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  (none)
// 
// ERRORS:
//  (only error_None for this placeholder method)
// 
// NOTES:
//  (1) This is a placeholder method.  The real functionality is done by the
//  method for the ExternalEASpace class.
//  (2) Notice that no padding is carried in this EA space or its subview.
//  (The attribute length of each item is always rounded up to a four byte
//  boundary; that's it.) Padding is only added to the data written out by the
//  toDisk() method--even there it is not put into this item or its subview.
//  If you need to know where and how much padding will be added by toDisk(),
//  see the GroupOfShortsEAViewItem::determinePaddingNeeded() method.
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------

//----------------------------------------------------------------------
// METHOD: EASpace::isA  --CJB
//  
//  Returns the enumerated type of this EA space.
//
// ARGS:
//  (none)
//
// RETURNS:
//  RWClassID -- returns the enumerated type (EASpaceType) of this EA space.
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  (none)
// 
// ERRORS:
//  (none)
// 
// NOTES:
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------

//----------------------------------------------------------------------
// METHOD: EASpace::dirty  --CJB
//  
//  Setter method for dirty_.
//
// ARGS:
//  Boolean                 newValue        IN  new value for the dirty_ variable.
//
// RETURNS:
//  (none)
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  This EA space's dirty_ variable is updated to the new value.
// 
// ERRORS:
//  (none)
// 
// NOTES:
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------




//----------------------------------------------------------------------
// CLASS: EmbeddedEASpace     --CJB
//
//  EA space class for EAs that are embedded in the main file node.  The items in this
//  embedded EA space are all short items--their length is less than block size.
//
// PUBLIC DATA MEMBERS:
//    (none)
//
// PUBLIC METHODS:
//    EmbeddedEASpace()         - Constructor.
//    ~EmbeddedEASpace()        - Destructor.
//    copy_ ()                  - Method to do the actual work of the copy constructor and
//                                assignment operator.
//    operator= ()              - Assignment operator.
//    fromISO()                 - Reads the data of this EA space from a buffer in its ISO form.
//    toISO()                   - Writes the data of this EA space to a buffer in its ISO form.
//    length()                  - Returns the total data length this EA space will have when it is
//                                written to its ByteArray.  It includes the length of the header.
//    isA()                     - Returns the EASpaceType of this class.
//    numEntries()              - Returns the total number of items in this EA space, not including
//                                the header.
//    at()                      - Fetches an item by (virtual) index.
//    removeAt()                - Removes the EAviewItem at a virtual index of this EA space, and
//                                returns a pointer to the removed item.
//    removeAndDestroyAt()      - Removes the EAviewItem at a virtual index of this EA space, and
//                                calls the destructor for the item.
//    insert ()                 - Inserts an item into the EA space.  Ordering is done automatically,
//                                according to the ISO and OSTA rules.
//    bytesAvailable()          - Returns the remaining number of bytes available for use.
//    printPhysicalLists ()     - Prints the various underlying physical lists in this EA space.
//
// USAGE NOTES:
//  (See the notes for the EASpace base class.)
// 
//----------------------------------------------------------------------
// COLLABORATORS:  
//
// PRIVATE METHODS:
//    findInsertionPoint()      - Finds the point where a specified item should be inserted.
//    privateAt()               - Fetches an EAViewItem by physical index of the EASpace.
//    privateRemoveAt()         - Removes an EAViewItem by physical index of the EASpace, and
//                                returns a pointer to the removed item.
//    privateInsert ()          - Does the actual work of inserting an item into the embedded EA space.
//
// IMPLEMENTATION NOTES:
//
//----------------------------------------------------------------------
class EmbeddedEASpace : public EASpace {

private:
    ByteArray &         srcByteArray_;
    ShortEAView *       eaView_;


public:
    EmbeddedEASpace(LogicalVolume& logicalVolume, ByteArray & srcBA);

    // INLINE: EmbeddedEASpace::EmbeddedEASpace()
    EmbeddedEASpace(const EmbeddedEASpace & x) :    // copy constructor
            EASpace (x.logicalVolume_),
            srcByteArray_(x.srcByteArray_) {
                copy_(x, error_);
    }

    virtual ~EmbeddedEASpace(void);

    void  copy_ (const EmbeddedEASpace & x, Error & err);

    // INLINE: EmbeddedEASpace::operator=()
    EmbeddedEASpace& operator= (const EmbeddedEASpace &x) {
        copy_(x, error_); 
        return *this;
    }

    void fromISO (UINT32 nodeLocation, Error & err);

    void toISO (UINT32 nodeLocation, Error & err);

    UINT32 length(void)     const;

    // INLINE: EmbeddedEASpace::isA()
    EASpaceType isA(void)   const   { return EmbeddedEASpaceType; }

    UINT32 numEntries(void) const;

    // INLINE: EmbeddedEASpace::at()
    const EAViewItem * at(INT16 index, Error & err) const { return this->privateAt(index+1, err); }

    // INLINE: EmbeddedEASpace::removeAt()
    EAViewItem * removeAt(INT16 index, Error & err) { return this->privateRemoveAt(index+1, err); }

    // INLINE: EmbeddedEASpace::removeAndDestroyAt()
    void removeAndDestroyAt(INT16 index, Error & err) { delete (void *) this->privateRemoveAt(index+1, err); }

    const EAViewItem * insert (const ShortEAViewItem & seavi, Error & err);

    INT32 bytesAvailable(Node& myNode, Error& err) const;

                        
#if defined ENABLE_PRINTING
    void printPhysicalLists (INT16 indent=0) const;
#endif  

                        
private:
    void findInsertionPoint(const EAViewItem * myItem, INT16 & index, Error & err) const;

    const EAViewItem * privateAt(INT16 index, Error & err) const;

    EAViewItem * privateAt(INT16 index, Error & err);

    EAViewItem * privateRemoveAt(INT16 index, Error & err);

    const EAViewItem * privateInsert(const NSR::ShortEAViewItem & seavi, UINT32 regKey, Error & err);

}; // EmbeddedEASpace

//----------------------------------------------------------------------
// METHOD: EmbeddedEASpace::EmbeddedEASpace  --CJB
//  
//  Copy constructor.
//
// ARGS:
//  const EmbeddedEASpace&  x               IN  source object to copy
//
// RETURNS:
//  (none)
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  An EmbeddedEASpace object is constructed which is a copy of x.
// 
// ERRORS:
//  (call error() to get the object's error status.)
//  error_Null_pointer
//  error_EA_Invalid_EA_type
//  error_No_free_store
// 
// NOTES:
//  If x is the same as this, nothing is done--ie., we don't copy to ourself.
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------

//----------------------------------------------------------------------
// METHOD: EmbeddedEASpace::operator=  --CJB
//  
//  Assignment operator.
//
// ARGS:
//  const EmbeddedEASpace&  x               IN  source object to copy
//
// RETURNS:
//  (none)
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  Assigns a copy of the source object into the specified object.
// 
// ERRORS:
//  (call error() to get the object's error status.)
//  error_Null_pointer
//  error_EA_Invalid_EA_type
//  error_No_free_store
// 
// NOTES:
//  If x is the same as this, nothing is done--ie., we don't assign to ourself.
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------

//----------------------------------------------------------------------
// METHOD: EmbeddedEASpace::isA  --CJB
//  
//  Returns the enumerated type of this EA space.
//
// ARGS:
//  (none)
//
// RETURNS:
//  RWClassID -- returns the enumerated type (EmbeddedEASpaceType) of this EA space.
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  (none)
// 
// ERRORS:
//  (none)
// 
// NOTES:
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------

//----------------------------------------------------------------------
// METHOD: EmbeddedEASpace::at  --CJB
//  
//  Returns a const pointer to an EAViewItem by virtual index of the EASpace.
//
// ARGS:
//  INT16                   index           IN  virtual index into this EA space
//  Error&                  err             OUT error status
//
// RETURNS:
//  const EAViewItem* -- returns a pointer to the specified EA view item, or NULL
//  if there is a problem.
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  (none)
// 
// ERRORS:
//  error_Required_object_not_present
//  error_Index_out_of_bounds
// 
// NOTES:
//  IMPORTANT: This method expects a virtual index.
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------

//----------------------------------------------------------------------
// METHOD: EmbeddedEASpace::removeAt  --CJB
//  
//  Removes an EAViewItem by virtual index of the EASpace, and returns a
//  pointer to the removed item.
//
// ARGS:
//  INT16                   index           IN  virtual index into this EA space
//  Error&                  err             OUT error status
//
// RETURNS:
//  EAViewItem* -- returns a pointer to the specified EA view item and
//  removes it from this EA view. Returns NULL if there is any problem.
//  The dirty flag is set.
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  The specified EA view item is removed from this EA space.
// 
// ERRORS:
//  error_Required_object_not_present
//  error_Index_out_of_bounds
//  error_No_free_store
//  error_Null_pointer;
//  error_REGISTRY_Entry_not_found  (if regKey is invalid)
// 
// NOTES:
//  This method does not delete the returned object--It is the caller's
//  responsibility to do that.
//  IMPORTANT: This method expects a virtual index.
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------

//----------------------------------------------------------------------
// METHOD: EmbeddedEASpace::removeAndDestroyAt  --CJB
//  
//  Removes a selected EA view item from this EA space, and calls it's destructor.
//
// ARGS:
//  INT16                   index           IN  virtual index into this EA space
//  Error&                  err             OUT error status
//
// RETURNS:
//  (none)
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  The specified EA view item is removed from this EA space and deleted.
//  The dirty flag is set.
// 
// ERRORS:
//  error_Required_object_not_present
//  error_Index_out_of_bounds
// 
// NOTES:
//  IMPORTANT: This method expects a virtual index.
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------




//----------------------------------------------------------------------
// CLASS: ExternalEASpace     --CJB
//
//  EA space class for EAs that are not embedded in the main file node, but are held instead by
//  an auxilliary "EA node".  The items in this external EA space may be either short items
//  (attribute length less than block size) or long items (attribute length equal to or greater
//  than block size).
//
// PUBLIC DATA MEMBERS:
//    (none)
//
// PUBLIC METHODS:
//    ExternalEASpace()         - Constructor.
//    ~ExternalEASpace()        - Destructor.
//    copy_ ()                  - Method to do the actual work of the copy constructor and
//                                assignment operator.
//    operator= ()              - Assignment operator.
//    fromDisk()                - Reads the data of this EA space from the disk.
//    toDisk()                  - Writes the data of this EA space to the disk.
//    length()                  - Returns the total data length this EA space will have when it is
//                                written to its LogExtentList.  It includes the length of the header.
//    numEntries()              - Returns the total number of items in this EA space, not including
//                                the header.
//    at()                      - Fetches an item by (virtual) index.
//    removeDeallocateAndDestroyAt() - Removes the item at an index in our list, destroys the
//                                item object, and deallocates any associated disk space.
//    insert ()                 - Inserts an item into the EA space.  Ordering is done automatically,
//                                according to the ISO and OSTA rules.
//    findFirstPadItemOffset()  - Returns the offset of the first EA free space item.
//    putIntoTrashList ()       - Puts an extent list into our internal "trash list". The space is
//                                not actually deallocated by this method.
//    emptyTrashList ()         - Actually deallocates all disk space that is in the "trash list",
//                                after first checking each extent to make sure it is not in use
//                                internally in this EA space, or in the caller's extent list.
//    deallocateCallersExtentList () -  Puts all disk space of the caller's extent list into the
//                                "trash list". The space is not actually deallocated by this method.
//    deallocateEADiskSpace()   - Puts all disk space held internally in this EA space, into the
//                                "trash list". The space is not actually deallocated by this method.
//    moveExtentsFromSourceToTarget() - Overloaded static methods to move extents from a specified
//                                source extent list to a specified target extent list. One method
//                                unconditionally moves all extents; another moves only those
//                                extents that are also in a third "compare list".
//    printPhysicalLists ()     - Prints the various underlying physical lists in this EA space.
//    markExtentsAllocatedForTesting () - For testing. Static method to mark the extents of a
//                                specified extent list as allocated in our internal test tables.
//                                Prints a message if any of the extents are already marked as
//                                allocated in the table.
//    markExtentsFreeForTesting () - For testing. Static method to  mark the extents of a
//                                specified extent list as free in our internal test tables.
//                                Prints a message if any of the extents are already marked as
//                                free in the table.
//    printSpaceResourceAllocatedBlks () - For testing. Static method to print the extents that
//                                are morked as allocated in our internal test table.
//    countSpaceResourceAllocatedBlks () - For testing. Static method to return the number of
//                                extents that are morked as allocated in our internal test table.
//    countDiskSpace()          - For testing. Static method to return the total number of disk
//                                sectors held internally by this EA space.
//    printAllocatedBlocks()    - For testing. Static method to print a list of all disk sectors
//                                held internally by this EA space.
//    printSpaceInfo ()         - For testing.  Static method to print all information about the
//                                disk space held internally by this EA space, and held in the
//                                caller's extent list.
//    printLogExtentList ()     - For testing. Static method to print the logical block numbers
//                                of every extent in a specified extent list.
//    dumpLogExtentList ()      - For testing.  Static method to dump the entire data of a specified
//                                extent list to a file on the native file system.
//    isA()                     - Returns the EASpaceType of this class.
//
// USAGE NOTES:
//  (Also see the notes for the EASpace base class.)
//  The caller of this class will have to be aware of whether an EA is short
//  or long, and when to change an EA from short to long or vice versa, but not of
//  any of the details of inserting, removing, ordering, splitting or combining
//  GroupOFShorts items, padding, etc.
//
//  Disk space management is a complex issue that the user will have to be aware of.
//  From the instant that a Eview item is inserted into this EA space, either explicitly by
//  the user or implicitly by the fromDisk() method, the EA space takes responsibility for
//  its disk space.  If the user wishes to remove an item from the EA space he should call
//  removeDeallocateAndDestroyAt(), which does just what its name suggests.
//
//  If any changes have been made, the user should call toDisk() before deleting the EA space
//  object. When the EA space destructor is called, it deallocates all disk space held internally
//  that is not also in the caller's extent list.  If the caller wishes to also deallocate the disk
//  space of his extent list he should call deallocateCallersExtentList() before calling the
//  EA space destructor.
//
//  Internally, the EA space uses a "trash list" that holds extents slated for deallocation.
//  When the actual deallocation is to be done, it first checks that the extents are not in
//  used, either internally or in the caller's extent list.
// 
//----------------------------------------------------------------------
// COLLABORATORS:  
//
// PRIVATE METHODS:
//    findInsertionPoint()      - Returns the internal indices needed to insert an item into
//                                this EA space.
//    privateAt()               - Fetches an EAViewItem by physical index of the EASpace.
//    privateRemoveAt()         - Removes an EAViewItem by physical index of the EASpace,
//                                returning a pointer to the removed item.
//    privateInsert ()          - Does the actual work of inserting an item into the EA space.
//    readBlockOfLEL ()         - Method used by fromDisk() to read data from the caller's
//                                extent list one block at a time.
//    insertIntoAllocBlksTab () - For testing. Static method to insert a single extent into our
//                                internal test table.
//    removeFromAllocBlksTab () - For testing. Static method to remove a single extent from our
//                                internal test table.
//
// IMPLEMENTATION NOTES:
//
//----------------------------------------------------------------------
class ExternalEASpace : public EASpace {

private:
    LongEAView  *       eaView_;
    LogExtentList &     callersLel_;
#if defined DEBUG_EA__TRACK_DISK_ALLOCATION
    static UINT32       allocatedBlkTabEntries;
    static ABT          allocatedBlkTab[MAX_ALLOC_TAB_ENTRIES];
#endif
#if defined DEBUG_EA__GENERAL
public:
#endif
    ISOSpaceResource *  spaceResource_;
    LogExtentList       trashLel_;
    

public:
    ExternalEASpace (LogExtentList & lel, ISOSpaceResource *spaceResource);

    // INLINE: ExternalEASpace::ExternalEASpace()
    ExternalEASpace(const ExternalEASpace & x) :    // copy constructor
            EASpace (x.logicalVolume_),
            callersLel_(x.callersLel_),
            trashLel_(x.trashLel_) {
                copy_(x, error_);
    }

    virtual ~ExternalEASpace (void);

    void  copy_ (const ExternalEASpace & x, Error & err);

    // INLINE: ExternalEASpace::operator=()
    ExternalEASpace& operator= (const ExternalEASpace &x) {
        copy_(x, error_); 
        return *this;
    }

    void fromDisk (Error & err);

    void toDisk (Error & err);

    UINT32 length(void)                                 const;

    UINT32 numEntries(void)                             const;

    // INLINE: ExternalEASpace::at()
    const EAViewItem* at(INT16 index, Error & err)      const   { return this->privateAt(index+1, err); }
 
    void removeDeallocateAndDestroyAt(INT16 index, Error & err);

    const EAViewItem * insert (const ShortEAViewItem & seavi, Error & err);

    const EAViewItem * insert (const LongEAViewItem & leavi, Error & err);

    UINT32  findFirstPadItemOffset (Error & err)        const;

    // INLINE: ExternalEASpace::putIntoTrashList()
    void putIntoTrashList (LogExtentList& sourceList, Error & err) {
        ExternalEASpace::moveExtentsFromSourceToTarget(sourceList, trashLel_, err);
    }

    void emptyTrashList (Error & err);

    // INLINE: ExternalEASpace::deallocateCallersExtentList()
    void deallocateCallersExtentList (Error & err)      { this->putIntoTrashList(callersLel_, err); }

    void deallocateEADiskSpace(Error & err);
    
    static void moveExtentsFromSourceToTarget(LogExtentList & sourceList,
                                              LogExtentList & targetList, Error & err);

    static void moveExtentsFromSourceToTarget(LogExtentList & sourceList,
                                              const LogExtentList & compareList, LogExtentList & targetList, Error & err);

#if defined ENABLE_PRINTING
    void printPhysicalLists (INT16 indent=0)            const;
#endif

#if defined DEBUG_EA__TRACK_DISK_ALLOCATION
    static void  markExtentsAllocatedForTesting (const NSR::LogExtentList& lel);

    static void  markExtentsFreeForTesting (const NSR::LogExtentList& lel);

    static void  printSpaceResourceAllocatedBlks (void);

    static UINT32  countSpaceResourceAllocatedBlks (void);
#endif

#if defined DEBUG_EA__GENERAL
    UINT32 countDiskSpace(UINT32 blockSize)             const;

    void printAllocatedBlocks(void)                     const;

    static void  printSpaceInfo (ExternalEASpace& externalEASpace, LogExtentList& extList,
                                 Boolean verbose);

    static void  printSpaceInfo (LogExtentList& extList, INT32 freeSectors, Boolean verbose);

    static void  printSpaceInfo (INT32 freeSectors, INT32 extListSectors, INT32 eaSpaceSectors,
                                 INT32 trashListSectors, Boolean verbose);

    static void  printLogExtentList (const NSR::LogExtentList& lel);

#if defined MAC_PLATFORM
    static void dumpLogExtentList (const LogExtentList & lel, UINT16 extension_num, Error & err);
#endif
#endif

    // Methods meant to be called only by member functions of this class and its derived classes,
    // and by their friends.

    // INLINE: ExternalEASpace::isA()
    EASpaceType isA(void)   const   { return ExternalEASpaceType; }


private:
    void findInsertionPoint(const EAViewItem * myItem, INT16 & topLevelIndex,
                            INT16 & secondLevelIndex, INT16 & topLevelIndexOfPrev,
                            INT16 & secondLevelIndexOfPrev, Error & err) const;
  
    const EAViewItem * privateAt(INT16 index, Error & err) const;

    EAViewItem * privateAt(INT16 index, Error & err);

    EAViewItem * privateAt(INT16 index, INT16 * topLevelIndex,
                           INT16 * secondLevelIndex, Error & err);

    EAViewItem * privateRemoveAt(INT16 index, Error & err);

    const EAViewItem * privateInsert (const NSR::ShortEAViewItem & seavi, UINT32 regKey, Error & err);

    const EAViewItem * privateInsert (const NSR::LongEAViewItem & leavi, UINT32 regKey, Error & err);

    void readBlockOfLEL (LogExtentList &myLEL, ByteArray &myBA, INT32 &bytesLeftInBuf,
                         INT32 &originalReadLen, UINT32 &blocksToAdvance, Error &err);

#if defined DEBUG_EA__TRACK_DISK_ALLOCATION
    static void  insertIntoAllocBlksTab (UINT32 startBlock, UINT32 numBlocks);

    static void  removeFromAllocBlksTab (UINT32 startBlock, UINT32 numBlocks);
#endif
    
}; // ExternalEASpace

//----------------------------------------------------------------------
// METHOD: ExternalEASpace::ExternalEASpace  --CJB
//  
//  Copy constructor.
//
// ARGS:
//  const ExternalEASpace&  x               IN  source object to copy
//
// RETURNS:
//  (none)
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  An ExternalEASpace object is constructed which is a copy of x.
// 
// ERRORS:
//  (call error() to get the object's error status.)
//  error_Null_pointer
//  error_EA_Invalid_EA_type
//  error_No_free_store
// 
// NOTES:
//  If x is the same as this, nothing is done--ie., we don't copy to ourself.
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------

//----------------------------------------------------------------------
// METHOD: ExternalEASpace::operator=  --CJB
//  
//  Assignment operator.
//
// ARGS:
//  const ExternalEASpace&  x               IN  source object to copy
//
// RETURNS:
//  (none)
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  Assigns a copy of the source object into the specified object.
// 
// ERRORS:
//  (call error() to get the object's error status.)
//  error_Null_pointer
//  error_EA_Invalid_EA_type
//  error_No_free_store
// 
// NOTES:
//  If x is the same as this, nothing is done--ie., we don't assign to ourself.
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------

//----------------------------------------------------------------------
// METHOD: ExternalEASpace::at  --CJB
//  
//  Returns a const pointer to an EAViewItem by virtual index of the EASpace.
//
// ARGS:
//  INT16                   index           IN  virtual index into this EA space
//  Error&                  err             OUT error status
//
// RETURNS:
//  const EAViewItem* -- returns a pointer to the specified EA view item, or NULL
//  if there is a problem.
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  (none)
// 
// ERRORS:
//  error_Required_object_not_present
//  error_Index_out_of_bounds
// 
// NOTES:
//  IMPORTANT: This method expects a virtual index.
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------

//----------------------------------------------------------------------
// METHOD: ExternalEASpace::putIntoTrashList  --CJB
//  
//  Moves all extents from the source list into the trash list.  Checks for
//  the extents already existing in the trash list and does not insert duplicates,
//  although they are removed from the source list.
//
// ARGS:
//  LogExtentList&          sourceList      IN  extent list to put into the trash list
//  Error&                  err             OUT error status
//
// RETURNS:
//  (none)
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  All extents are removed from the source list, and moved to the trash list.
// 
// ERRORS:
//  error_No_free_store
//  error_Null_pointer;
// 
// NOTES:
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------

//----------------------------------------------------------------------
// METHOD: ExternalEASpace::deallocateCallersExtentList  --CJB
//  
//  Moves all extents from the caller's extent list into the trash list.
//
// ARGS:
//  Error&                  err             OUT error status
//
// RETURNS:
//  (none)
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  All extents are removed from the caler's extent list, and moved to the trash list.
// 
// ERRORS:
//  error_No_free_store
//  error_Null_pointer;
// 
// NOTES:
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------

//----------------------------------------------------------------------
// METHOD: ExternalEASpace::isA  --CJB
//  
//  Returns the enumerated type of this EA space.
//
// ARGS:
//  (none)
//
// RETURNS:
//  RWClassID -- returns the enumerated type (ExternalEASpaceType) of this EA space.
// 
// PRE-CONDITIONS:
//  (none)
// 
// POST-CONDITIONS:
//  (none)
// 
// ERRORS:
//  (none)
// 
// NOTES:
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------




#endif      /* ifdef _NSREATTR_ */
