<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">###############################################################################
#
#   Package: NaturalDocs::ReferenceString
#
###############################################################################
#
#   A package to manage &lt;ReferenceString&gt; handling throughout the program.
#
###############################################################################

# This file is part of Natural Docs, which is Copyright (C) 2003-2008 Greg Valure
# Natural Docs is licensed under the GPL

use strict;
use integer;

package NaturalDocs::ReferenceString;

use vars '@ISA', '@EXPORT';
@ISA = 'Exporter';
@EXPORT = ( 'BINARYREF_NOTYPE', 'BINARYREF_NORESOLVINGFLAGS',

                     'REFERENCE_TEXT', 'REFERENCE_CH_CLASS', 'REFERENCE_CH_PARENT',

                     'RESOLVE_RELATIVE', 'RESOLVE_ABSOLUTE', 'RESOLVE_NOPLURAL', 'RESOLVE_NOUSING' );


#
#   Constants: Binary Format Flags
#
#   These flags can be combined to specify the format when using &lt;ToBinaryFile()&gt; and &lt;FromBinaryFile()&gt;.  All are exported
#   by default.
#
#   BINARYREF_NOTYPE - Do not include the &lt;ReferenceType&gt;.
#   BINARYREF_NORESOLVEFLAGS - Do not include the &lt;Resolving Flags&gt;.
#
use constant BINARYREF_NOTYPE =&gt; 0x01;
use constant BINARYREF_NORESOLVINGFLAGS =&gt; 0x02;


#
#   Constants: ReferenceType
#
#   The type of a reference.
#
#       REFERENCE_TEXT - The reference appears in the text of the documentation.
#       REFERENCE_CH_CLASS - A class reference handled by &lt;NaturalDocs::ClassHierarchy&gt;.
#       REFERENCE_CH_PARENT - A parent class reference handled by &lt;NaturalDocs::ClassHierarchy&gt;.
#
#   Dependencies:
#
#       - &lt;ToBinaryFile()&gt; and &lt;FromBinaryFile()&gt; require that these values fit into a UInt8, i.e. are &lt;= 255.
#
use constant REFERENCE_TEXT =&gt; 1;
use constant REFERENCE_CH_CLASS =&gt; 2;
use constant REFERENCE_CH_PARENT =&gt; 3;


#
#   Constants: Resolving Flags
#
#   Used to influence the method of resolving references in &lt;NaturalDocs::SymbolTable&gt;.
#
#       RESOLVE_RELATIVE - The reference text is truly relative, rather than Natural Docs' semi-relative.
#       RESOLVE_ABSOLUTE - The reference text is always absolute.  No local or relative references.
#       RESOLVE_NOPLURAL - The reference text may not be interpreted as a plural, and thus match singular forms as well.
#       RESOLVE_NOUSING - The reference text may not include "using" statements when being resolved.
#
#       If neither &lt;RESOLVE_RELATIVE&gt; or &lt;RESOLVE_ABSOLUTE&gt; is specified, Natural Docs' semi-relative kicks in instead,
#       which is where links are interpreted as local, then global, then relative.  &lt;RESOLVE_RELATIVE&gt; states that links are
#       local, then relative, then global.
#
#   Dependencies:
#
#       - &lt;ToBinaryFile()&gt; and &lt;FromBinaryFile()&gt; require that these values fit into a UInt8, i.e. are &lt;= 255.
#
use constant RESOLVE_RELATIVE =&gt; 0x01;
use constant RESOLVE_ABSOLUTE =&gt; 0x02;
use constant RESOLVE_NOPLURAL =&gt; 0x04;
use constant RESOLVE_NOUSING =&gt; 0x08;


#
#
#   Function: MakeFrom
#
#   Encodes the passed information as a &lt;ReferenceString&gt;.  The format of the string should be treated as opaque.  However, the
#   characteristic you can rely on is that the same string will always be made from the same parameters, and thus it's suitable
#   for comparison and use as hash keys.
#
#   Parameters:
#
#       type - The &lt;ReferenceType&gt;.
#       symbol - The &lt;SymbolString&gt; of the reference.
#       language - The name of the language that defines the file this reference appears in.
#       scope - The scope &lt;SymbolString&gt; the reference appears in, or undef if none.
#       using - An arrayref of scope &lt;SymbolStrings&gt; that are also available for checking due to the equivalent a "using" statement,
#                  or undef if none.
#       resolvingFlags - The &lt;Resolving Flags&gt; to use with this reference.  They are ignored if the type is &lt;REFERENCE_TEXT&gt;.
#
#   Returns:
#
#       The encoded &lt;ReferenceString&gt;.
#
sub MakeFrom #(ReferenceType type, SymbolString symbol, string language, SymbolString scope, SymbolString[]* using, flags resolvingFlags)
    {
    my ($self, $type, $symbol, $language, $scope, $using, $resolvingFlags) = @_;

    if ($type == ::REFERENCE_TEXT() || $resolvingFlags == 0)
       {  $resolvingFlags = undef;  };

    # The format is [type] 0x1E [resolving flags] 0x1E [symbol] 0x1E [scope] ( 0x1E [using] )*
    # If there is no scope and/or using, the separator characters still remain.

    # DEPENDENCY: SymbolString-&gt;FromText() removed all 0x1E characters.
    # DEPENDENCY: SymbolString-&gt;FromText() doesn't use 0x1E characters in its encoding.

    my $string = $type . "\x1E" . $symbol . "\x1E" . $language . "\x1E" . $resolvingFlags . "\x1E";

    if (defined $scope)
        {
        $string .= $scope;
        };

    $string .= "\x1E";

    if (defined $using)
        {
        $string .= join("\x1E", @$using);
        };

    return $string;
    };


#
#   Function: ToBinaryFile
#
#   Writes a &lt;ReferenceString&gt; to the passed filehandle.  Can also encode an undef.
#
#   Parameters:
#
#       fileHandle - The filehandle to write to.
#       referenceString - The &lt;ReferenceString&gt; to write, or undef.
#       binaryFormatFlags - Any &lt;Binary Format Flags&gt; you want to use to influence encoding.
#
#   Format:
#
#       &gt; [SymbolString: Symbol or undef for an undef reference]
#       &gt; [AString16: language]
#       &gt; [SymbolString: Scope or undef for none]
#       &gt;
#       &gt; [SymbolString: Using or undef for none]
#       &gt; [SymbolString: Using or undef for no more]
#       &gt; ...
#       &gt;
#       &gt; [UInt8: Type unless BINARYREF_NOTYPE is set]
#       &gt; [UInt8: Resolving Flags unless BINARYREF_NORESOLVINGFLAGS is set]
#
#   Dependencies:
#
#       - &lt;ReferenceTypes&gt; must fit into a UInt8.  All values must be &lt;= 255.
#       - All &lt;Resolving Flags&gt; must fit into a UInt8.  All values must be &lt;= 255.
#
sub ToBinaryFile #(FileHandle fileHandle, ReferenceString referenceString, flags binaryFormatFlags)
    {
    my ($self, $fileHandle, $referenceString, $binaryFormatFlags) = @_;

    my ($type, $symbol, $language, $scope, $using, $resolvingFlags) = $self-&gt;InformationOf($referenceString);

    # [SymbolString: Symbol or undef for an undef reference]

    NaturalDocs::SymbolString-&gt;ToBinaryFile($fileHandle, $symbol);

    # [AString16: language]

    print $fileHandle pack('nA*', length $language, $language);

    # [SymbolString: scope or undef if none]

    NaturalDocs::SymbolString-&gt;ToBinaryFile($fileHandle, $scope);

    # [SymbolString: using or undef if none/no more] ...

    if (defined $using)
        {
        foreach my $usingScope (@$using)
            {  NaturalDocs::SymbolString-&gt;ToBinaryFile($fileHandle, $usingScope);  };
        };

    NaturalDocs::SymbolString-&gt;ToBinaryFile($fileHandle, undef);

    # [UInt8: Type unless BINARYREF_NOTYPE is set]

    if (!($binaryFormatFlags &amp; BINARYREF_NOTYPE))
        {  print $fileHandle pack('C', $type);  };

    # [UInt8: Resolving Flags unless BINARYREF_NORESOLVINGFLAGS is set]

    if (!($binaryFormatFlags &amp; BINARYREF_NORESOLVINGFLAGS))
        {  print $fileHandle pack('C', $type);  };
    };


#
#   Function: FromBinaryFile
#
#   Reads a &lt;ReferenceString&gt; or undef from the passed filehandle.
#
#   Parameters:
#
#       fileHandle - The filehandle to read from.
#       binaryFormatFlags - Any &lt;Binary Format Flags&gt; you want to use to influence decoding.
#       type - The &lt;ReferenceType&gt; to use if &lt;BINARYREF_NOTYPE&gt; is set.
#       resolvingFlags - The &lt;Resolving Flags&gt; to use if &lt;BINARYREF_NORESOLVINGFLAGS&gt; is set.
#
#   Returns:
#
#       The &lt;ReferenceString&gt; or undef.
#
#   See Also:
#
#       See &lt;ToBinaryFile()&gt; for format and dependencies.
#
sub FromBinaryFile #(FileHandle fileHandle, flags binaryFormatFlags, ReferenceType type, flags resolvingFlags)
    {
    my ($self, $fileHandle, $binaryFormatFlags, $type, $resolvingFlags) = @_;
    my $raw;

    # [SymbolString: Symbol or undef for an undef reference]

    my $symbol = NaturalDocs::SymbolString-&gt;FromBinaryFile($fileHandle);

    if (!defined $symbol)
        {  return undef;  };


    # [AString16: language]

    read($fileHandle, $raw, 2);
    my $languageLength = unpack('n', $raw);

    my $language;
    read($fileHandle, $language, $languageLength);


    # [SymbolString: scope or undef if none]

    my $scope = NaturalDocs::SymbolString-&gt;FromBinaryFile($fileHandle);

    # [SymbolString: using or undef if none/no more] ...

    my $usingSymbol;
    my @using;

    while ($usingSymbol = NaturalDocs::SymbolString-&gt;FromBinaryFile($fileHandle))
        {  push @using, $usingSymbol;  };

    if (scalar @using)
        {  $usingSymbol = \@using;  }
    else
        {  $usingSymbol = undef;  };

    # [UInt8: Type unless BINARYREF_NOTYPE is set]

    if (!($binaryFormatFlags &amp; BINARYREF_NOTYPE))
        {
        my $raw;
        read($fileHandle, $raw, 1);
        $type = unpack('C', $raw);
        };

    # [UInt8: Resolving Flags unless BINARYREF_NORESOLVINGFLAGS is set]

    if (!($binaryFormatFlags &amp; BINARYREF_NORESOLVINGFLAGS))
        {
        my $raw;
        read($fileHandle, $raw, 1);
        $resolvingFlags = unpack('C', $raw);
        };

    return $self-&gt;MakeFrom($type, $symbol, $language, $scope, $usingSymbol, $resolvingFlags);
    };


#
#   Function: InformationOf
#
#   Returns the information encoded in a &lt;ReferenceString&gt;.
#
#   Parameters:
#
#       referenceString - The &lt;ReferenceString&gt; to decode.
#
#   Returns:
#
#       The array ( type, symbol, language, scope, using, resolvingFlags ).
#
#       type - The &lt;ReferenceType&gt;.
#       symbol - The &lt;SymbolString&gt;.
#       language - The name of the language that defined the file the reference was defined in.
#       scope - The scope &lt;SymbolString&gt;, or undef if none.
#       using - An arrayref of scope &lt;SymbolStrings&gt; that the reference also has access to via "using" statements, or undef if none.
#       resolvingFlags - The &lt;Resolving Flags&gt; of the reference.
#
sub InformationOf #(ReferenceString referenceString)
    {
    my ($self, $referenceString) = @_;

    my ($type, $symbolString, $language, $resolvingFlags, $scopeString, @usingStrings) = split(/\x1E/, $referenceString);

    if (!length $resolvingFlags)
        {  $resolvingFlags = undef;  };

    return ( $type, $symbolString, $language, $scopeString, [ @usingStrings ], $resolvingFlags );
    };


#
#   Function: TypeOf
#
#   Returns the &lt;ReferenceType&gt; encoded in the reference string.  This is faster than &lt;InformationOf()&gt; if this is
#   the only information you need.
#
sub TypeOf #(ReferenceString referenceString)
    {
    my ($self, $referenceString) = @_;

    $referenceString =~ /^([^\x1E]+)/;
    return $1;
    };


1;
</pre></body></html>