#ifndef _NSRATTR_ //-*-c++-*-
#define _NSRATTR_

//----------------------------------------------------------------------
//  nsrAttr.h
//  This file implements the Attributes class, which is a robust 
//    user-level interface for accessing and manipulating the file
//    attributes (extracted from a FileEntry).
//
//      Unpublished Confidential Information of Hewlett-Packard
//      Company. Do not disclose.  Copyright (c) Hewlett-Packard
//      Company 1995. All rights reserved
// 
// The contents of this software are proprietary and confidential to
// the Hewlett- Packard Company, and are limited in distribution to
// those with a direct need to know.  Individuals having access to
// this software are responsible for maintaining the confidentiality
// of the content and for keeping the software secure when not in use.
// Transfer to any party is strictly forbidden other than as expressly
// permitted in writing by Hewlett-Packard Company.  Unauthorized
// transfer to or possession by any unauthorized party may be a
// criminal offense.
//
//                  RESTRICTED RIGHTS LEGEND
//
//      Use,  duplication,  or disclosure by the U. S. Government is
//      subject to restrictions as set forth in subparagraph (c) (1)
//      (ii) in the Rights in Technical Data and Computer Software
//      clause in DFARS 252.227-7013 or any other successor clause.
//
//                      HEWLETT-PACKARD COMPANY
//                      3000 Hanover St.
//                      Palo Alto, CA  94304 U.S.A.
//
//      Rights for non-DOD U.S. Government Departments and Agencies
//      are as set forth in FAR 52.227-19 (c) (1,2) or any other
//      successor clause.
//
//----------------------------------------------------------------------
// $Source: /projects/HMS/nsr/udfCore/descr/nsrAttr.h,v $
// $Revision: 1.23 $    $Author: hmgr $
// $State: Exp $        $Locker:  $
// $Date: 96/05/23 09:21:16 $
//

// The following constants are used as bit positions or bit masks in
//   manipulating individual bits for file permissions, file characteristics,
//   etc.

// Define the bit positions for each flag (used to generate masks below).
#define MiscSortedDirectoryBitPosition       ((UINT16)(0))
#define MiscNonRelocatableBitPosition        ((UINT16)(1))
#define MiscArchiveBitPosition               ((UINT16)(2))
#define MiscSetUidBitPosition                ((UINT16)(3))
#define MiscSetGidBitPosition                ((UINT16)(4))
#define MiscStickyBitPosition                ((UINT16)(5))
#define MiscContiguousBitPosition            ((UINT16)(6))
#define MiscSystemBitPosition                ((UINT16)(7))
#define MiscTransformedBitPosition           ((UINT16)(8))
#define MiscMultiVersionsBitPosition         ((UINT16)(9))

// Define masks for the various bits.
#define MiscSortedDirectoryBitMask            ((UINT16)(0x0001 << MiscSortedDirectoryBitPosition))
#define MiscNonRelocatableBitMask       ((UINT16)(0x0001 << MiscNonRelocatableBitPosition))
#define MiscArchiveBitMask              ((UINT16)(0x0001 << MiscArchiveBitPosition))
#define MiscSetUidBitMask               ((UINT16)(0x0001 << MiscSetUidBitPosition))
#define MiscSetGidBitMask               ((UINT16)(0x0001 << MiscSetGidBitPosition))
#define MiscStickyBitMask               ((UINT16)(0x0001 << MiscStickyBitPosition))
#define MiscContiguousBitMask           ((UINT16)(0x0001 << MiscContiguousBitPosition))
#define MiscSystemBitMask               ((UINT16)(0x0001 << MiscSystemBitPosition))
#define MiscTransformedBitMask          ((UINT16)(0x0001 << MiscTransformedBitPosition))
#define MiscMultiVersionsBitMask        ((UINT16)(0x0001 << MiscMultiVersionsBitPosition))

// The top 4 bits of the fileCharacteristics_ field can be used to
// pack the FileType (when returned from ICB_Tag).
#define AttrFileTypeMask            ((UINT16)(0xF000))
#define AttrFileTypeShiftNum        ((UINT16)(12))

// NOTE:  The following bit offsets are defined in the "/usr/include/sys/stat.h"
//   for the HP-UX 9.04 environment, but should be correct for all POSIX
//   environments.
// The following bit offsets refer to the Unix st_mode
//   data type, and are especially needed in Attributes.
#define UnixModeSetUidBitPosition       ((UINT16)(11))
#define UnixModeSetGidBitPosition       ((UINT16)(10))
#define UnixModeStickyBitPosition       ((UINT16)(9))

#define UnixModeUsrReadBitPosition      ((UINT16)(8))
#define UnixModeUsrWriteBitPosition     ((UINT16)(7))
#define UnixModeUsrExecuteBitPosition   ((UINT16)(6))
#define UnixModeGrpReadBitPosition      ((UINT16)(5))
#define UnixModeGrpWriteBitPosition     ((UINT16)(4))
#define UnixModeGrpExecuteBitPosition   ((UINT16)(3))
#define UnixModeOthReadBitPosition      ((UINT16)(2))
#define UnixModeOthWriteBitPosition     ((UINT16)(1))
#define UnixModeOthExecuteBitPosition   ((UINT16)(0))

#define UnixModeSetUidBitMask       ((UINT16)( 0x00000001 << UnixModeSetUidBitPosition))
#define UnixModeSetGidBitMask       ((UINT16)( 0x00000001 << UnixModeSetGidBitPosition))
#define UnixModeStickyBitMask       ((UINT16)( 0x00000001 << UnixModeStickyBitPosition))


// Bit positions for the permissions, used UINT16 to NSR.
#define PermOwnDeleteBitPosition  ((UINT16)(14))
#define PermOwnChattrBitPosition  ((UINT16)(13))
#define PermOwnReadBitPosition    ((UINT16)(12))
#define PermOwnWriteBitPosition   ((UINT16)(11))
#define PermOwnExecuteBitPosition ((UINT16)(10))

#define PermGrpDeleteBitPosition  ((UINT16)(9))
#define PermGrpChattrBitPosition  ((UINT16)(8))
#define PermGrpReadBitPosition    ((UINT16)(7))
#define PermGrpWriteBitPosition   ((UINT16)(6))
#define PermGrpExecuteBitPosition ((UINT16)(5))

#define PermOthDeleteBitPosition  ((UINT16)(4))
#define PermOthChattrBitPosition  ((UINT16)(3))
#define PermOthReadBitPosition    ((UINT16)(2))
#define PermOthWriteBitPosition   ((UINT16)(1))
#define PermOthExecuteBitPosition ((UINT16)(0))


// Masks for getting permission information out of FilePerms.
#define PermOwnDeleteBitMask  ((UINT16)(0x0001 << PermOwnDeleteBitPosition))
#define PermOwnChattrBitMask  ((UINT16)(0x0001 << PermOwnChattrBitPosition))
#define PermOwnReadBitMask    ((UINT16)(0x0001 << PermOwnReadBitPosition))
#define PermOwnWriteBitMask   ((UINT16)(0x0001 << PermOwnWriteBitPosition))
#define PermOwnExecuteBitMask ((UINT16)(0x0001 << PermOwnExecuteBitPosition))

#define PermGrpDeleteBitMask  ((UINT16)(0x0001 << PermGrpDeleteBitPosition))
#define PermGrpChattrBitMask  ((UINT16)(0x0001 << PermGrpChattrBitPosition))
#define PermGrpReadBitMask    ((UINT16)(0x0001 << PermGrpReadBitPosition))
#define PermGrpWriteBitMask   ((UINT16)(0x0001 << PermGrpWriteBitPosition))
#define PermGrpExecuteBitMask ((UINT16)(0x0001 << PermGrpExecuteBitPosition))

#define PermOthDeleteBitMask  ((UINT16)(0x0001 << PermOthDeleteBitPosition))
#define PermOthChattrBitMask  ((UINT16)(0x0001 << PermOthChattrBitPosition))
#define PermOthReadBitMask    ((UINT16)(0x0001 << PermOthReadBitPosition))
#define PermOthWriteBitMask   ((UINT16)(0x0001 << PermOthWriteBitPosition))
#define PermOthExecuteBitMask ((UINT16)(0x0001 << PermOthExecuteBitPosition))

// Maks 3 bits for the permissions for RWX for each category.
#define RightThreeBitsMask    ((UINT16)( 0x0007))
#define AttrUsrRWXBitsMask    ((UINT16)( (RightThreeBitsMask << PermOwnExecuteBitPosition)))
#define AttrGrpRWXBitsMask    ((UINT16)( (RightThreeBitsMask << PermGrpExecuteBitPosition)))
#define AttrOthRWXBitsMask    ((UINT16)( (RightThreeBitsMask << PermOthExecuteBitPosition)))


//----------------------------------------------------------------------
// CLASS: Attributes     --CSB
//
//    The Attributes class is a set of file attributes in a UDF-packed
//    manner, where the attributes are extracted from the FileEntry class.
//  
// PURPOSE:
//    The purpose of this class is to stand as the robust public interface
//    to the descriptor libraries.  On C++ platforms, the user should
//    interact with the stable interface member fucntions which provide
//    a high-level of robust capability in manipulating file attribute
//    information.  (These functions should be complete and provide all
//    manner of information access that is relevant to the user).
//
// IMPLICATIONS:  
//    The Attributes class is the stable, formalized interface to the
//    FileEntry class and the rest of the Descriptor hierarchy.  Users must
//    set the values in the Attributes class for later transfer to a FileEntry.
//
// PLATFORM (C OR C++):
//    This Attributes class is implemented as a "struct" with conditional
//    pre-processor directives (#ifdef __CPLUSPLUS) to detect a C++
//    compiler (the _CPLUSPLUS directive is automatically set by C++
//    compilers).
//
//    No members to this class are virtual, and this class does not derive
//    from any parent class.  Once one member becomes "virtual", a 4-byte
//    vptr will become a member of this class and the offsets will NOT
//    be the same in C and C++ (this would cause run-time memory access
//    violations, leading to segmentation fault/core dump.)
//
//    On a C platform, the class behaves as a struct with public data
//    members, and no member functions (to facilitate an easy interface
//    with C developers).  On C++ platforms, however, the struct will
//    will make the data members private, and the user must interface
//    with the many member functions for formal (simplified) interface
//    access to individual bits and other data inside the Attributes class.
//
//    If the user is interacting with this class on a C platform, the user
//    MUST take care that all logical bit positions are respected and set
//    with logical correctness.  The actual bits are specified by the UDF
//    standard and arbitrarily assigned bit locations within this class
//    using the const UINT16 masks at the top of this file.
//
// COLLABORATORS:  
//    FileEntry  -- source and destination for data in this Attributes class.
//
// IMPLEMENTATION:
//    The user needs to only be aware of the public member functions of
//    the Attributes class.  However, for the academically curious, the
//    Attributes class implements two private class types that are logical
//    containers of file attribute information (the user is not able to 
//    instantiate, access, or otherwise interact with these types).
//
//    The private member class PackedTAC is a logical container of the FileType 
//    and other file characteristics.  The file type is an enumerated value packed
//    into the high 4 bits of a UINT16, and the other characteristics are
//    packed into the low order 10 bits of the same UINT16.
//
//    The private member class FilePermisions is a logical container of the
//    Delete, Chattr, Read, Write, Execute bits for owner, group, and other
//    (15 bits).  The high-order bit of the UINT16 is not used.
//
//    The Attributes class implements a very thin interface (member functions)
//    that merely call the member functions for PackedTAC and FilePermissions
//    where possible.
//
// PUBLIC METHODS:
//    Some (major) member functions for the Attributes class are described
//    below:
//    
//    **general**
//
//      toFileEntry()
//      void toFileEntry(FileEntry& fileEntry);
//        Sends all state information from the Attributes class to the FileEntry
//        passed in.  
//        ***note***:  The Attributes class may be modified in this process.  On every
//        toFileEntry() call, the attributes class automatically sets the
//        following bits to False to ensure *osta* compliance:  sortedDirectoryBit,
//        nonRelocatableBit, contiguousBit, transformedBit, and multiVersionsBit.
//        Also, all attributes *except* FileType and accessTime, modificationTime,
//        and attributesTime are set to zero on this write if the Attributes is a
//        ExtendedAttributes (the other data fields do not apply).
//
//      fromFileEntry()
//      void fromFileEntry(FileEntry& fileEntry);
//        Populates all values in this Attributes class from the FileEntry object
//        passed in, which is not modified.
//        from the FileEntry and Attributes class.
//
//      linkCount()
//      UINT32 linkCount(void) const;
//        This function returns the number of links to this file.  NOTE:  All files
//        have ONE link by default for the ".." entry, not two as in UNIX for the
//        ".." and "." entries.  However, the ExtendedAttributes type of Attributes
//        will always be forced to zero links on a toFileEntry() call.  Each platform 
//        is free to set up additional links to the file, as long as the file linkCount 
//        is appropriately updated.
//        
//      uid()
//      gid()
//      accessTime()
//      modificationTime()
//      attributeTime()
//
//      operator==()
//      Boolean operator!=(const Attributes& attributes) const;
//        These functions will compare two instances of an Attributes class together.
//        If each Attributes class has the same state as the other for all bits, the
//        logical "True" or "False" value is returned.
//
//      fileType()
//      void fileType(FileType newType);
//      FileType fileType(void) const;
//        This functions set and get an enumerated value that defines the type of
//        Attributes class stored.  While the user may directly set an invalid
//        type, the value "file_InvalidType" is returned if the file type is not
//        a discretely allowed type.
//
//    **unix-specific**:
//     
//      unixMode()
//      void   unixMode(UINT16 newMode);
//      UINT16 unixMode(void) const;
//        These functions allow the user to set parts of the Attributes state with a
//        POSIX compliant stat_t type.  This is a UINT16 with RWX bits for owner,
//        group, and other defined by POSIX compliant operating systems.  In addition,
//        bits are present for setuid, setgid, and sticky.
//
//      usrRWXBits()
//      UINT16 usrRWXBits(void) const;
//      grpRWXBits()
//      UINT16 grpRWXBits(void) const;
//      othRWXBits()
//      UINT16 othRWXBits(void) const;
//      usrRWXBits()
//      void usrRWXBits(UINT16 newBits);
//      grpRWXBits()
//      void grpRWXBits(UINT16 newBits);
//      othRWXBits()
//      void othRWXBits(UINT16 newBits);
//        These functions give access to the RWX bits for each usr, grp, or oth.
//        NOTE:  although a UINT16 is the parameter, only the RIGHTMOST (low order)
//        three bits are used to set and retrieve the RWX bits.  All other bits are
//        silently ignored.
//
//    **other**
//      Many other member functions exist to set and get values for one
//      logical bit of permissions, file characteristics, etc. at a time.
//----------------------------------------------------------------------
class Attributes 
{
  // NOTE:  The two classes "Permissions" and "PackedTAC" are private member
  //   classes to this Attributes class.  No outside entity needs to access
  //   these classes:  they are merely logical abstract entities for Attributes
  //   to manage internal bits for file permissions and file characteristics,
  //   respectively.

  // NOTE:  the "fileCharacteristics_" data member is instantiated in the
  //   PackedTAC definition, and the "filePermissions_" data member is
  //   instantiated in the Permissions definition.  This is because the C
  //   language does not allow a structure definition to be nested in
  //   another structure, unless an object is instantiated (and this header
  //   may be compiled by a C compiler).

//----------------------------------------------------------------------
// Class: PackedTAC     --CSB
// NOTE:  THIS CLASS IS A PRIVATE MEMBER TYPE OF CLASS ATTRIBUTES.
//  This class is an abstract collection of bits and logic to store (in
//    a packed format) the FileType and the file attributes.  The bottom
//    ten bits are attributes, and the top 4 bits store the FileType.
//
// COLLABORATORS:  
//  This is a private class member of Attributes (the sole user).
//----------------------------------------------------------------------
// NOTES:
//  No members to this class are virtual, and this class does not derive
//  from any parent class.  Once one member becomes "virtual", a 4-byte
//  vptr will become a member of this class and the offsets will NOT
//  be the same in C and C++ (this would cause run-time memory access
//  violations, leading to segmentation fault/core dump.)
//----------------------------------------------------------------------
class PackedTAC
{
    // The member "tac_" is the "type and characteristics" for a FileEntry.
    //   The lower 10 bits are used for specific file characteristics, and
    //   the upper 4 bits are used for the FileType enumeration.  
    UINT16 tac_;

#ifdef __cplusplus

  public:
    PackedTAC(UINT16 newTac = 0) { tac_ = newTac; }
    ~PackedTAC(void) {}

    // INLINE: PackedTAC::operator==()
    Boolean operator==(const PackedTAC otherTac) const{return (tac_==otherTac.tac_)?True:False;}

    // RECALL:  The FileType enumeration has values ranging from 0-12.
    // Because these values can be stored in 4 bits, the high
    //   4 bits of the fileCharacteristics_ field is set aside for it
    //   (becuase those bits were not being used).
    FileType fileType(void) const
    {
      switch ((UINT16)((UINT16)tac_ >> (UINT16)AttrFileTypeShiftNum) & 
        ((UINT16)AttrFileTypeMask >> (UINT16)AttrFileTypeShiftNum))
      {  case file_Unspecified:
           return file_Unspecified;
         case file_Directory:
           return file_Directory;
         case file_Raw:
           return file_Raw;
         case file_SpecialBlockDevice:
           return file_SpecialBlockDevice;
         case file_SpecialCharacterDevice:
           return file_SpecialCharacterDevice;
         case file_ExtendedAttributes:
           return file_ExtendedAttributes;
         case file_Fifo:
           return file_Fifo;
         case file_Sock:
           return file_Sock;
         case file_SymbolicLink:
           return file_SymbolicLink;
         default: // If we reach here, this is an invalid file type.
           return file_InvalidFile;
      }
    }

    void fileType(FileType newFileType) 
      { tac_ &= ~AttrFileTypeMask;   
        tac_ |= (((UINT16)newFileType << AttrFileTypeShiftNum) & AttrFileTypeMask);}

    // DVM--I did not do "operator=()" and "operator UINT16()" because those two
    //   operations must implicitly strip off the FileType, leaving only the
    //   characteristics to do what we wanted.  In case the maintainer does not
    //   realize this, I decided to just make two "characterisics()" functions
    //   so it is obvious that the FileType is stripped off.  --CSB 9-13-95.
    UINT16 characteristics(void) const{return (tac_ & (~AttrFileTypeMask));}
    void   characteristics(UINT16 newCharacteristics){
      tac_ &= (AttrFileTypeMask);  tac_ |= (newCharacteristics & (~AttrFileTypeMask));}

    // Return the following bits.
    Boolean sortedDirectoryBit     (void)const {return (tac_ & MiscSortedDirectoryBitMask)? True:False;}
    Boolean nonRelocatableBit(void)const {return (tac_ & MiscNonRelocatableBitMask)? True:False;}
    Boolean archiveBit       (void)const {return (tac_ & MiscArchiveBitMask)? True:False;}
    Boolean setUidBit        (void)const {return (tac_ & MiscSetUidBitMask)? True:False;}
    Boolean setGidBit        (void)const {return (tac_ & MiscSetGidBitMask)? True:False;}
    Boolean stickyBit        (void)const {return (tac_ & MiscStickyBitMask)? True:False;}
    Boolean contiguousBit    (void)const {return (tac_ & MiscContiguousBitMask)? True:False;}
    Boolean systemBit        (void)const {return (tac_ & MiscSystemBitMask)? True:False;}
    Boolean transformedBit   (void)const {return (tac_ & MiscTransformedBitMask)? True:False;}
    Boolean multiVersionsBit (void)const {return (tac_ & MiscMultiVersionsBitMask)? True:False;}

    // Set the following bits.
    void sortedDirectoryBit         (Boolean newBit)
      { tac_ &= ~MiscSortedDirectoryBitMask; tac_ |= newBit << MiscSortedDirectoryBitPosition; }
    void nonRelocatableBit    (Boolean newBit)
      { tac_ &= ~MiscNonRelocatableBitMask; tac_ |= newBit << MiscNonRelocatableBitPosition; }
    void archiveBit           (Boolean newBit)
      { tac_ &= ~MiscArchiveBitMask; tac_ |= newBit << MiscArchiveBitPosition; }
    void setUidBit            (Boolean newBit)
      { tac_ &= ~MiscSetUidBitMask; tac_ |= newBit << MiscSetUidBitPosition; }
    void setGidBit            (Boolean newBit)
      { tac_ &= ~MiscSetGidBitMask; tac_ |= newBit << MiscSetGidBitPosition; }
    void stickyBit            (Boolean newBit)
      { tac_ &= ~MiscStickyBitMask; tac_ |= newBit << MiscStickyBitPosition; }
    void contiguousBit        (Boolean newBit)
      { tac_ &= ~MiscContiguousBitMask; tac_ |= newBit << MiscContiguousBitPosition; }
    void systemBit            (Boolean newBit)
      { tac_ &= ~MiscSystemBitMask; tac_ |= newBit << MiscSystemBitPosition; }
    void transformedBit       (Boolean newBit)
      { tac_ &= ~MiscTransformedBitMask; tac_ |= newBit << MiscTransformedBitPosition; }
    void multiVersionsBit     (Boolean newBit)
      { tac_ &= ~MiscMultiVersionsBitMask; tac_ |= newBit << MiscMultiVersionsBitPosition; }

    // Append file char characters to a string ref.  User assumes cstring init, and
    // null termination.
    Boolean setFileCharacteristics(const RWCString& cstr)
    {
        //printf ("setFileCharacteristics: %s\n", (CONST_CHAR_PTR)cstr);
        
        // Validate the incomming cstring.
        if (cstr[6] != 'D' && cstr[6] != '-' ||
            cstr[7] != 'N' && cstr[7] != '-' ||
            cstr[8] != 'A' && cstr[8] != '-' ||
            cstr[9] != 'U' && cstr[9] != '-' ||
            cstr[10] != 'G' && cstr[10] != '-' ||
            cstr[11] != 'K' && cstr[11] != '-' ||
            cstr[12] != 'C' && cstr[12] != '-' ||
            cstr[13] != 'S' && cstr[13] != '-' ||
            cstr[14] != 'T' && cstr[14] != '-' ||
            cstr[15] != 'M' && cstr[15] != '-')
        {
            return False;
        }

        // convert filetype bits to the enum filetype.
        UINT16 fileTypeInt;
        fileTypeInt  = (cstr[0] == '1')? 8:0;
        fileTypeInt += (cstr[1] == '1')? 4:0;
        fileTypeInt += (cstr[2] == '1')? 2:0;
        fileTypeInt += (cstr[3] == '1')? 1:0;
        
        fileType((FileType) fileTypeInt);
     
                 
        // chars 4 and 5 are merely placeholders.
        sortedDirectoryBit ((NSR::Boolean) (cstr[6]  == 'D'));
        nonRelocatableBit  ((NSR::Boolean) (cstr[7]  == 'N'));
      
        archiveBit         ((NSR::Boolean) (cstr[8]  == 'A'));
               
        setUidBit          ((NSR::Boolean) (cstr[9]  == 'U'));
        setGidBit          ((NSR::Boolean) (cstr[10] == 'G'));
        stickyBit          ((NSR::Boolean) (cstr[11] == 'K'));
      
        contiguousBit      ((NSR::Boolean) (cstr[12] == 'C'));
        systemBit          ((NSR::Boolean) (cstr[13] == 'S'));
        transformedBit     ((NSR::Boolean) (cstr[14] == 'T'));
      
        multiVersionsBit   ((NSR::Boolean) (cstr[15] == 'M'));

        return True;
    }
    
    CONST_CHAR_PTR appendFileCharacteristics(RWCString& cstr) const
    { 
      // Append filetype enum, as 4 bits (redundant with file type).
      cstr += (tac_ & 0x8000) ? "1":"-";
      cstr += (tac_ & 0x4000) ? "1":"-";
      cstr += (tac_ & 0x2000) ? "1":"-";
      cstr += (tac_ & 0x1000) ? "1":"-";
      
      // next two bits are not currently used.
      cstr += ".";
      cstr += ".";

      // The remaining bits are self-documenting.
      cstr += (sortedDirectoryBit() == True) ?"D":"-";
      cstr += (nonRelocatableBit() == True) ?"N":"-";
      cstr += (archiveBit() == True) ?"A":"-";

      cstr += (setUidBit() == True) ?"U":"-";
      cstr += (setGidBit() == True) ?"G":"-";
      cstr += (stickyBit() == True) ?"K":"-";

      cstr += (contiguousBit() == True) ?"C":"-";
      cstr += (systemBit() == True) ?"S":"-";
      cstr += (transformedBit() == True) ?"T":"-";

      cstr += (multiVersionsBit() == True) ?"M":"-";

      return (CONST_CHAR_PTR) cstr;
    }

#endif // __cplusplus.

// NOTE:  Because this file may be compiled with a C compiler (and these classes
//   become structures), WE MUST INSTANTIATE OUR OBJECT IN THE STRUCT DEFINITION.
//   This is because the C language does not allow structures to be defined nested
//   in other structures unless the nested structure instantiates an object.
} fileCharacteristics_;  

//----------------------------------------------------------------------
// Class: Permissions     --CSB
// NOTE:  THIS CLASS IS A PRIVATE MEMBER TYPE OF CLASS ATTRIBUTES.
//  This class is an abstract collection of bits and logic to store 
//    the fifteen permissions bits for the UDF standard.
//
// COLLABORATORS:  
//  This is a private class member of Attributes (the sole user).
//----------------------------------------------------------------------
// NOTES:
//  No members to this class are virtual, and this class does not derive
//  from any parent class.  Once one member becomes "virtual", a 4-byte
//  vptr will become a member of this class and the offsets will NOT
//  be the same in C and C++ (this would cause run-time memory access
//  violations, leading to segmentation fault/core dump.)
//----------------------------------------------------------------------
class Permissions
{
    UINT16 permissions_;

#ifdef __cplusplus

  public:
    Permissions(UINT16 newPermissions=0) { permissions_ = newPermissions; }
    ~Permissions(void) {}

    Boolean operator==(const Permissions otherPerms) const{return (permissions_==otherPerms.permissions_)?True:False;}

    UINT16 getAllPermissions(void) const{return permissions_;}
    void setAllPermissions(UINT16 newPerms){permissions_ = newPerms;}

    // Return RWX for each of the three catagories Usr, Grp, Oth.
    UINT16 usrRWXBits(void) const { return ((permissions_ >> PermOwnExecuteBitPosition) & RightThreeBitsMask);}
    UINT16 grpRWXBits(void) const { return ((permissions_ >> PermGrpExecuteBitPosition) & RightThreeBitsMask);}
    UINT16 othRWXBits(void) const { return ((permissions_ >> PermOthExecuteBitPosition) & RightThreeBitsMask);}

    // Set the RWX for each of the three catagories Usr, Grp, Oth.
    void usrRWXBits(UINT16 newBits)
      { 
        permissions_ &=  ~AttrUsrRWXBitsMask;
        permissions_ |= newBits << PermOwnExecuteBitPosition; 
      }
    void grpRWXBits(UINT16 newBits)
      { 
        permissions_ &=  ~AttrGrpRWXBitsMask;
        permissions_ |= newBits << PermGrpExecuteBitPosition; 
        }
    void othRWXBits(UINT16 newBits)
      { 
        permissions_ &=  ~AttrOthRWXBitsMask;
        permissions_ |= newBits << PermOthExecuteBitPosition; 
        }

    // The following functions return a Boolean for whether this bit is set or not.
    // Return the following bits.
    Boolean permOthDelete      (void) const
      { return ((permissions_ & PermOthDeleteBitMask) ? True : False); }
    Boolean permOthChattr      (void) const
      { return ((permissions_ & PermOthChattrBitMask) ? True : False); }
    Boolean permOthRead      (void) const
      { return ((permissions_ & PermOthReadBitMask) ? True : False); }
    Boolean permOthWrite      (void) const
      { return ((permissions_ & PermOthWriteBitMask) ? True : False); }
    Boolean permOthExecute      (void) const
      { return ((permissions_ & PermOthExecuteBitMask) ? True : False); }

    Boolean permGrpDelete      (void) const
      { return ((permissions_ & PermGrpDeleteBitMask) ? True : False); }
    Boolean permGrpChattr      (void) const
      { return ((permissions_ & PermGrpChattrBitMask) ? True : False); }
    Boolean permGrpRead      (void) const
      { return ((permissions_ & PermGrpReadBitMask) ? True : False); }
    Boolean permGrpWrite      (void) const
      { return ((permissions_ & PermGrpWriteBitMask) ? True : False); }
    Boolean permGrpExecute      (void) const
      { return ((permissions_ & PermGrpExecuteBitMask) ? True : False); }

    Boolean permOwnDelete      (void) const
      { return ((permissions_ & PermOwnDeleteBitMask) ? True : False); }
    Boolean permOwnChattr      (void) const
      { return ((permissions_ & PermOwnChattrBitMask) ? True : False); }
    Boolean permOwnRead      (void) const
      { return ((permissions_ & PermOwnReadBitMask) ? True : False); }
    Boolean permOwnWrite      (void) const
      { return ((permissions_ & PermOwnWriteBitMask) ? True : False); }
    Boolean permOwnExecute      (void) const
      { return ((permissions_ & PermOwnExecuteBitMask) ? True : False); }

    // The following functions set the bit based on the Boolean passed in.
    void permOthDelete         (Boolean newBit)
      { permissions_ &=  ~PermOthDeleteBitMask;
        permissions_ |= newBit << PermOthDeleteBitPosition; }
    void permOthChattr         (Boolean newBit)
      { permissions_ &=  ~PermOthChattrBitMask;
        permissions_ |= newBit << PermOthChattrBitPosition; }
    void permOthRead         (Boolean newBit)
      { permissions_ &=  ~PermOthReadBitMask;
        permissions_ |= newBit << PermOthReadBitPosition; }
    void permOthWrite         (Boolean newBit)
      { permissions_ &=  ~PermOthWriteBitMask;
        permissions_ |= newBit << PermOthWriteBitPosition; }
    void permOthExecute         (Boolean newBit)
      { permissions_ &=  ~PermOthExecuteBitMask;
        permissions_ |= newBit << PermOthExecuteBitPosition; }

    void permGrpDelete         (Boolean newBit)
      { permissions_ &=  ~PermGrpDeleteBitMask;
        permissions_ |= newBit << PermGrpDeleteBitPosition; }
    void permGrpChattr         (Boolean newBit)
      { permissions_ &=  ~PermGrpChattrBitMask;
        permissions_ |= newBit << PermGrpChattrBitPosition; }
    void permGrpRead         (Boolean newBit)
      { permissions_ &=  ~PermGrpReadBitMask;
        permissions_ |= newBit << PermGrpReadBitPosition; }
    void permGrpWrite         (Boolean newBit)
      { permissions_ &=  ~PermGrpWriteBitMask;
        permissions_ |= newBit << PermGrpWriteBitPosition; }
    void permGrpExecute         (Boolean newBit)
      { permissions_ &=  ~PermGrpExecuteBitMask;
        permissions_ |= newBit << PermGrpExecuteBitPosition; }

    void permOwnDelete         (Boolean newBit)
      { permissions_ &=  ~PermOwnDeleteBitMask;
        permissions_ |= newBit << PermOwnDeleteBitPosition; }
    void permOwnChattr         (Boolean newBit)
      { permissions_ &=  ~PermOwnChattrBitMask;
        permissions_ |= newBit << PermOwnChattrBitPosition; }
    void permOwnRead         (Boolean newBit)
      { permissions_ &=  ~PermOwnReadBitMask;
        permissions_ |= newBit << PermOwnReadBitPosition; }
    void permOwnWrite         (Boolean newBit)
      { permissions_ &=  ~PermOwnWriteBitMask;
        permissions_ |= newBit << PermOwnWriteBitPosition; }
    void permOwnExecute         (Boolean newBit)
      { permissions_ &=  ~PermOwnExecuteBitMask;
        permissions_ |= newBit << PermOwnExecuteBitPosition; }

    Boolean setAllPermissions(const RWCString& cstr)
    {
        //printf ("setAllPermissions: %s\n", (CONST_CHAR_PTR)cstr);
        
        // Validate permissions string.
        if ( cstr[0] != '-' ||
            (cstr[1] != 'D' && cstr[1] != '-') ||
            (cstr[2] != 'C' && cstr[2] != '-') ||
            (cstr[3] != 'R' && cstr[3] != '-') ||
            (cstr[4] != 'W' && cstr[4] != '-') ||
            (cstr[5] != 'X' && cstr[5] != '-') ||
            
            (cstr[6] != 'D' && cstr[6] != '-') ||
            (cstr[7] != 'C' && cstr[7] != '-') ||
            (cstr[8] != 'R' && cstr[8] != '-') ||
            (cstr[9] != 'W' && cstr[9] != '-') ||
            (cstr[10] != 'X' && cstr[10] != '-') ||
            
            (cstr[11] != 'D' && cstr[11] != '-') ||
            (cstr[12] != 'C' && cstr[12] != '-') ||
            (cstr[13] != 'R' && cstr[13] != '-') ||
            (cstr[14] != 'W' && cstr[14] != '-') ||
            (cstr[15] != 'X' && cstr[15] != '-') )
        {
            return False;
        }
        
        permOwnDelete  ((NSR::Boolean) (cstr[1]  == 'D'));
        permOwnChattr  ((NSR::Boolean) (cstr[2]  == 'C'));
        permOwnRead    ((NSR::Boolean) (cstr[3]  == 'R'));
        permOwnWrite   ((NSR::Boolean) (cstr[4]  == 'W'));
        permOwnExecute ((NSR::Boolean) (cstr[5]  == 'X'));
        
        permGrpDelete  ((NSR::Boolean) (cstr[6]  == 'D'));
        permGrpChattr  ((NSR::Boolean) (cstr[7]  == 'C'));
        permGrpRead    ((NSR::Boolean) (cstr[8]  == 'R'));
        permGrpWrite   ((NSR::Boolean) (cstr[9]  == 'W'));
        permGrpExecute ((NSR::Boolean) (cstr[10] == 'X'));
                                          
        permOthDelete  ((NSR::Boolean) (cstr[11] == 'D'));
        permOthChattr  ((NSR::Boolean) (cstr[12] == 'C'));
        permOthRead    ((NSR::Boolean) (cstr[13] == 'R'));
        permOthWrite   ((NSR::Boolean) (cstr[14] == 'W'));
        permOthExecute ((NSR::Boolean) (cstr[15] == 'X'));

        return True;
   }
    
    CONST_CHAR_PTR appendAllPermissions(RWCString& cstr)  const
    {
      cstr += "-";
      cstr += (permOwnDelete() == True)?"D":"-";
      cstr += (permOwnChattr() == True)?"C":"-";
      cstr += (permOwnRead() == True)?"R":"-";
      cstr += (permOwnWrite() == True)?"W":"-";
      cstr += (permOwnExecute() == True)?"X":"-";
          
      cstr += (permGrpDelete() == True)?"D":"-";
      cstr += (permGrpChattr() == True)?"C":"-";
      cstr += (permGrpRead() == True)?"R":"-";
      cstr += (permGrpWrite() == True)?"W":"-";
      cstr += (permGrpExecute() == True)?"X":"-";
          
      cstr += (permOthDelete() == True)?"D":"-";
      cstr += (permOthChattr() == True)?"C":"-";
      cstr += (permOthRead() == True)?"R":"-";
      cstr += (permOthWrite() == True)?"W":"-";
      cstr += (permOthExecute() == True)?"X":"-";

      return (CONST_CHAR_PTR) cstr;
    }

#endif // __cplusplus.

// NOTE:  Because this file may be compiled with a C compiler (and these classes
//   become structures), WE MUST INSTANTIATE OUR OBJECT IN THE STRUCT DEFINITION.
//   This is because the C language does not allow structures to be defined nested
//   in other structures unless the nested structure instantiates an object.
} filePermissions_;

    UINT32   uid_;
    UINT32   gid_;
    time_t   accessTime_;
    time_t   modificationTime_;
    time_t   attributeTime_;
  
    // NOTE:  "linkCount_" stores the TOTAL number of links to this
    //   file.  All files have a minimum of ONE link, except Extended
    //   attributes which have ZERO links (Extended Attributes are not
    //   visible by a directory, and thus cannot have links).  Any 
    //   NON-Extended Attribute file can have additional links added
    //   by platform-specific features.
    UINT16   linkCount_;
  

// Make this look like a "struct" in C, and a "class" in C++:
#ifdef __cplusplus 

  public:
    Attributes(void);
    ~Attributes(void);

    void clear(void) {
      // Instantiate another Attributes class, which gets the default
      //   values, and assign it to ourselves.
      Attributes other;
      // NOTE: This operation ASSUMES an Attributes::operator=(Attributes)
      //   exists.  We did not write one, but the default one provided
      //   is adequate because no members of this Attributes class are
      //   pointers (a member-wise assignment by the compiler supplied
      //   operator=() is acceptable).
      *this = other;
    }

    UINT32 uid(void) const { return uid_; }
    void   uid(UINT32 newUid) { uid_ = newUid; }

    UINT32 gid(void) const { return gid_; }
    void   gid(UINT32 newGid) { gid_ = newGid; }

    time_t accessTime(void) const { return accessTime_; }
    void   accessTime(time_t newTime) { accessTime_ = newTime; }
    time_t modificationTime(void) const { return modificationTime_; }
    void   modificationTime(time_t newTime) { modificationTime_ = newTime; }
    time_t attributeTime(void) const { return attributeTime_; }
    void   attributeTime(time_t newTime) { attributeTime_ = newTime; }

    UINT32 linkCount(void) const { return linkCount_; }
    void   linkCount(UINT16 newNum) { linkCount_ = newNum; }

    void toFileEntry(FileEntry& fileEntry) ;
    void fromFileEntry(FileEntry& fileEntry);

    void   unixMode(UINT16 newMode);
    UINT16 unixMode(void) const;

    UINT16 usrRWXBits(void) const { return filePermissions_.usrRWXBits();}
    UINT16 grpRWXBits(void) const { return filePermissions_.grpRWXBits();}
    UINT16 othRWXBits(void) const { return filePermissions_.othRWXBits();}
    void usrRWXBits(UINT16 newBits) { filePermissions_.usrRWXBits(newBits); }
    void grpRWXBits(UINT16 newBits) { filePermissions_.grpRWXBits(newBits); }
    void othRWXBits(UINT16 newBits) { filePermissions_.othRWXBits(newBits); }

    Boolean operator==(const Attributes& attributes) const;
    Boolean operator!=(const Attributes& attributes) const;

    // RECALL:  When getting the type, we force any "bad" types to the
    //   file_InvalidFile return value.
    FileType fileType(void) const 
      {return fileCharacteristics_.fileType(); }
    // RECALL:  When setting the type, any type is acceptable.
    void fileType(FileType newType) {fileCharacteristics_.fileType(newType);}

    // Return the following bits.
    Boolean sortedDirectoryBit     (void)const {return fileCharacteristics_.sortedDirectoryBit();}
    Boolean nonRelocatableBit(void)const {return fileCharacteristics_.nonRelocatableBit();}
    Boolean archiveBit       (void)const {return fileCharacteristics_.archiveBit();}
    Boolean setUidBit        (void)const {return fileCharacteristics_.setUidBit();}
    Boolean setGidBit        (void)const {return fileCharacteristics_.setGidBit();}
    Boolean stickyBit        (void)const {return fileCharacteristics_.stickyBit();}
    Boolean contiguousBit    (void)const {return fileCharacteristics_.contiguousBit();}
    Boolean systemBit        (void)const {return fileCharacteristics_.systemBit();}
    Boolean transformedBit   (void)const {return fileCharacteristics_.transformedBit();}
    Boolean multiVersionsBit (void)const {return fileCharacteristics_.multiVersionsBit();}

    // Set the following bits.
    void sortedDirectoryBit     (Boolean newBit){fileCharacteristics_.sortedDirectoryBit(newBit); }
    void nonRelocatableBit(Boolean newBit){fileCharacteristics_.nonRelocatableBit(newBit); }
    void archiveBit       (Boolean newBit){fileCharacteristics_.archiveBit(newBit); }
    void setUidBit        (Boolean newBit){fileCharacteristics_.setUidBit(newBit); }
    void setGidBit        (Boolean newBit){fileCharacteristics_.setGidBit(newBit); }
    void stickyBit        (Boolean newBit){fileCharacteristics_.stickyBit(newBit); }
    void contiguousBit    (Boolean newBit){fileCharacteristics_.contiguousBit(newBit); }
    void systemBit        (Boolean newBit){fileCharacteristics_.systemBit(newBit); }
    void transformedBit   (Boolean newBit){fileCharacteristics_.transformedBit(newBit); }
    void multiVersionsBit (Boolean newBit){fileCharacteristics_.multiVersionsBit(newBit); }

    // PERMISSIONS BITS.
    // The following functions return a Boolean for whether this bit is set or not.
    // Return the following bits.
    Boolean permOthDeleteBit   (void) const { return filePermissions_.permOthDelete(); }
    Boolean permOthChattrBit   (void) const { return filePermissions_.permOthChattr(); }
    Boolean permOthReadBit     (void) const { return filePermissions_.permOthRead(); }
    Boolean permOthWriteBit    (void) const { return filePermissions_.permOthWrite(); }
    Boolean permOthExecuteBit  (void) const { return filePermissions_.permOthExecute(); }

    Boolean permGrpDeleteBit   (void) const { return filePermissions_.permGrpDelete(); }
    Boolean permGrpChattrBit   (void) const { return filePermissions_.permGrpChattr(); }
    Boolean permGrpReadBit     (void) const { return filePermissions_.permGrpRead(); }
    Boolean permGrpWriteBit    (void) const { return filePermissions_.permGrpWrite(); }
    Boolean permGrpExecuteBit  (void) const { return filePermissions_.permGrpExecute(); }

    Boolean permOwnDeleteBit   (void) const { return filePermissions_.permOwnDelete(); }
    Boolean permOwnChattrBit   (void) const { return filePermissions_.permOwnChattr(); }
    Boolean permOwnReadBit     (void) const { return filePermissions_.permOwnRead(); }
    Boolean permOwnWriteBit    (void) const { return filePermissions_.permOwnWrite(); }
    Boolean permOwnExecuteBit  (void) const { return filePermissions_.permOwnExecute(); }

    // The following functions set the bit based on the Boolean passed in.
    void permOthDeleteBit  (Boolean newBit) { filePermissions_.permOthDelete(newBit); }
    void permOthChattrBit  (Boolean newBit) { filePermissions_.permOthChattr(newBit); }
    void permOthReadBit    (Boolean newBit) { filePermissions_.permOthRead(newBit); }
    void permOthWriteBit   (Boolean newBit) { filePermissions_.permOthWrite(newBit); }
    void permOthExecuteBit (Boolean newBit) { filePermissions_.permOthExecute(newBit); }
    void permGrpDeleteBit  (Boolean newBit) { filePermissions_.permGrpDelete(newBit); }
    void permGrpChattrBit  (Boolean newBit) { filePermissions_.permGrpChattr(newBit); }
    void permGrpReadBit    (Boolean newBit) { filePermissions_.permGrpRead(newBit); }
    void permGrpWriteBit   (Boolean newBit) { filePermissions_.permGrpWrite(newBit); }
    void permGrpExecuteBit (Boolean newBit) { filePermissions_.permGrpExecute(newBit); }
    void permOwnDeleteBit  (Boolean newBit) { filePermissions_.permOwnDelete(newBit); }
    void permOwnChattrBit  (Boolean newBit) { filePermissions_.permOwnChattr(newBit); }
    void permOwnReadBit    (Boolean newBit) { filePermissions_.permOwnRead(newBit); }
    void permOwnWriteBit   (Boolean newBit) { filePermissions_.permOwnWrite(newBit); }
    void permOwnExecuteBit (Boolean newBit) { filePermissions_.permOwnExecute(newBit); }

    Boolean setOtherInfo(const RWCString& cstr)
    {
        //printf ("setOtherInfo: %s\n", (CONST_CHAR_PTR)cstr);
        
        UINT32   newUid;
        UINT32   newGid;
        time_t   newAccessTime;
        time_t   newModificationTime;
        time_t   newAttributeTime;
        UINT16   newLinkCount;

        RWCTokenizer nextToken(cstr);
        RWCString token;

        token = nextToken(); // uid label
        token = nextToken(); // uid value
        newUid = strtoul((CONST_CHAR_PTR)token, NULL, 0);
        uid(newUid);

        token = nextToken(); // gid label
        token = nextToken(); // gid label
        newGid = strtoul((CONST_CHAR_PTR)token, NULL, 0);
        gid(newGid);

        token = nextToken(); // times label
        token = nextToken(); // access time
        newAccessTime = strtoul((CONST_CHAR_PTR)token, NULL, 0);
        accessTime(newAccessTime);
        
        token = nextToken(); // modification time
        newModificationTime = strtoul((CONST_CHAR_PTR)token, NULL, 0);
        modificationTime(newModificationTime);

        token = nextToken(); // attribute time
        newAttributeTime = strtoul((CONST_CHAR_PTR)token, NULL, 0);
        attributeTime(newAttributeTime);

        token = nextToken(); // links label
        token = nextToken(); // links value
        newLinkCount = atoi((CONST_CHAR_PTR)token);
        linkCount(newLinkCount);

        return True;
    }

    CONST_CHAR_PTR appendOtherInfo(RWCString& cstr) const ;

    CONST_CHAR_PTR appendUnixMode(RWCString& cstr) const
    { 
        cstr += (stickyBit() == True)?"S":"-";
        cstr += (setUidBit() == True)?"U":"-";
        cstr += (setGidBit() == True)?"G":"-";
          
        cstr += (permOwnReadBit() == True)?"R":"-";
        cstr += (permOwnWriteBit() == True)?"W":"-";
        cstr += (permOwnExecuteBit() == True)?"X":"-";
          
        cstr += (permGrpReadBit() == True)?"R":"-";
        cstr += (permGrpWriteBit() == True)?"W":"-";
        cstr += (permGrpExecuteBit() == True)?"X":"-";
          
        cstr += (permOthReadBit() == True)?"R":"-";
        cstr += (permOthWriteBit() == True)?"W":"-";
        cstr += (permOthExecuteBit() == True)?"X":"-";

        return (CONST_CHAR_PTR) cstr;
    }

    CONST_CHAR_PTR appendUINT16Bits(UINT16 bits, RWCString& cstr)
    { 
        cstr += (bits & 0x8000) ? "1":"-";
        cstr += (bits & 0x4000) ? "1":"-";
        cstr += (bits & 0x2000) ? "1":"-";
        cstr += (bits & 0x1000) ? "1":"-";
        cstr += (bits & 0x0800) ? "1":"-";
        cstr += (bits & 0x0400) ? "1":"-";
        cstr += (bits & 0x0200) ? "1":"-";
        cstr += (bits & 0x0100) ? "1":"-";
        cstr += (bits & 0x0080) ? "1":"-";
        cstr += (bits & 0x0040) ? "1":"-";
        cstr += (bits & 0x0020) ? "1":"-";
        cstr += (bits & 0x0010) ? "1":"-";
        cstr += (bits & 0x0008) ? "1":"-";
        cstr += (bits & 0x0004) ? "1":"-";
        cstr += (bits & 0x0002) ? "1":"-";
        cstr += (bits & 0x0001) ? "1":"-";

        return (CONST_CHAR_PTR) cstr;
    }

    // A convenient file type description maker.
    CONST_CHAR_PTR appendFileType(RWCString& cstr) const
    {
        switch(fileCharacteristics_.fileType())
        {
        case file_Unspecified:
            cstr += "Unspecified";
            break;
        case file_Directory:
            cstr += "Directory";
            break;
        case file_Raw:
            cstr += "Raw";
            break;
        case file_SpecialBlockDevice:
            cstr += "SpecialBlockDevice";
            break;
        case file_SpecialCharacterDevice:
            cstr += "SpecialCharacterDevice";
            break;
        case file_ExtendedAttributes:
            cstr += "ExtendedAttributes";
            break;
        case file_Fifo:
            cstr += "Fifo";
            break;
        case file_Sock:
            cstr += "Sock";
            break;
        case file_SymbolicLink:
            cstr += "SymbolicLink";
        default: // If we reach here, this is an invalid file type.
            cstr += "InvalidFile";
        }

        return (CONST_CHAR_PTR) cstr;
    }

    // Collect all of the attributes info, at a consistently highest
    // available class level of abstraction.
    CONST_CHAR_PTR appendAttributes (RWCString& cstr) const
    {
        appendOtherInfo(cstr);
        cstr += " ";

        fileCharacteristics_.appendFileCharacteristics(cstr);
        cstr += " ";

        filePermissions_.appendAllPermissions(cstr);
        cstr += " ";

        return (CONST_CHAR_PTR) cstr;
    }

    Boolean setAttributes(const RWCString& cstr)
    {
        RWCString otherCstr = "";
        RWTokenizer tok(cstr);
        
        otherCstr += tok(); otherCstr += " "; // uid label
        otherCstr += tok(); otherCstr += " "; // uid val
        otherCstr += tok(); otherCstr += " "; // gid label
        otherCstr += tok(); otherCstr += " "; // gid val
        otherCstr += tok(); otherCstr += " "; // times label
        otherCstr += tok(); otherCstr += " "; // time
        otherCstr += tok(); otherCstr += " "; // time
        otherCstr += tok(); otherCstr += " "; // time
        otherCstr += tok(); otherCstr += " "; // links label
        otherCstr += tok();  // links val
        if (setOtherInfo(otherCstr) == False)
            return False;
    
        RWCString fileCharacteristicsCstr = tok();
        if (fileCharacteristics_.
            setFileCharacteristics(fileCharacteristicsCstr) == False)
            return False;
    
        RWCString filePermissionsCstr = tok();
        if (filePermissions_.setAllPermissions(filePermissionsCstr) == False)
            return False;
        
        return True;
    }   

#ifdef INCLUDE_PRINT_FUNCS
    // Several print versions of append methods are provided here
    // for convenience.
    void printOtherInfo(CONST_CHAR_PTR label="") const
    {
        RWCString cstr = "";
        appendOtherInfo(cstr);
        printf ("%s: %s\n", label, (CONST_CHAR_PTR)cstr);
    }
 
    void printFileCharacteristics(CONST_CHAR_PTR label="") const
    {
        RWCString cstr = "";
        fileCharacteristics_.appendFileCharacteristics(cstr);
        printf ("%s: %s\n", label, (CONST_CHAR_PTR)cstr);
    }
    void printAllPermissions(CONST_CHAR_PTR label="") const
    {
        RWCString cstr = "";
        filePermissions_.appendAllPermissions(cstr);
        printf ("%s: %s\n", label, (CONST_CHAR_PTR)cstr);
    }
    void printAttributes (CHAR_PTR label = "") const
    {
        RWCString cstr = "";
        appendAttributes(cstr);
        printf ("%s %s\n", label, (CONST_CHAR_PTR)cstr);
    }
    static void printUINT16Bits (UINT16 bits, CHAR_PTR label = "")
    {
        RWCString cstr = "";
        appendUINT16Bits(bits, cstr);
        printf ("%s %s\n", label, (CONST_CHAR_PTR)cstr);
    }
#endif
#endif

    
};


#endif // _NSRATTR_


