OSDN Git Service

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