private int CompareSegments(MetadataSegmentSection x, MetadataSegmentSection y)
 {
     if (x.StartExtent > y.StartExtent)
     {
         return(1);
     }
     else if (x.StartExtent < y.StartExtent)
     {
         return(-1);
     }
     return(0);
 }
        private SparseStream OpenSegment(MetadataSegmentSection segment)
        {
            if (segment.Stripes.Length != 1)
            {
                throw new IOException("invalid number of stripes");
            }
            var            stripe = segment.Stripes[0];
            PhysicalVolume pv;

            if (!_pvs.TryGetValue(stripe.PhysicalVolumeName, out pv))
            {
                throw new IOException("missing pv");
            }
            if (pv.PvHeader.DiskAreas.Length != 1)
            {
                throw new IOException("invalid number od pv data areas");
            }
            var dataArea = pv.PvHeader.DiskAreas[0];
            var start    = dataArea.Offset + (stripe.StartExtentNumber * _extentSize * PhysicalVolume.SECTOR_SIZE);
            var length   = segment.ExtentCount * _extentSize * PhysicalVolume.SECTOR_SIZE;

            return(new SubStream(pv.Content, Ownership.None, (long)start, (long)length));
        }
        internal void Parse(string head, TextReader data)
        {
            var segments = new List <MetadataSegmentSection>();

            Name = head.Trim().TrimEnd('{').TrimEnd();
            string line;

            while ((line = Metadata.ReadLine(data)) != null)
            {
                if (line == String.Empty)
                {
                    continue;
                }
                if (line.Contains("="))
                {
                    var parameter = Metadata.ParseParameter(line);
                    switch (parameter.Key.Trim().ToLowerInvariant())
                    {
                    case "id":
                        Id = Metadata.ParseStringValue(parameter.Value);
                        byte[] guid = new byte[16];
                        EndianUtilities.StringToBytes(Id.Replace("-", String.Empty), guid, 0, 16);
                        // Mark it as a version 4 GUID
                        guid[7]  = (byte)((guid[7] | (byte)0x40) & (byte)0x4f);
                        guid[8]  = (byte)((guid[8] | (byte)0x80) & (byte)0xbf);
                        Identity = new Guid(guid);
                        break;

                    case "status":
                        var values = Metadata.ParseArrayValue(parameter.Value);
                        foreach (var value in values)
                        {
                            switch (value.ToLowerInvariant().Trim())
                            {
                            case "read":
                                Status |= LogicalVolumeStatus.Read;
                                break;

                            case "write":
                                Status |= LogicalVolumeStatus.Write;
                                break;

                            case "visible":
                                Status |= LogicalVolumeStatus.Visible;
                                break;

                            default:
                                throw new ArgumentOutOfRangeException("status", "Unexpected status in physical volume metadata");
                            }
                        }
                        break;

                    case "flags":
                        Flags = Metadata.ParseArrayValue(parameter.Value);
                        break;

                    case "creation_host":
                        CreationHost = Metadata.ParseStringValue(parameter.Value);
                        break;

                    case "creation_time":
                        CreationTime = Metadata.ParseDateTimeValue(parameter.Value);
                        break;

                    case "segment_count":
                        SegmentCount = Metadata.ParseNumericValue(parameter.Value);
                        break;

                    default:
                        throw new ArgumentOutOfRangeException(parameter.Key, "Unexpected parameter in global metadata");
                    }
                }
                else if (line.EndsWith("{"))
                {
                    var segment = new MetadataSegmentSection();
                    segment.Parse(line, data);
                    segments.Add(segment);
                }
                else if (line.EndsWith("}"))
                {
                    break;
                }
                else
                {
                    throw new ArgumentOutOfRangeException(line, "unexpected input");
                }
            }
            Segments = segments.ToArray();
        }