예제 #1
0
        internal bool TryGetDocument(string fullPath, out DocumentHandle documentHandle)
        {
            var fileName = FileNameUtilities.GetFileName(fullPath);

            KeyValuePair <DocumentNameAndHandle, ImmutableArray <DocumentNameAndHandle> > documents;

            if (!_map.TryGetValue(fileName, out documents))
            {
                documentHandle = default(DocumentHandle);
                return(false);
            }

            // SymReader first attempts to find the document by the full path, then by file name with extension.

            if (documents.Key.FileName != null)
            {
                // There is only one document with the specified file name.
                // SymReader returns the document regardless of whether the path matches the name.
                documentHandle = documents.Key.Handle;
                return(true);
            }

            Debug.Assert(documents.Value.Length > 1);

            // We have multiple candidates with the same file name. Find the one whose name matches the specified full path.
            // If none does return the first one. It will be the one with the smallest handle, due to the multi-map construction implementation.

            // First try to find candidate whose full name is exactly matching.
            foreach (DocumentNameAndHandle candidate in documents.Value)
            {
                if (_reader.StringComparer.Equals(_reader.GetDocument(candidate.Handle).Name, fullPath, ignoreCase: false))
                {
                    documentHandle = candidate.Handle;
                    return(true);
                }
            }

            // Then try to find candidate whose full name is matching ignoring case.
            foreach (DocumentNameAndHandle candidate in documents.Value)
            {
                if (_reader.StringComparer.Equals(_reader.GetDocument(candidate.Handle).Name, fullPath, ignoreCase: true))
                {
                    documentHandle = candidate.Handle;
                    return(true);
                }
            }

            // Then try to find candidate whose file name is matching exactly.
            foreach (DocumentNameAndHandle candidate in documents.Value)
            {
                if (candidate.FileName == fileName)
                {
                    documentHandle = candidate.Handle;
                    return(true);
                }
            }

            documentHandle = documents.Value[0].Handle;
            return(true);
        }
예제 #2
0
        private static string GetFileName(MetadataReader reader, DocumentHandle documentHandle)
        {
            var document = reader.GetDocument(documentHandle);

            if (document.Name.IsNil)
            {
                return(null);
            }

            var nameReader = reader.GetBlobReader(document.Name);

            int separator = nameReader.ReadByte();

            if (!FileNameUtilities.IsDirectorySeparator((char)separator))
            {
                return(FileNameUtilities.GetFileName(reader.GetString(document.Name)));
            }

            // find the last part handle:
            BlobHandle partHandle = default(BlobHandle);

            while (nameReader.RemainingBytes > 0)
            {
                partHandle = nameReader.ReadBlobHandle();
            }

            if (partHandle.IsNil)
            {
                return(string.Empty);
            }

            var partReader = reader.GetBlobReader(partHandle);
            var part       = partReader.ReadUTF8(partReader.Length);

            if (part.IndexOf('\0') >= 0)
            {
                // bad metadata
                return(null);
            }

            // it is valid to encode document name so that the parts contain directory separators:
            return(FileNameUtilities.GetFileName(part));
        }