//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\ // MemoryMapper2.cs 15-Oct-18/\\//\\//\\// //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\ // Split from MM v4.8.2.80 15-Oct\//\\//\\// //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\ // Copied in and altered to read/write // downward towards zero from the offset // instead of upward from offset to EoF. // v4.8.2.81 Designed & Written, Evo in // Testing & RetroSpection. TestsWell! // v4.9.3.87 14-Nov-2018 Kernals Splitout. // Favorites and Removals Modifications // ReDesigned with Separate flow to do // Removals from PrintBlaster, with MyEditor // running &&&, not-running it appends them // to removals.sme and MyEditor then checks // the file next run & handles any backlog. // v4.9.4.88 19-Nov-2018 -JpE-//\\//\\//\\// // v5.0.6.00 21-Feb-19 List to Collection //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\ using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.IO; using System.IO.MemoryMappedFiles; using System.Linq; using System.Text; using System.Threading; using System.Windows.Forms; using MCR = MyCustomLibrary.Properties.Resources; namespace MyCustomLibrary { public static partial class MemoryMapper { #region Kernals for MemoryMapper.cs methods #region Read/Write Bytes Kernals #region Read Bytes Kernal private static Collection ReadBytesKernal(string path, string name, long size, bool read, long offs, long view, bool shred) { var j = size < 1; var z = File.Exists(path); if (j && z) size = GetSize(path); if (j &&!z) size = 1; var bytes = new Collection(); using (var m = MemoryMappedFile.CreateFromFile( path, FileMode.OpenOrCreate, name, size)) { if (!read) return bytes;// <-= Created Only. var position = offs; using (var reader = m.CreateViewAccessor(offs, view, // REM: View itself now ^ offset. ^ MemoryMappedFileAccess.ReadWrite)) { if (view == 0) view = size; while (position <= view && position < size - offs) { byte flag; // vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv try{flag=reader.ReadByte(position++);} catch (ArgumentException) { break; } // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bytes.Add(flag); } if (shred) { var used = position; position = 0; while(position <= used && position < (size - offs) && position <= view) { reader.Write(position, (ushort) 0); position += 2; } } } } return bytes; } private static long GetSize(string path) { var s = new FileInfo(path); return Convert.ToInt64(s.Length); } #endregion Read Bytes Kernal //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\// #region Write Bytes Kernal private static bool WriteBytesKernal( string path, string name, long size, long offset, long view, object arg) { var bytes = GetBytes(arg); if (bytes == null || bytes.Count < 1) return false; if(size<1)size=offset+bytes.Count; using (var t = MemoryMappedFile .CreateFromFile(path, FileMode .OpenOrCreate, name, size)) { using (var writer = t.CreateViewAccessor(offset, view, MemoryMappedFileAccess.Write)) { foreach (var bite in bytes) { byte data; try {data = Convert.ToByte(bite);} catch (FormatException){continue;} catch (InvalidCastException) { continue; } //\\ vvvvvvvvvvvvvvvvvvvvvvvvvvvv try{writer.Write(offset++, data);} //\\ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ catch(ArgumentException) { return false; } } } } return true; } private static Collection GetBytes(object arg) { Collection bites; try{bites = arg as Collection; } catch (InvalidCastException) {try{bites= (Collection) arg; } catch (InvalidCastException) { bites = new Collection{1}; } } return bites; } #endregion Write Bytes Kernal //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\// #endregion Read/Write Bytes Kernals //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\// #region Read/Write Long Kernals #region Read Long Kernals private static Collection ReadInt64Kernal(long s, string h, string t, bool r, long o, long v, bool b) { var c = new Collection(); var z = s == 0; var w = File.Exists(h); if (z && w) s = GetSize(h); if (z &&!w) s = 8L; using ( var f = MemoryMappedFile.CreateFromFile( h, FileMode.OpenOrCreate, t, s)) { if (!r) return c;// Create File Only. using (var m = f. CreateViewAccessor(o, v, MemoryMappedFileAccess.ReadWrite)) { var y = 0L + o;// position+offset. if (v == 0) v = s; #region View^ = itself now Offset. // rem view is offset, so it's all // relative inside the 2nd using, // starts at pos-0 & ends at view. // (The v variable here.) period^. #endregion while (y < v-7 && y < s-o-7) { long n; //\\//\\ vvvvvvvvvvvvvvvvv try{ n = m.ReadInt64(y); }// <-= //\\//\\ ^^^^^^^^^^^^^^^^^ catch(ArgumentException){break;} y += 8L; c.Add(n); } if (b) { var u = y; y = 0; while (y <= u // Blank bytes used. && y < s-o && y <= v) { m.Write(y, (ushort) 0); y += 2; } } } } return c; } #endregion Read Long Kernal //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\// #region Write Long Kernal private static bool WriteLongKernal( object arg, long s, string h, string n, long o, long v) { Collection l; var j = CalcSize64(arg, out l); if (s < 1 || s < j) s = j; if (s < 1 || l.Count < 1) return false; var p = 0L; // (v)iew will be offset. using (var fi = MemoryMappedFile.CreateFromFile( h, FileMode.OpenOrCreate, n, s)) { using (var wi = fi.CreateViewAccessor( o, v, MemoryMappedFileAccess.Write)) { var xx = 0; if (v == 0) v = s-o; while (p < v-7 && p < s-o-7) { if (xx > l.Count-1) break; var i = l[xx++]; try { wi.Write(p, i); }// <-==<< catch(ArgumentException){break;} p += 8L; } } } // long is 8 ^ bytes each. return p == j; } private static long CalcSize64( object arg, out Collection l) { var size = 0L; l = new Collection(); try { l = arg as Collection; if (l != null){ size = l.Count; } } catch(InvalidCastException){return 0L;} // Basically returns a ref to l. if (l != null) size *= 8;// 8 bytes ea. else size = 0L; return size; } #endregion Write Long Kernals //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\// #endregion Read Write Long Kernals //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\// #region Read/Write Strings Kernals #region Read Strings Kernal private static Collection ReadStringsKernal(string path, long size, long offs, string name, bool read, long view, bool shred) { var pos = 0L; var input = new Collection(); var t = File.Exists(path); var s = size == 0L; if (s && t) size = GetSize(path); if (s && !t) size = offs + 2048L; using (var mmf = MemoryMappedFile .CreateFromFile(path, FileMode .OpenOrCreate, name, size)) { if (!read) return null; using (var rdr = mmf.CreateViewAccessor(offs, view, MemoryMappedFileAccess.ReadWrite)) { // ^ REM ^ Accessor itself is now offset. if (view == 0) view = size - offs; while (pos <= view && pos < size - offs) { var len = rdr.ReadUInt16(pos); if ( len < 1) break; // That's it! var buff = new byte[len]; rdr.ReadArray(pos+=2,buff,0,len); pos += len; // reposition rdr. var str = Encoding .Unicode.GetString(buff); if (string.IsNullOrEmpty(str)) break; input.Add(str); } if (shred) // Shred only bytes used. { var used = pos; pos = 0; while (pos <= used && pos < size - offs && pos <= view) { rdr.Write(pos, (ushort) 0); pos += 2; } } } } return input; } #endregion Read Strings Kernal //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\// #region Write Strings Kernal private static bool WriteStringsKernal( string file, string name, long size, long offs, long view, IEnumerable strings) { var pos = 0L; var is1 = false; try { using (var f = MemoryMappedFile .CreateFromFile(file, FileMode.OpenOrCreate, name, size)) { using (var w = f.CreateViewAccessor( offs, view, MemoryMappedFileAccess.Write)) { // ^v View is already offset. if (view == 0) view = size - offs; foreach (var str in strings) { if (string.IsNullOrEmpty(str) || str.Length > view - pos || str.Length > size - offs - pos || str.Length > 1073741824) continue; // 1g Max w/byte ^ arrays. var buf = Encoding.Unicode.GetBytes(str); long len = buf.Length; if (len < 1) break; is1 = true; w.Write(pos, (ushort) len); w.WriteArray( pos += 2, buf, 0, (int) len); pos += len; } } } } catch (ArgumentOutOfRangeException) { return false; } return is1; } #endregion Write Strings Kernal //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\// #endregion Read/Write Strings Kernals //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\// #endregion Kernals //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\// #region Reversed Clones private static readonly Mutex Mux1 = new Mutex(false, "Mux1"); private static readonly Mutex Mux2 = new Mutex(false, "Mux2"); private static readonly Mutex Mux3 = new Mutex(false, "Mux3"); #region Reverse Read/Write List // Hacked to reverse order and // read downward from offset towards 0L // or first zero value whichever comes first. // v4.8.2.81 20-Oct-2018 public static Collection ReverseReadBytes(object[] args) { Mux1.WaitOne(); const string t = "Reverse Read Bytes"; long size, offs, lnth; // Number of Bytes ^ to read. if (args == null || args.Length < 6) throw new ArgumentException(t); bool read, dele; string path, name; try // now unbox args. { path =args[0].ToString();//[0]); size = Convert.ToInt64(args[1]); offs = Convert.ToInt64(args[2]); lnth = Convert.ToInt64(args[3]);// <-= NOTE read=Convert.ToBoolean(args[4]); name=args[5].ToString(); //[5]); dele=Convert.ToBoolean(args[6]); } catch (InvalidCastException) { throw new InvalidCastException(t); } catch (FormatException) { throw new FormatException(t); } #region Memory Mapping var j = size < 1; var z = File.Exists(path); if (j && z) size = GetSize(path); if (j &&!z || size < 1 || offs == 0) size = 1; var bytes = new Collection(); using (var m = MemoryMappedFile.CreateFromFile( path, FileMode.OpenOrCreate, name, size)) { if (!read) return bytes;// <-= Created Only. using (var reader = m.CreateViewAccessor( 0L, offs+1, MemoryMappedFileAccess.Read)) { for (var i = 0; i < lnth; ++i) { byte flag; try{flag=reader.ReadByte(offs--);} catch (ArgumentException){ break; } if (offs < 0) break; bytes.Add(flag); } } } if (dele && File.Exists(path)) File.Delete(path); else if (File.Exists(path)) File.SetLastAccessTime(path, DateTime.Now); #endregion Mux1.ReleaseMutex(); return bytes; } public static bool ReverseWriteBytes(object[] args) { Mux1.WaitOne(); if (args == null || !args.Any()) throw new ArgumentException("Reverse Write Bytes"); string path, name; long size, offset; try { path = args[0].ToString(); } catch (FormatException) { path = Convert.ToString(args[0]); } try { size =(Convert.ToInt64(args[1]));} catch (InvalidCastException){size= 1;} try { offset =Convert.ToInt64(args[2]);} catch (FormatException) { Mux1.ReleaseMutex(); return false; } catch(InvalidCastException) { Mux1.ReleaseMutex(); return false; } try { name = args[5].ToString(); } catch(InvalidCastException){name="mux";} catch(FormatException) { name = "mux"; } var bytes = GetBytes(args[3]); if (bytes == null || bytes.Count < 1) { Mux1.ReleaseMutex(); return false; } #region Memory Mapping // Altered to write downward instead of upward. if (size < 1) size = bytes.Count; if (size < 1 || offset +1 > size || offset < 0) { Mux1.ReleaseMutex(); return false; } using (var t = MemoryMappedFile .CreateFromFile(path, FileMode .OpenOrCreate, name, size)) { using (var writer = t.CreateViewAccessor( 0L, offset+1, MemoryMappedFileAccess.Write)) { foreach (var bite in bytes){ byte data; try { data = Convert.ToByte(bite);} catch (FormatException) { continue; } catch (InvalidCastException) { continue; } try { writer.Write(offset--, data); } catch(ArgumentException) { Mux1.ReleaseMutex(); return false; } if (offset < 0) break; } } } var time = DateTime.Now; File.SetLastWriteTime( path, time); File.SetLastAccessTime(path, time); #endregion Mux1.ReleaseMutex(); return true; } #endregion //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\// // todo: Develop the below only as needed. #region Reverse Read/Write List public static Collection ReverseReadInt64(object[] args) { Mux2.WaitOne(); // todos as needed. // pre testscode if (args == null || args.Length <1) return null; var str = (from string s in args where !string.IsNullOrEmpty(s) select s) .Aggregate("args are:\n------", (current, s) => current + (s + "\n")); MessageBox.Show(str); Mux2.ReleaseMutex(); return new Collection{1};// <-= testscode } public static bool ReverseWriteInt64(object[] args) { Mux2.WaitOne(); // todos as needed. // pre testscode if (args == null || args.Length <1) return false; var str = (from string s in args where !string.IsNullOrEmpty(s) select s) .Aggregate("args are:\n------", (current, s) => current + (s + "\n")); MessageBox.Show(str); Mux2.ReleaseMutex(); return true; } #endregion //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\// #region Reverse Read/Write Collection public static Collection ReverseReadStrings(object[] args) { Mux3.WaitOne(); // todos as needed. // pre testscode if (args == null || args.Length <1) return null; var str = (from string s in args where !string.IsNullOrEmpty(s) select s) .Aggregate("args are:\n------", (current, s) => current + (s + "\n")); MessageBox.Show(str); Mux3.ReleaseMutex(); return new Collection{"fubar"}; } public static bool ReverseWriteStrings(object[] args) { Mux3.WaitOne(); // pre testscode if (args == null || args.Length <1) return false; var test = args[0].ToString(); // todos as needed. MessageBox.Show(test); Mux3.ReleaseMutex(); return true; } #endregion //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\// #endregion Reversed Clones //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\// } }