Beispiel #1
0
        /// <summary>
        ///     Reads a BCFv2 zip archive
        /// </summary>
        /// <param name="zipFileStream">The zip archive of the physical file</param>
        /// <returns></returns>
        public static BCFv21Container ReadStream(Stream zipFileStream)
        {
            var container     = new BCFv21Container();
            var bcfZipArchive = new ZipArchive(zipFileStream, ZipArchiveMode.Read);
            // Check if version info is compliant with this implementation (2.1)
            var versionEntry = bcfZipArchive.Entries.FirstOrDefault(e => string.Equals(e.FullName, "bcf.version", StringComparison.OrdinalIgnoreCase));

            if (versionEntry != null)
            {
                var fileVersionInfo = Version.Deserialize(versionEntry.Open());
                if (fileVersionInfo.VersionId != "2.1" || !fileVersionInfo.DetailedVersion.Contains("2.1"))
                {
                    throw new NotSupportedException("BCFzip version");
                }
            }
            // Get project info if present
            if (bcfZipArchive.Entries.Any(e => e.FullName == "project.bcfp"))
            {
                var deserializedProject = ProjectExtension.Deserialize(bcfZipArchive.Entries.First(Entry => Entry.FullName == "project.bcfp").Open());
                if (!(string.IsNullOrWhiteSpace(deserializedProject.ExtensionSchema) && (deserializedProject.Project == null || string.IsNullOrWhiteSpace(deserializedProject.Project.Name) && string.IsNullOrWhiteSpace(deserializedProject.Project.ProjectId))))
                {
                    if (string.IsNullOrWhiteSpace(deserializedProject.ExtensionSchema))
                    {
                        deserializedProject.ExtensionSchema = null;
                    }
                    container.BcfProject = deserializedProject;
                    if (!string.IsNullOrWhiteSpace(container.BcfProject.ExtensionSchema) && bcfZipArchive.Entries.Any(e => e.FullName == container.BcfProject.ExtensionSchema))
                    {
                        using (var extensionsReader = new StreamReader(bcfZipArchive.Entries.First(e => e.FullName == container.BcfProject.ExtensionSchema).Open()))
                        {
                            container.ProjectExtensions = new ProjectExtensions(extensionsReader.ReadToEnd());
                        }
                    }
                }
            }
            // Get each topic's GUID and read the topic
            var topicIds = new List <string>();

            foreach (var entry in bcfZipArchive.Entries)
            {
                var topicId = entry.FullName;
                if (Regex.IsMatch(topicId, @"^\b[A-Fa-f0-9]{8}(?:-[A-Fa-f0-9]{4}){3}-[A-Fa-f0-9]{12}/markup.bcf\b"))
                {
                    if (!topicIds.Contains(Regex.Match(topicId, @"^\b[A-Fa-f0-9]{8}(?:-[A-Fa-f0-9]{4}){3}-[A-Fa-f0-9]{12}\b").Value))
                    {
                        container.Topics.Add(ReadSingleTopic(bcfZipArchive, Regex.Match(topicId, @"^\b[A-Fa-f0-9]{8}(?:-[A-Fa-f0-9]{4}){3}-[A-Fa-f0-9]{12}\b").Value, container));
                    }
                    topicIds.Add(Regex.Match(topicId, @"^\b[A-Fa-f0-9]{8}(?:-[A-Fa-f0-9]{4}){3}-[A-Fa-f0-9]{12}\b").Value);
                }
            }
            // Check if there is no extension but a reference to it; delete the reference then
            if (container.ProjectExtensions == null && !string.IsNullOrWhiteSpace(container.BcfProject?.ExtensionSchema))
            {
                container.BcfProject.ExtensionSchema = null;
            }
            return(container);
        }
Beispiel #2
0
        private static BCFTopic ReadSingleTopic(ZipArchive archive, string topicId, BCFv21Container container)
        {
            var topic = new BCFTopic();

            // Get the markup
            topic.Markup = Markup.Deserialize(archive.Entries.First(e => e.FullName == topicId + "/" + "markup.bcf").Open());
            // Check if any comments have a Viewpoint object without any value, then set it to null
            foreach (var comment in topic.Markup.Comment.Where(c => c.ShouldSerializeViewpoint() && string.IsNullOrWhiteSpace(c.Viewpoint.Guid)))
            {
                comment.Viewpoint = null;
            }
            if (topic.Markup.Topic.ShouldSerializeBimSnippet() && !topic.Markup.Topic.BimSnippet.isExternal)
            {
                // Read the snippet
                var snippetPathInArchive = GetAbsolutePath(topicId, topic.Markup.Topic.BimSnippet.Reference);
                var entry = archive.Entries.FirstOrDefault(Curr => Curr.FullName == snippetPathInArchive);
                if (entry == null)
                {
                    topic.Markup.Topic.BimSnippet.isExternal = true;
                }
                else
                {
                    using (var memStream = new MemoryStream())
                    {
                        entry.Open().CopyTo(memStream);
                        topic.SnippetData = memStream.ToArray();
                    }
                }
            }
            // See if any internal header files are referenced
            if (topic.Markup.ShouldSerializeHeader() && topic.Markup.Header.Any(h => !h.isExternal))
            {
                foreach (var internalFile in topic.Markup.Header.Where(h => !h.isExternal))
                {
                    if (internalFile.Reference == null)
                    {
                        continue;
                    }
                    var filePathInArchive = GetAbsolutePath(topicId, internalFile.Reference);
                    var entry             = archive.Entries.FirstOrDefault(e => e.FullName == filePathInArchive);
                    // Only append if not known already and the file is actually present
                    if (entry != null && !container.FileAttachments.ContainsKey(entry.Name))
                    {
                        using (var memStream = new MemoryStream())
                        {
                            entry.Open().CopyTo(memStream);
                            container.FileAttachments.Add(entry.Name, memStream.ToArray());
                        }
                    }
                }
            }
            // Get referenced documents
            if (topic.Markup.Topic.ShouldSerializeDocumentReference() && topic.Markup.Topic.DocumentReference.Any(d => !d.isExternal))
            {
                foreach (var internalDocument in topic.Markup.Topic.DocumentReference.Where(d => !d.isExternal))
                {
                    var filePathInArchive = GetAbsolutePath(topicId, internalDocument.ReferencedDocument);
                    var entry             = archive.Entries.FirstOrDefault(e => e.FullName == filePathInArchive);
                    // Only append if not known already and the file is actually present
                    if (entry != null && !container.FileAttachments.ContainsKey(entry.Name))
                    {
                        using (var memStream = new MemoryStream())
                        {
                            entry.Open().CopyTo(memStream);
                            container.FileAttachments.Add(entry.Name, memStream.ToArray());
                        }
                    }
                }
            }
            // Get viewpoints
            for (var i = 0; i < topic.Markup.Viewpoints.Count; i++)
            {
                var deserializedViewpoint = VisualizationInfo.Deserialize(archive.Entries.First(e => e.FullName == topicId + "/" + topic.Markup.Viewpoints[i].Viewpoint).Open());
                deserializedViewpoint.Guid = topic.Markup.Viewpoints[i].Guid;
                topic.Viewpoints.Add(deserializedViewpoint);
                // Get viewpoint bitmaps if present
                if (topic.Viewpoints[i].Bitmap.Count > 0)
                {
                    foreach (var viewpointBitmap in topic.Viewpoints[i].Bitmap)
                    {
                        using (var bytesMemoryStream = new MemoryStream())
                        {
                            var bitmapPathInArchive = GetAbsolutePath(topicId, viewpointBitmap.Reference);
                            var bitmapFileEntry     = archive.Entries.FirstOrDefault(e => e.FullName == bitmapPathInArchive);
                            if (bitmapFileEntry == null)
                            {
                                // File entry was not found, possible because it was referenced with an absolute path
                                bitmapPathInArchive = GetAbsolutePath(topicId, TransformToRelativePath(viewpointBitmap.Reference, topicId));
                                bitmapFileEntry     = archive.Entries.FirstOrDefault(e => e.FullName == bitmapPathInArchive);
                                if (bitmapFileEntry != null)
                                {
                                    viewpointBitmap.Reference = TransformToRelativePath(viewpointBitmap.Reference, topicId);
                                }
                                else
                                {
                                    throw new ArgumentNullException(nameof(bitmapFileEntry), "Could not locate bitmap file in archive");
                                }
                            }
                            bitmapFileEntry.Open().CopyTo(bytesMemoryStream);
                            if (!topic.ViewpointBitmaps.ContainsKey(topic.Viewpoints[i]))
                            {
                                topic.ViewpointBitmaps.Add(topic.Viewpoints[i], new List <byte[]>());
                            }
                            topic.ViewpointBitmaps[topic.Viewpoints[i]].Add(bytesMemoryStream.ToArray());
                        }
                    }
                }
                if (!string.IsNullOrWhiteSpace(topic.Markup.Viewpoints[i].Snapshot))
                {
                    using (var bytesMemoryStream = new MemoryStream())
                    {
                        archive.Entries.First(e => e.FullName == topicId + "/" + topic.Markup.Viewpoints[i].Snapshot).Open().CopyTo(bytesMemoryStream);
                        topic.AddOrUpdateSnapshot(topic.Viewpoints[i].Guid, bytesMemoryStream.ToArray());
                    }
                }
            }
            return(topic);
        }