1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335
|
###############################################################################
#
# Package: NaturalDocs::ReferenceString
#
###############################################################################
#
# A package to manage <ReferenceString> handling throughout the program.
#
###############################################################################
# This file is part of Natural Docs, which is Copyright 2003-2010 Greg Valure
# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
# Refer to License.txt for the complete details
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 <ToBinaryFile()> and <FromBinaryFile()>. All are exported
# by default.
#
# BINARYREF_NOTYPE - Do not include the <ReferenceType>.
# BINARYREF_NORESOLVEFLAGS - Do not include the <Resolving Flags>.
#
use constant BINARYREF_NOTYPE => 0x01;
use constant BINARYREF_NORESOLVINGFLAGS => 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 <NaturalDocs::ClassHierarchy>.
# REFERENCE_CH_PARENT - A parent class reference handled by <NaturalDocs::ClassHierarchy>.
#
# Dependencies:
#
# - <ToBinaryFile()> and <FromBinaryFile()> require that these values fit into a UInt8, i.e. are <= 255.
#
use constant REFERENCE_TEXT => 1;
use constant REFERENCE_CH_CLASS => 2;
use constant REFERENCE_CH_PARENT => 3;
#
# Constants: Resolving Flags
#
# Used to influence the method of resolving references in <NaturalDocs::SymbolTable>.
#
# 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 <RESOLVE_RELATIVE> or <RESOLVE_ABSOLUTE> is specified, Natural Docs' semi-relative kicks in instead,
# which is where links are interpreted as local, then global, then relative. <RESOLVE_RELATIVE> states that links are
# local, then relative, then global.
#
# Dependencies:
#
# - <ToBinaryFile()> and <FromBinaryFile()> require that these values fit into a UInt8, i.e. are <= 255.
#
use constant RESOLVE_RELATIVE => 0x01;
use constant RESOLVE_ABSOLUTE => 0x02;
use constant RESOLVE_NOPLURAL => 0x04;
use constant RESOLVE_NOUSING => 0x08;
#
#
# Function: MakeFrom
#
# Encodes the passed information as a <ReferenceString>. 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 <ReferenceType>.
# symbol - The <SymbolString> of the reference.
# language - The name of the language that defines the file this reference appears in.
# scope - The scope <SymbolString> the reference appears in, or undef if none.
# using - An arrayref of scope <SymbolStrings> that are also available for checking due to the equivalent a "using" statement,
# or undef if none.
# resolvingFlags - The <Resolving Flags> to use with this reference. They are ignored if the type is <REFERENCE_TEXT>.
#
# Returns:
#
# The encoded <ReferenceString>.
#
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->FromText() removed all 0x1E characters.
# DEPENDENCY: SymbolString->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 <ReferenceString> to the passed filehandle. Can also encode an undef.
#
# Parameters:
#
# fileHandle - The filehandle to write to.
# referenceString - The <ReferenceString> to write, or undef.
# binaryFormatFlags - Any <Binary Format Flags> you want to use to influence encoding.
#
# Format:
#
# > [SymbolString: Symbol or undef for an undef reference]
# > [AString16: language]
# > [SymbolString: Scope or undef for none]
# >
# > [SymbolString: Using or undef for none]
# > [SymbolString: Using or undef for no more]
# > ...
# >
# > [UInt8: Type unless BINARYREF_NOTYPE is set]
# > [UInt8: Resolving Flags unless BINARYREF_NORESOLVINGFLAGS is set]
#
# Dependencies:
#
# - <ReferenceTypes> must fit into a UInt8. All values must be <= 255.
# - All <Resolving Flags> must fit into a UInt8. All values must be <= 255.
#
sub ToBinaryFile #(FileHandle fileHandle, ReferenceString referenceString, flags binaryFormatFlags)
{
my ($self, $fileHandle, $referenceString, $binaryFormatFlags) = @_;
my ($type, $symbol, $language, $scope, $using, $resolvingFlags) = $self->InformationOf($referenceString);
# [SymbolString: Symbol or undef for an undef reference]
NaturalDocs::SymbolString->ToBinaryFile($fileHandle, $symbol);
# [AString16: language]
print $fileHandle pack('nA*', length $language, $language);
# [SymbolString: scope or undef if none]
NaturalDocs::SymbolString->ToBinaryFile($fileHandle, $scope);
# [SymbolString: using or undef if none/no more] ...
if (defined $using)
{
foreach my $usingScope (@$using)
{ NaturalDocs::SymbolString->ToBinaryFile($fileHandle, $usingScope); };
};
NaturalDocs::SymbolString->ToBinaryFile($fileHandle, undef);
# [UInt8: Type unless BINARYREF_NOTYPE is set]
if (!($binaryFormatFlags & BINARYREF_NOTYPE))
{ print $fileHandle pack('C', $type); };
# [UInt8: Resolving Flags unless BINARYREF_NORESOLVINGFLAGS is set]
if (!($binaryFormatFlags & BINARYREF_NORESOLVINGFLAGS))
{ print $fileHandle pack('C', $type); };
};
#
# Function: FromBinaryFile
#
# Reads a <ReferenceString> or undef from the passed filehandle.
#
# Parameters:
#
# fileHandle - The filehandle to read from.
# binaryFormatFlags - Any <Binary Format Flags> you want to use to influence decoding.
# type - The <ReferenceType> to use if <BINARYREF_NOTYPE> is set.
# resolvingFlags - The <Resolving Flags> to use if <BINARYREF_NORESOLVINGFLAGS> is set.
#
# Returns:
#
# The <ReferenceString> or undef.
#
# See Also:
#
# See <ToBinaryFile()> 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->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->FromBinaryFile($fileHandle);
# [SymbolString: using or undef if none/no more] ...
my $usingSymbol;
my @using;
while ($usingSymbol = NaturalDocs::SymbolString->FromBinaryFile($fileHandle))
{ push @using, $usingSymbol; };
if (scalar @using)
{ $usingSymbol = \@using; }
else
{ $usingSymbol = undef; };
# [UInt8: Type unless BINARYREF_NOTYPE is set]
if (!($binaryFormatFlags & BINARYREF_NOTYPE))
{
my $raw;
read($fileHandle, $raw, 1);
$type = unpack('C', $raw);
};
# [UInt8: Resolving Flags unless BINARYREF_NORESOLVINGFLAGS is set]
if (!($binaryFormatFlags & BINARYREF_NORESOLVINGFLAGS))
{
my $raw;
read($fileHandle, $raw, 1);
$resolvingFlags = unpack('C', $raw);
};
return $self->MakeFrom($type, $symbol, $language, $scope, $usingSymbol, $resolvingFlags);
};
#
# Function: InformationOf
#
# Returns the information encoded in a <ReferenceString>.
#
# Parameters:
#
# referenceString - The <ReferenceString> to decode.
#
# Returns:
#
# The array ( type, symbol, language, scope, using, resolvingFlags ).
#
# type - The <ReferenceType>.
# symbol - The <SymbolString>.
# language - The name of the language that defined the file the reference was defined in.
# scope - The scope <SymbolString>, or undef if none.
# using - An arrayref of scope <SymbolStrings> that the reference also has access to via "using" statements, or undef if none.
# resolvingFlags - The <Resolving Flags> 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 <ReferenceType> encoded in the reference string. This is faster than <InformationOf()> if this is
# the only information you need.
#
sub TypeOf #(ReferenceString referenceString)
{
my ($self, $referenceString) = @_;
$referenceString =~ /^([^\x1E]+)/;
return $1;
};
1;
|