diff --git a/DiscImageChef.Helpers/DiscImageChef.Helpers.csproj b/DiscImageChef.Helpers/DiscImageChef.Helpers.csproj index b20970cb1..7f2ebf4a0 100644 --- a/DiscImageChef.Helpers/DiscImageChef.Helpers.csproj +++ b/DiscImageChef.Helpers/DiscImageChef.Helpers.csproj @@ -45,6 +45,14 @@ + + + + + + + + @@ -58,6 +66,9 @@ LICENSE.LGPL + + + @@ -70,7 +81,7 @@ - + diff --git a/DiscImageChef.Helpers/Extents/ExtentsByte.cs b/DiscImageChef.Helpers/Extents/ExtentsByte.cs new file mode 100644 index 000000000..f5e0dd5ff --- /dev/null +++ b/DiscImageChef.Helpers/Extents/ExtentsByte.cs @@ -0,0 +1,200 @@ +// /*************************************************************************** +// The Disc Image Chef +// ---------------------------------------------------------------------------- +// +// Filename : ExtentsByte.cs +// Author(s) : Natalia Portillo +// +// Component : Component +// +// --[ Description ] ---------------------------------------------------------- +// +// Description +// +// --[ License ] -------------------------------------------------------------- +// +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 2.1 of the +// License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, see . +// +// ---------------------------------------------------------------------------- +// Copyright © 2011-2017 Natalia Portillo +// ****************************************************************************/ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Extents +{ + public class ExtentsByte + { + List> backend; + + public ExtentsByte() + { + backend = new List>(); + } + + public int Count { get { return backend.Count; } } + + public void Add(byte item) + { + Tuple removeOne = null; + Tuple removeTwo = null; + Tuple itemToAdd = null; + + for(int i = 0; i < backend.Count; i++) + { + // Already contained in an extent + if(item >= backend[i].Item1 && item <= backend[i].Item2) + return; + + // Expands existing extent start + if(item == backend[i].Item1 - 1) + { + removeOne = backend[i]; + + if(i > 0 && item == backend[i - 1].Item2 + 1) + { + removeTwo = backend[i - 1]; + itemToAdd = new Tuple(backend[i - 1].Item1, backend[i].Item2); + } + else + itemToAdd = new Tuple(item, backend[i].Item2); + + break; + } + + // Expands existing extent end + if(item == backend[i].Item2 + 1) + { + removeOne = backend[i]; + + if(i < backend.Count - 1 && item == backend[i + 1].Item1 - 1) + { + removeTwo = backend[i + 1]; + itemToAdd = new Tuple(backend[i].Item1, backend[i + 1].Item2); + } + else + itemToAdd = new Tuple(backend[i].Item1, item); + + break; + } + } + + if(itemToAdd != null) + { + backend.Remove(removeOne); + backend.Remove(removeTwo); + backend.Add(itemToAdd); + } + else + backend.Add(new Tuple(item, item)); + + // Sort + backend = backend.OrderBy(t => t.Item1).ToList(); + } + + public void Add(byte start, byte end) + { + Add(start, end, false); + } + + public void Add(byte start, byte end, bool run) + { + byte realEnd; + if(run) + realEnd = (byte)(start + end - 1); + else + realEnd = end; + + // TODO: Optimize this + for(byte t = start; t <= realEnd; t++) + Add(t); + } + + public bool Contains(byte item) + { + foreach(Tuple extent in backend) + if(item >= extent.Item1 && item <= extent.Item2) + return true; + return false; + } + + public void Clear() + { + backend.Clear(); + } + + public bool Remove(byte item) + { + Tuple toRemove = null; + Tuple toAddOne = null; + Tuple toAddTwo = null; + + foreach(Tuple extent in backend) + { + // Extent is contained and not a border + if(item > extent.Item1 && item < extent.Item2) + { + toRemove = extent; + toAddOne = new Tuple(extent.Item1, (byte)(item - 1)); + toAddTwo = new Tuple((byte)(item + 1), extent.Item2); + break; + } + + // Extent is left border, but not only element + if(item == extent.Item1 && item != extent.Item2) + { + toRemove = extent; + toAddOne = new Tuple((byte)(item + 1), extent.Item2); + break; + } + + // Extent is right border, but not only element + if(item != extent.Item1 && item == extent.Item2) + { + toRemove = extent; + toAddOne = new Tuple(extent.Item1, (byte)(item - 1)); + break; + } + + // Extent is only element + if(item == extent.Item1 && item == extent.Item2) + { + toRemove = extent; + break; + } + } + + // Item not found + if(toRemove == null) + return false; + + backend.Remove(toRemove); + if(toAddOne != null) + backend.Add(toAddOne); + if(toAddTwo != null) + backend.Add(toAddTwo); + + // Sort + backend = backend.OrderBy(t => t.Item1).ToList(); + + return true; + } + + public Tuple[] ToArray() + { + return backend.ToArray(); + } + } +} diff --git a/DiscImageChef.Helpers/Extents/ExtentsInt.cs b/DiscImageChef.Helpers/Extents/ExtentsInt.cs new file mode 100644 index 000000000..096aa5f1d --- /dev/null +++ b/DiscImageChef.Helpers/Extents/ExtentsInt.cs @@ -0,0 +1,200 @@ +// /*************************************************************************** +// The Disc Image Chef +// ---------------------------------------------------------------------------- +// +// Filename : ExtentsInt.cs +// Author(s) : Natalia Portillo +// +// Component : Component +// +// --[ Description ] ---------------------------------------------------------- +// +// Description +// +// --[ License ] -------------------------------------------------------------- +// +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 2.1 of the +// License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License aint with this library; if not, see . +// +// ---------------------------------------------------------------------------- +// Copyright © 2011-2017 Natalia Portillo +// ****************************************************************************/ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Extents +{ + public class ExtentsInt + { + List> backend; + + public ExtentsInt() + { + backend = new List>(); + } + + public int Count { get { return backend.Count; } } + + public void Add(int item) + { + Tuple removeOne = null; + Tuple removeTwo = null; + Tuple itemToAdd = null; + + for(int i = 0; i < backend.Count; i++) + { + // Already contained in an extent + if(item >= backend[i].Item1 && item <= backend[i].Item2) + return; + + // Expands existing extent start + if(item == backend[i].Item1 - 1) + { + removeOne = backend[i]; + + if(i > 0 && item == backend[i - 1].Item2 + 1) + { + removeTwo = backend[i - 1]; + itemToAdd = new Tuple(backend[i - 1].Item1, backend[i].Item2); + } + else + itemToAdd = new Tuple(item, backend[i].Item2); + + break; + } + + // Expands existing extent end + if(item == backend[i].Item2 + 1) + { + removeOne = backend[i]; + + if(i < backend.Count - 1 && item == backend[i + 1].Item1 - 1) + { + removeTwo = backend[i + 1]; + itemToAdd = new Tuple(backend[i].Item1, backend[i + 1].Item2); + } + else + itemToAdd = new Tuple(backend[i].Item1, item); + + break; + } + } + + if(itemToAdd != null) + { + backend.Remove(removeOne); + backend.Remove(removeTwo); + backend.Add(itemToAdd); + } + else + backend.Add(new Tuple(item, item)); + + // Sort + backend = backend.OrderBy(t => t.Item1).ToList(); + } + + public void Add(int start, int end) + { + Add(start, end, false); + } + + public void Add(int start, int end, bool run) + { + int realEnd; + if(run) + realEnd = start + end - 1; + else + realEnd = end; + + // TODO: Optimize this + for(int t = start; t <= realEnd; t++) + Add(t); + } + + public bool Contains(int item) + { + foreach(Tuple extent in backend) + if(item >= extent.Item1 && item <= extent.Item2) + return true; + return false; + } + + public void Clear() + { + backend.Clear(); + } + + public bool Remove(int item) + { + Tuple toRemove = null; + Tuple toAddOne = null; + Tuple toAddTwo = null; + + foreach(Tuple extent in backend) + { + // Extent is contained and not a border + if(item > extent.Item1 && item < extent.Item2) + { + toRemove = extent; + toAddOne = new Tuple(extent.Item1, item - 1); + toAddTwo = new Tuple(item + 1, extent.Item2); + break; + } + + // Extent is left border, but not only element + if(item == extent.Item1 && item != extent.Item2) + { + toRemove = extent; + toAddOne = new Tuple(item + 1, extent.Item2); + break; + } + + // Extent is right border, but not only element + if(item != extent.Item1 && item == extent.Item2) + { + toRemove = extent; + toAddOne = new Tuple(extent.Item1, item - 1); + break; + } + + // Extent is only element + if(item == extent.Item1 && item == extent.Item2) + { + toRemove = extent; + break; + } + } + + // Item not found + if(toRemove == null) + return false; + + backend.Remove(toRemove); + if(toAddOne != null) + backend.Add(toAddOne); + if(toAddTwo != null) + backend.Add(toAddTwo); + + // Sort + backend = backend.OrderBy(t => t.Item1).ToList(); + + return true; + } + + public Tuple[] ToArray() + { + return backend.ToArray(); + } + } +} diff --git a/DiscImageChef.Helpers/Extents/ExtentsLong.cs b/DiscImageChef.Helpers/Extents/ExtentsLong.cs new file mode 100644 index 000000000..dde1c4dc2 --- /dev/null +++ b/DiscImageChef.Helpers/Extents/ExtentsLong.cs @@ -0,0 +1,200 @@ +// /*************************************************************************** +// The Disc Image Chef +// ---------------------------------------------------------------------------- +// +// Filename : ExtentsLong.cs +// Author(s) : Natalia Portillo +// +// Component : Component +// +// --[ Description ] ---------------------------------------------------------- +// +// Description +// +// --[ License ] -------------------------------------------------------------- +// +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 2.1 of the +// License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, see . +// +// ---------------------------------------------------------------------------- +// Copyright © 2011-2017 Natalia Portillo +// ****************************************************************************/ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Extents +{ + public class ExtentsLong + { + List> backend; + + public ExtentsLong() + { + backend = new List>(); + } + + public int Count { get { return backend.Count; } } + + public void Add(long item) + { + Tuple removeOne = null; + Tuple removeTwo = null; + Tuple itemToAdd = null; + + for(int i = 0; i < backend.Count; i++) + { + // Already contained in an extent + if(item >= backend[i].Item1 && item <= backend[i].Item2) + return; + + // Expands existing extent start + if(item == backend[i].Item1 - 1) + { + removeOne = backend[i]; + + if(i > 0 && item == backend[i - 1].Item2 + 1) + { + removeTwo = backend[i - 1]; + itemToAdd = new Tuple(backend[i - 1].Item1, backend[i].Item2); + } + else + itemToAdd = new Tuple(item, backend[i].Item2); + + break; + } + + // Expands existing extent end + if(item == backend[i].Item2 + 1) + { + removeOne = backend[i]; + + if(i < backend.Count - 1 && item == backend[i + 1].Item1 - 1) + { + removeTwo = backend[i + 1]; + itemToAdd = new Tuple(backend[i].Item1, backend[i + 1].Item2); + } + else + itemToAdd = new Tuple(backend[i].Item1, item); + + break; + } + } + + if(itemToAdd != null) + { + backend.Remove(removeOne); + backend.Remove(removeTwo); + backend.Add(itemToAdd); + } + else + backend.Add(new Tuple(item, item)); + + // Sort + backend = backend.OrderBy(t => t.Item1).ToList(); + } + + public void Add(long start, long end) + { + Add(start, end, false); + } + + public void Add(long start, long end, bool run) + { + long realEnd; + if(run) + realEnd = start + end - 1; + else + realEnd = end; + + // TODO: Optimize this + for(long t = start; t <= realEnd; t++) + Add(t); + } + + public bool Contains(long item) + { + foreach(Tuple extent in backend) + if(item >= extent.Item1 && item <= extent.Item2) + return true; + return false; + } + + public void Clear() + { + backend.Clear(); + } + + public bool Remove(long item) + { + Tuple toRemove = null; + Tuple toAddOne = null; + Tuple toAddTwo = null; + + foreach(Tuple extent in backend) + { + // Extent is contained and not a border + if(item > extent.Item1 && item < extent.Item2) + { + toRemove = extent; + toAddOne = new Tuple(extent.Item1, item - 1); + toAddTwo = new Tuple(item + 1, extent.Item2); + break; + } + + // Extent is left border, but not only element + if(item == extent.Item1 && item != extent.Item2) + { + toRemove = extent; + toAddOne = new Tuple(item + 1, extent.Item2); + break; + } + + // Extent is right border, but not only element + if(item != extent.Item1 && item == extent.Item2) + { + toRemove = extent; + toAddOne = new Tuple(extent.Item1, item - 1); + break; + } + + // Extent is only element + if(item == extent.Item1 && item == extent.Item2) + { + toRemove = extent; + break; + } + } + + // Item not found + if(toRemove == null) + return false; + + backend.Remove(toRemove); + if(toAddOne != null) + backend.Add(toAddOne); + if(toAddTwo != null) + backend.Add(toAddTwo); + + // Sort + backend = backend.OrderBy(t => t.Item1).ToList(); + + return true; + } + + public Tuple[] ToArray() + { + return backend.ToArray(); + } + } +} diff --git a/DiscImageChef.Helpers/Extents/ExtentsSByte.cs b/DiscImageChef.Helpers/Extents/ExtentsSByte.cs new file mode 100644 index 000000000..ec1c06083 --- /dev/null +++ b/DiscImageChef.Helpers/Extents/ExtentsSByte.cs @@ -0,0 +1,200 @@ +// /*************************************************************************** +// The Disc Image Chef +// ---------------------------------------------------------------------------- +// +// Filename : ExtentsSByte.cs +// Author(s) : Natalia Portillo +// +// Component : Component +// +// --[ Description ] ---------------------------------------------------------- +// +// Description +// +// --[ License ] -------------------------------------------------------------- +// +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 2.1 of the +// License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, see . +// +// ---------------------------------------------------------------------------- +// Copyright © 2011-2017 Natalia Portillo +// ****************************************************************************/ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Extents +{ + public class ExtentsSByte + { + List> backend; + + public ExtentsSByte() + { + backend = new List>(); + } + + public int Count { get { return backend.Count; } } + + public void Add(sbyte item) + { + Tuple removeOne = null; + Tuple removeTwo = null; + Tuple itemToAdd = null; + + for(int i = 0; i < backend.Count; i++) + { + // Already contained in an extent + if(item >= backend[i].Item1 && item <= backend[i].Item2) + return; + + // Expands existing extent start + if(item == backend[i].Item1 - 1) + { + removeOne = backend[i]; + + if(i > 0 && item == backend[i - 1].Item2 + 1) + { + removeTwo = backend[i - 1]; + itemToAdd = new Tuple(backend[i - 1].Item1, backend[i].Item2); + } + else + itemToAdd = new Tuple(item, backend[i].Item2); + + break; + } + + // Expands existing extent end + if(item == backend[i].Item2 + 1) + { + removeOne = backend[i]; + + if(i < backend.Count - 1 && item == backend[i + 1].Item1 - 1) + { + removeTwo = backend[i + 1]; + itemToAdd = new Tuple(backend[i].Item1, backend[i + 1].Item2); + } + else + itemToAdd = new Tuple(backend[i].Item1, item); + + break; + } + } + + if(itemToAdd != null) + { + backend.Remove(removeOne); + backend.Remove(removeTwo); + backend.Add(itemToAdd); + } + else + backend.Add(new Tuple(item, item)); + + // Sort + backend = backend.OrderBy(t => t.Item1).ToList(); + } + + public void Add(sbyte start, sbyte end) + { + Add(start, end, false); + } + + public void Add(sbyte start, sbyte end, bool run) + { + sbyte realEnd; + if(run) + realEnd = (sbyte)(start + end - 1); + else + realEnd = end; + + // TODO: Optimize this + for(sbyte t = start; t <= realEnd; t++) + Add(t); + } + + public bool Contains(sbyte item) + { + foreach(Tuple extent in backend) + if(item >= extent.Item1 && item <= extent.Item2) + return true; + return false; + } + + public void Clear() + { + backend.Clear(); + } + + public bool Remove(sbyte item) + { + Tuple toRemove = null; + Tuple toAddOne = null; + Tuple toAddTwo = null; + + foreach(Tuple extent in backend) + { + // Extent is contained and not a border + if(item > extent.Item1 && item < extent.Item2) + { + toRemove = extent; + toAddOne = new Tuple(extent.Item1, (sbyte)(item - 1)); + toAddTwo = new Tuple((sbyte)(item + 1), extent.Item2); + break; + } + + // Extent is left border, but not only element + if(item == extent.Item1 && item != extent.Item2) + { + toRemove = extent; + toAddOne = new Tuple((sbyte)(item + 1), extent.Item2); + break; + } + + // Extent is right border, but not only element + if(item != extent.Item1 && item == extent.Item2) + { + toRemove = extent; + toAddOne = new Tuple(extent.Item1, (sbyte)(item - 1)); + break; + } + + // Extent is only element + if(item == extent.Item1 && item == extent.Item2) + { + toRemove = extent; + break; + } + } + + // Item not found + if(toRemove == null) + return false; + + backend.Remove(toRemove); + if(toAddOne != null) + backend.Add(toAddOne); + if(toAddTwo != null) + backend.Add(toAddTwo); + + // Sort + backend = backend.OrderBy(t => t.Item1).ToList(); + + return true; + } + + public Tuple[] ToArray() + { + return backend.ToArray(); + } + } +} diff --git a/DiscImageChef.Helpers/Extents/ExtentsShort.cs b/DiscImageChef.Helpers/Extents/ExtentsShort.cs new file mode 100644 index 000000000..70f9c7e78 --- /dev/null +++ b/DiscImageChef.Helpers/Extents/ExtentsShort.cs @@ -0,0 +1,200 @@ +// /*************************************************************************** +// The Disc Image Chef +// ---------------------------------------------------------------------------- +// +// Filename : ExtentsShort.cs +// Author(s) : Natalia Portillo +// +// Component : Component +// +// --[ Description ] ---------------------------------------------------------- +// +// Description +// +// --[ License ] -------------------------------------------------------------- +// +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 2.1 of the +// License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License ashort with this library; if not, see . +// +// ---------------------------------------------------------------------------- +// Copyright © 2011-2017 Natalia Portillo +// ****************************************************************************/ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Extents +{ + public class ExtentsShort + { + List> backend; + + public ExtentsShort() + { + backend = new List>(); + } + + public int Count { get { return backend.Count; } } + + public void Add(short item) + { + Tuple removeOne = null; + Tuple removeTwo = null; + Tuple itemToAdd = null; + + for(int i = 0; i < backend.Count; i++) + { + // Already contained in an extent + if(item >= backend[i].Item1 && item <= backend[i].Item2) + return; + + // Expands existing extent start + if(item == backend[i].Item1 - 1) + { + removeOne = backend[i]; + + if(i > 0 && item == backend[i - 1].Item2 + 1) + { + removeTwo = backend[i - 1]; + itemToAdd = new Tuple(backend[i - 1].Item1, backend[i].Item2); + } + else + itemToAdd = new Tuple(item, backend[i].Item2); + + break; + } + + // Expands existing extent end + if(item == backend[i].Item2 + 1) + { + removeOne = backend[i]; + + if(i < backend.Count - 1 && item == backend[i + 1].Item1 - 1) + { + removeTwo = backend[i + 1]; + itemToAdd = new Tuple(backend[i].Item1, backend[i + 1].Item2); + } + else + itemToAdd = new Tuple(backend[i].Item1, item); + + break; + } + } + + if(itemToAdd != null) + { + backend.Remove(removeOne); + backend.Remove(removeTwo); + backend.Add(itemToAdd); + } + else + backend.Add(new Tuple(item, item)); + + // Sort + backend = backend.OrderBy(t => t.Item1).ToList(); + } + + public void Add(short start, short end) + { + Add(start, end, false); + } + + public void Add(short start, short end, bool run) + { + short realEnd; + if(run) + realEnd = (short)(start + end - 1); + else + realEnd = end; + + // TODO: Optimize this + for(short t = start; t <= realEnd; t++) + Add(t); + } + + public bool Contains(short item) + { + foreach(Tuple extent in backend) + if(item >= extent.Item1 && item <= extent.Item2) + return true; + return false; + } + + public void Clear() + { + backend.Clear(); + } + + public bool Remove(short item) + { + Tuple toRemove = null; + Tuple toAddOne = null; + Tuple toAddTwo = null; + + foreach(Tuple extent in backend) + { + // Extent is contained and not a border + if(item > extent.Item1 && item < extent.Item2) + { + toRemove = extent; + toAddOne = new Tuple(extent.Item1, (short)(item - 1)); + toAddTwo = new Tuple((short)(item + 1), extent.Item2); + break; + } + + // Extent is left border, but not only element + if(item == extent.Item1 && item != extent.Item2) + { + toRemove = extent; + toAddOne = new Tuple((short)(item + 1), extent.Item2); + break; + } + + // Extent is right border, but not only element + if(item != extent.Item1 && item == extent.Item2) + { + toRemove = extent; + toAddOne = new Tuple(extent.Item1, (short)(item - 1)); + break; + } + + // Extent is only element + if(item == extent.Item1 && item == extent.Item2) + { + toRemove = extent; + break; + } + } + + // Item not found + if(toRemove == null) + return false; + + backend.Remove(toRemove); + if(toAddOne != null) + backend.Add(toAddOne); + if(toAddTwo != null) + backend.Add(toAddTwo); + + // Sort + backend = backend.OrderBy(t => t.Item1).ToList(); + + return true; + } + + public Tuple[] ToArray() + { + return backend.ToArray(); + } + } +} diff --git a/DiscImageChef.Helpers/Extents/ExtentsUInt.cs b/DiscImageChef.Helpers/Extents/ExtentsUInt.cs new file mode 100644 index 000000000..a91ef9ad1 --- /dev/null +++ b/DiscImageChef.Helpers/Extents/ExtentsUInt.cs @@ -0,0 +1,200 @@ +// /*************************************************************************** +// The Disc Image Chef +// ---------------------------------------------------------------------------- +// +// Filename : ExtentsUInt.cs +// Author(s) : Natalia Portillo +// +// Component : Component +// +// --[ Description ] ---------------------------------------------------------- +// +// Description +// +// --[ License ] -------------------------------------------------------------- +// +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 2.1 of the +// License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License auint with this library; if not, see . +// +// ---------------------------------------------------------------------------- +// Copyright © 2011-2017 Natalia Portillo +// ****************************************************************************/ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Extents +{ + public class ExtentsUInt + { + List> backend; + + public ExtentsUInt() + { + backend = new List>(); + } + + public int Count { get { return backend.Count; } } + + public void Add(uint item) + { + Tuple removeOne = null; + Tuple removeTwo = null; + Tuple itemToAdd = null; + + for(int i = 0; i < backend.Count; i++) + { + // Already contained in an extent + if(item >= backend[i].Item1 && item <= backend[i].Item2) + return; + + // Expands existing extent start + if(item == backend[i].Item1 - 1) + { + removeOne = backend[i]; + + if(i > 0 && item == backend[i - 1].Item2 + 1) + { + removeTwo = backend[i - 1]; + itemToAdd = new Tuple(backend[i - 1].Item1, backend[i].Item2); + } + else + itemToAdd = new Tuple(item, backend[i].Item2); + + break; + } + + // Expands existing extent end + if(item == backend[i].Item2 + 1) + { + removeOne = backend[i]; + + if(i < backend.Count - 1 && item == backend[i + 1].Item1 - 1) + { + removeTwo = backend[i + 1]; + itemToAdd = new Tuple(backend[i].Item1, backend[i + 1].Item2); + } + else + itemToAdd = new Tuple(backend[i].Item1, item); + + break; + } + } + + if(itemToAdd != null) + { + backend.Remove(removeOne); + backend.Remove(removeTwo); + backend.Add(itemToAdd); + } + else + backend.Add(new Tuple(item, item)); + + // Sort + backend = backend.OrderBy(t => t.Item1).ToList(); + } + + public void Add(uint start, uint end) + { + Add(start, end, false); + } + + public void Add(uint start, uint end, bool run) + { + uint realEnd; + if(run) + realEnd = start + end - 1; + else + realEnd = end; + + // TODO: Optimize this + for(uint t = start; t <= realEnd; t++) + Add(t); + } + + public bool Contains(uint item) + { + foreach(Tuple extent in backend) + if(item >= extent.Item1 && item <= extent.Item2) + return true; + return false; + } + + public void Clear() + { + backend.Clear(); + } + + public bool Remove(uint item) + { + Tuple toRemove = null; + Tuple toAddOne = null; + Tuple toAddTwo = null; + + foreach(Tuple extent in backend) + { + // Extent is contained and not a border + if(item > extent.Item1 && item < extent.Item2) + { + toRemove = extent; + toAddOne = new Tuple(extent.Item1, item - 1); + toAddTwo = new Tuple(item + 1, extent.Item2); + break; + } + + // Extent is left border, but not only element + if(item == extent.Item1 && item != extent.Item2) + { + toRemove = extent; + toAddOne = new Tuple(item + 1, extent.Item2); + break; + } + + // Extent is right border, but not only element + if(item != extent.Item1 && item == extent.Item2) + { + toRemove = extent; + toAddOne = new Tuple(extent.Item1, item - 1); + break; + } + + // Extent is only element + if(item == extent.Item1 && item == extent.Item2) + { + toRemove = extent; + break; + } + } + + // Item not found + if(toRemove == null) + return false; + + backend.Remove(toRemove); + if(toAddOne != null) + backend.Add(toAddOne); + if(toAddTwo != null) + backend.Add(toAddTwo); + + // Sort + backend = backend.OrderBy(t => t.Item1).ToList(); + + return true; + } + + public Tuple[] ToArray() + { + return backend.ToArray(); + } + } +} diff --git a/DiscImageChef.Helpers/Extents/ExtentsULong.cs b/DiscImageChef.Helpers/Extents/ExtentsULong.cs new file mode 100644 index 000000000..95d0051da --- /dev/null +++ b/DiscImageChef.Helpers/Extents/ExtentsULong.cs @@ -0,0 +1,200 @@ +// /*************************************************************************** +// The Disc Image Chef +// ---------------------------------------------------------------------------- +// +// Filename : ExtentsULong.cs +// Author(s) : Natalia Portillo +// +// Component : Component +// +// --[ Description ] ---------------------------------------------------------- +// +// Description +// +// --[ License ] -------------------------------------------------------------- +// +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 2.1 of the +// License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License aulong with this library; if not, see . +// +// ---------------------------------------------------------------------------- +// Copyright © 2011-2017 Natalia Portillo +// ****************************************************************************/ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Extents +{ + public class ExtentsULong + { + List> backend; + + public ExtentsULong() + { + backend = new List>(); + } + + public int Count { get { return backend.Count; } } + + public void Add(ulong item) + { + Tuple removeOne = null; + Tuple removeTwo = null; + Tuple itemToAdd = null; + + for(int i = 0; i < backend.Count; i++) + { + // Already contained in an extent + if(item >= backend[i].Item1 && item <= backend[i].Item2) + return; + + // Expands existing extent start + if(item == backend[i].Item1 - 1) + { + removeOne = backend[i]; + + if(i > 0 && item == backend[i - 1].Item2 + 1) + { + removeTwo = backend[i - 1]; + itemToAdd = new Tuple(backend[i - 1].Item1, backend[i].Item2); + } + else + itemToAdd = new Tuple(item, backend[i].Item2); + + break; + } + + // Expands existing extent end + if(item == backend[i].Item2 + 1) + { + removeOne = backend[i]; + + if(i < backend.Count - 1 && item == backend[i + 1].Item1 - 1) + { + removeTwo = backend[i + 1]; + itemToAdd = new Tuple(backend[i].Item1, backend[i + 1].Item2); + } + else + itemToAdd = new Tuple(backend[i].Item1, item); + + break; + } + } + + if(itemToAdd != null) + { + backend.Remove(removeOne); + backend.Remove(removeTwo); + backend.Add(itemToAdd); + } + else + backend.Add(new Tuple(item, item)); + + // Sort + backend = backend.OrderBy(t => t.Item1).ToList(); + } + + public void Add(ulong start, ulong end) + { + Add(start, end, false); + } + + public void Add(ulong start, ulong end, bool run) + { + ulong realEnd; + if(run) + realEnd = start + end - 1; + else + realEnd = end; + + // TODO: Optimize this + for(ulong t = start; t <= realEnd; t++) + Add(t); + } + + public bool Contains(ulong item) + { + foreach(Tuple extent in backend) + if(item >= extent.Item1 && item <= extent.Item2) + return true; + return false; + } + + public void Clear() + { + backend.Clear(); + } + + public bool Remove(ulong item) + { + Tuple toRemove = null; + Tuple toAddOne = null; + Tuple toAddTwo = null; + + foreach(Tuple extent in backend) + { + // Extent is contained and not a border + if(item > extent.Item1 && item < extent.Item2) + { + toRemove = extent; + toAddOne = new Tuple(extent.Item1, item - 1); + toAddTwo = new Tuple(item + 1, extent.Item2); + break; + } + + // Extent is left border, but not only element + if(item == extent.Item1 && item != extent.Item2) + { + toRemove = extent; + toAddOne = new Tuple(item + 1, extent.Item2); + break; + } + + // Extent is right border, but not only element + if(item != extent.Item1 && item == extent.Item2) + { + toRemove = extent; + toAddOne = new Tuple(extent.Item1, item - 1); + break; + } + + // Extent is only element + if(item == extent.Item1 && item == extent.Item2) + { + toRemove = extent; + break; + } + } + + // Item not found + if(toRemove == null) + return false; + + backend.Remove(toRemove); + if(toAddOne != null) + backend.Add(toAddOne); + if(toAddTwo != null) + backend.Add(toAddTwo); + + // Sort + backend = backend.OrderBy(t => t.Item1).ToList(); + + return true; + } + + public Tuple[] ToArray() + { + return backend.ToArray(); + } + } +} diff --git a/DiscImageChef.Helpers/Extents/ExtentsUShort.cs b/DiscImageChef.Helpers/Extents/ExtentsUShort.cs new file mode 100644 index 000000000..3950aaa3c --- /dev/null +++ b/DiscImageChef.Helpers/Extents/ExtentsUShort.cs @@ -0,0 +1,200 @@ +// /*************************************************************************** +// The Disc Image Chef +// ---------------------------------------------------------------------------- +// +// Filename : ExtentsUShort.cs +// Author(s) : Natalia Portillo +// +// Component : Component +// +// --[ Description ] ---------------------------------------------------------- +// +// Description +// +// --[ License ] -------------------------------------------------------------- +// +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 2.1 of the +// License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License aushort with this library; if not, see . +// +// ---------------------------------------------------------------------------- +// Copyright © 2011-2017 Natalia Portillo +// ****************************************************************************/ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Extents +{ + public class ExtentsUShort + { + List> backend; + + public ExtentsUShort() + { + backend = new List>(); + } + + public int Count { get { return backend.Count; } } + + public void Add(ushort item) + { + Tuple removeOne = null; + Tuple removeTwo = null; + Tuple itemToAdd = null; + + for(int i = 0; i < backend.Count; i++) + { + // Already contained in an extent + if(item >= backend[i].Item1 && item <= backend[i].Item2) + return; + + // Expands existing extent start + if(item == backend[i].Item1 - 1) + { + removeOne = backend[i]; + + if(i > 0 && item == backend[i - 1].Item2 + 1) + { + removeTwo = backend[i - 1]; + itemToAdd = new Tuple(backend[i - 1].Item1, backend[i].Item2); + } + else + itemToAdd = new Tuple(item, backend[i].Item2); + + break; + } + + // Expands existing extent end + if(item == backend[i].Item2 + 1) + { + removeOne = backend[i]; + + if(i < backend.Count - 1 && item == backend[i + 1].Item1 - 1) + { + removeTwo = backend[i + 1]; + itemToAdd = new Tuple(backend[i].Item1, backend[i + 1].Item2); + } + else + itemToAdd = new Tuple(backend[i].Item1, item); + + break; + } + } + + if(itemToAdd != null) + { + backend.Remove(removeOne); + backend.Remove(removeTwo); + backend.Add(itemToAdd); + } + else + backend.Add(new Tuple(item, item)); + + // Sort + backend = backend.OrderBy(t => t.Item1).ToList(); + } + + public void Add(ushort start, ushort end) + { + Add(start, end, false); + } + + public void Add(ushort start, ushort end, bool run) + { + ushort realEnd; + if(run) + realEnd = (ushort)(start + end - 1); + else + realEnd = end; + + // TODO: Optimize this + for(ushort t = start; t <= realEnd; t++) + Add(t); + } + + public bool Contains(ushort item) + { + foreach(Tuple extent in backend) + if(item >= extent.Item1 && item <= extent.Item2) + return true; + return false; + } + + public void Clear() + { + backend.Clear(); + } + + public bool Remove(ushort item) + { + Tuple toRemove = null; + Tuple toAddOne = null; + Tuple toAddTwo = null; + + foreach(Tuple extent in backend) + { + // Extent is contained and not a border + if(item > extent.Item1 && item < extent.Item2) + { + toRemove = extent; + toAddOne = new Tuple(extent.Item1, (ushort)(item - 1)); + toAddTwo = new Tuple((ushort)(item + 1), extent.Item2); + break; + } + + // Extent is left border, but not only element + if(item == extent.Item1 && item != extent.Item2) + { + toRemove = extent; + toAddOne = new Tuple((ushort)(item + 1), extent.Item2); + break; + } + + // Extent is right border, but not only element + if(item != extent.Item1 && item == extent.Item2) + { + toRemove = extent; + toAddOne = new Tuple(extent.Item1, (ushort)(item - 1)); + break; + } + + // Extent is only element + if(item == extent.Item1 && item == extent.Item2) + { + toRemove = extent; + break; + } + } + + // Item not found + if(toRemove == null) + return false; + + backend.Remove(toRemove); + if(toAddOne != null) + backend.Add(toAddOne); + if(toAddTwo != null) + backend.Add(toAddTwo); + + // Sort + backend = backend.OrderBy(t => t.Item1).ToList(); + + return true; + } + + public Tuple[] ToArray() + { + return backend.ToArray(); + } + } +}