// ----------------------------------------------------------------------------
//  FILE: icmpdnam.hpp
//
//  Classes for portable manipulation of compound, multipart names.
//
//       ICompoundName       - Class that represents a multipart name
//       ICompoundNameParser - Parser that converts text to compound names
// 
//  COPYRIGHT:
//       IBM Open Class Library
//       (C) Copyright International Business Machines Corporation 1997
//       Licensed Material - Program-Property of IBM - All Rights Reserved.
//
// Revision: 84 1.12.1.3 source/core/filesys/icmpdnam.hpp, filesystem, ioc.v400, 980918 
// ----------------------------------------------------------------------------

#ifndef _ICMPDNAM_
#define _ICMPDNAM_

#include <ilanglvl.hpp>
#include <itext.hpp>
#include <iprimtyp.hpp>
#include <imstrmbl.hpp>

#if __IBMCPP__ >= 400
#pragma namemangling(compat)
#endif

// Forward declarations...
class ICompoundNameParser;
class ICompoundNameImp;

#pragma enum(4)
#pragma pack(push,4)

class ICompoundName : public IMSTREAMABLE 
{
    StreamableDeclarationsMacro(ICompoundName);
public:
    ICompoundName();
    ICompoundName(const ICompoundName& copyMe);
                        
    ICompoundName(const IText& path,
    const ICompoundNameParser& parser);

    ICompoundName& operator=(const ICompoundName& copyMe);

    virtual ~ICompoundName();

    virtual long hash() const;
    virtual bool operator==(const ICompoundName& anotherPath) const;
    virtual bool operator!=(const ICompoundName& anotherPath) const;

    virtual bool isFullPath() const;
    
    virtual void setFullPath(bool isFull);

    virtual void append(const ICompoundName& relativePath);

    virtual void factorCommonRoot(const ICompoundName& anotherPath, 
                                  ICompoundName& commonRoot, 
                                  ICompoundName& rootToLeaf) const;

    virtual void truncate(const ICompoundName& relativePath);

    virtual void truncate(unsigned long segmentsToRemove);

    virtual unsigned long numberOfComponents() const;

    virtual IText componentAt(unsigned long index) const;
    
    virtual IText lastComponent() const;

    virtual void appendComponent(const IText& componentPath);
    
    virtual void writeToStream(IDataStream& towhere) const;
    virtual void readFromStream(IDataStream& fromwhere);

private:
    // Private functions, constants and data...
    void makeWritable();

    enum
    {
        kInitialSize = 8
    };

    class ICompoundNameImp* fPath;
};

class ICompoundNameParser 
{
public:
    virtual ~ICompoundNameParser ();
    
    virtual bool operator== (const ICompoundNameParser&) const;
    bool operator!= (const ICompoundNameParser&) const;

    virtual ICompoundName parseName(const IText&) const = 0;
    
    virtual IText formatName(const ICompoundName&) const = 0;

    virtual UniChar separator() const = 0;

protected:
    ICompoundNameParser();
    ICompoundNameParser(const ICompoundNameParser&);
    ICompoundNameParser& operator=(const ICompoundNameParser&);

#if !IC_RTTI_ENABLED
    typedef const char* IParserType;
    virtual    IParserType        typeOf() const = 0;
#endif // IC_RTTI_ENABLED
};

#pragma pack(pop)
#pragma enum(pop)

#if __IBMCPP__ >= 400
#pragma namemangling()
#endif

#endif
