.. _Name.Component:

Name.Component Class
====================

A Name.Component is holds a read-only name component value

:[C++]:

    Namespace: ``ndn``

Name.Component Constructor
--------------------------

Create a new Name.Component, copying the optional value.


:[C++]:

    .. code-block:: c++
    
        ndn::Name::Component(
            [const std::vector<uint8_t>& value]
        );

:Parameters:

    - ``value``
        (optional) The content byte array to copy.

Name.Component.toEscapedString Method
-------------------------------------

Convert this component value by escaping characters according to the NDN URI Scheme.

:[C++]:

    .. code-block:: c++
    
        std::string toEscapedString() const ();

:Returns:

    The escaped string.

.. _Name:

Name Class
==========

A Name holds an array of Name.Component and represents an NDN name.

:[C++]:
    Namespace: ``ndn``

:[Python]:
    Module: ``pyndn``

Name Constructor (array of components)
--------------------------------------

Create a new Name with the optional components.

:[C++]:

    .. code-block:: c++
    
        Name(
            [const std::vector<Name::Component>& components]
        );

:[JavaScript]:

    .. code-block:: javascript
    
        var Name = function Name (
            [components   // Array<Uint8Array>]    
        )

:[Python]:

    .. code-block:: python
    
        def __init__(self
            [, components // Array<string>]
        )
    
:Parameters:

    - ``components``
        (optional) The array of name components.

Name Constructor (from URI)
---------------------------

Parse the uri according to the NDN URI Scheme and create the Name with the components.

:[C++]:

    .. code-block:: c++
    
        Name(
            const char* uri
        );

:[JavaScript]:

    .. code-block:: javascript
    
        var Name = function Name (
            uri // string
        )

:Parameters:

    - ``uri``
        The URI in NDN URI Scheme.

Name.toUri Method
-----------------

Return the escaped name string according to the NDN URI Scheme.

:[C++]:

    .. code-block:: c++
    
        std::string toUri() const ();

:[JavaScript]:

    .. code-block:: javascript
    
        // Returns string
        Name.prototype.toUri = function();

:Returns:

The escaped name string according to the NDN URI Scheme.

Name.size Method
----------------

Get the number of components.

:[C++]:

    .. code-block:: c++
    
        size_t getComponentCount() const;

:Returns:

    The number of components.

Name.get Method
---------------

Get a Name Component by index number.

:[C++]:

    .. code-block:: c++
    
        const Component& getComponent(
            size_t i
        ) const;

:Parameters:

    - ``i``
        The index of the component to get, starting from 0.

:Returns:

    The Name.Component.

Name.getPrefix Method
---------------------

Get a new Name with the first nComponents components of this Name.

:[C++]:

    .. code-block:: c++
    
        Name getPrefix(
            size_t nComponents
        ) const;

:[JavaScript]:

    .. code-block:: javascript
    
        // Returns Name
        Name.prototype.getPrefix = function(
            nComponents  // Number
        );

:Parameters:

    - nComponents
        The number of prefix components. If larger than the number of components in this name, return a copy of this Name.

:Returns:

    A new Name.

Name.getSubName Method
----------------------

Get a new name, constructed as a subset of components.

:[C++]:

    .. code-block:: c++
    
        Name getSubName(
            size_t iStartComponent
            [, size_t nComponents]
        ) const;

:Parameters:

    - ``iStartComponent``
        The index if the first component to get.

    - ``nComponents``
        (optional) The number of components starting at iStartComponent. If omitted, return components until the end of the name.

:Returns:

    A new Name.

Name.match Method
-----------------

Check if the N components of this name are the same as the first N components of the given name.

:[C++]:

    .. code-block:: c++
    
        bool match(
            const Name& name
        ) const;

:[JavaScript]:

    .. code-block:: javascript
    
        // Returns boolean
        Name.prototype.match = function(
            name  // Name
        );

:Parameters:

    - ``name``
        The Name to check.

    - ``nComponents``
        The number of components starting at iStartComponent. If omitted, return components until the end of the name.

:Returns:

    true if this matches the given name, otherwise false.  This always returns true if this name is empty.

Name.append Method (copy byte array)
------------------------------------

Append a new component, copying from byte array.

:[C++]:

    .. code-block:: c++
    
        Name& append(
            const std::vector<uint8_t>& value
        );

:[JavaScript]:

    .. code-block:: javascript
    
        // Returns this Name
        Name.prototype.append = function(
            value  // Array<number>|ArrayBuffer|Uint8Array
        )

:Parameters:

    - ``value``
        The component byte array to copy.

:Returns:

    This name so that you can chain calls to append.

Name.append Method (from Blob)
------------------------------

Append a new component, taking another pointer to the byte array in the Blob.

:[C++]:

    .. code-block:: c++
    
        Name& append(
            const Blob& value
        );

:Parameters:

    - ``value``
        The Blob with the pointer to the byte array.

:Returns:

    This name so that you can chain calls to append.

Name.append Method (from Component)
-----------------------------------

Append the component to this name.

:[C++]:

    .. code-block:: c++
    
        Name& append(
            const Name::Component& value
        );

:Parameters:

    - ``value``
        The Name.Component to append.

:Returns:

    This name so that you can chain calls to append.

Name.append Method (from Name)
------------------------------

Append the components of the given name to this name.

:[C++]:

    .. code-block:: c++
    
        Name& append(
            const Name& name
        );

:[JavaScript]:

    .. code-block:: javascript
    
        // Returns this Name
        Name.prototype.append = function(
            value  // Name
        )

:Parameters:

    - ``name``
        The Name with components to append.

:Returns:

    This name so that you can chain calls to append.

Name.appendSegment Method
-------------------------

Append a component with the encoded segment number.

:[C++]:

    .. code-block:: c++
    
        Name& appendSegment(
            uint64_t segment
        );

:[JavaScript]:

    .. code-block:: javascript
    
        // Returns this Name
        Name.prototype.appendSegment = function(
            segment  // Number
        )

:Parameters:

    - ``segment``
        The integer segment number to be encoded.

:Returns:

    This name so that you can chain calls to append.

Name.appendVersion Method
-------------------------

Append a component with the encoded version number. Note that this encodes the exact value of version without converting from a time representation.

:[C++]:

    .. code-block:: c++
    
        Name& appendVersion(
            uint64_t version
        );

:Parameters:

    - ``version``
        The version number to be encoded.

:Returns:

    This name so that you can chain calls to append.

Other Name getter and setter methods
------------------------------------

:[JavaScript]:

    .. code-block:: javascript
    
        // Returns a new Name
        Name.prototype.cut = function(
            minusComponents  // number
        )
        
        // Returns number
        Name.prototype.indexOfFileName = function()
        
        // Returns Boolean
        Name.prototype.equalsName = function(
            name            // Name
        )
