GlobalAccessSoftware icon

MemoryMapper1.cs Class Update.

GlobalAccessSoftware | PRO | 03/23/19 11:02:38 AM UTC | 0 ⭐ | 742 👁️ | Never ⏰ | []
C# |

13.47 KB

|

None

|

0 👍

/

0 👎

//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//
// MemoryMapper1.cs 15-May-18//\\//\\//\\
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//
// v4.4.5.53 Mapped in to Lock Out//\\//\\
// v4.4.5.53 Split from PrintForm2\\//\\//
// v4.4.6.54 mm2 & mm3 transition //\\//\\
// Obsoletes mmf2 and mmf3 stuff. \\//\\//
// (c) John P. Edwards 20-May-2018//\\//\\
// v4.5.6.54 name & path/no-path mech/\\//
// Mapped in to Lock Out, extended//\\//\\
// v4.5.7.54neatobeto! All Dialed in!/\\//
// v4.5.7.56nights Brings in Strings!\//\\
// v4.5.7.56nighttime perfects class//\\//
// v4.5.7.56nightvision has Auto-Size!//\\
// v4.5.7.57 Auto-Size & args[6] Delete!//
// v4.5.7.57 Perfects Int64 Handling. Fini
// v4.5.7.58 Polished & Welltested. Jun-28
// v4.5.8.60 Revised For: Int64 lengths.
// v4.5.9.63 Final Integrations. 15-Aug
// v4.6.9.64 26-Aug-2018 Added omitted
// locking on the rest of the methods.oop
// 29-Aug-2018 Clarifies Resource Access:
// v4.6.9.65 Replaced Lock w/ Mutex 4 IPC!
// v4.6.9.67 08-Sep-2018 Mutex Properties.
// v4.8.1.78 06-Oct-2018 LastAccess Time.
// v4.9.3.87 15-Nov-2018 Favorites Mods.
// v4.9.4.89 20-Nov-2018 Ironing & Polish.
// v5.0.6.00 21-Feb-2019 Updated all:
// List<T> to Collection<T>
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
 
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Threading;
 
using MCR =
  MyCustomLibrary.Properties.Resources;
 
namespace MyCustomLibrary
{
  public static partial class MemoryMapper
  {
    private static readonly Mutex
      Mtx1 = new Mutex(false, MCR.M1);
 
    private static readonly Mutex
      Mtx2 = new Mutex(false, MCR.M2);
 
    private static readonly Mutex
      Mtx3 = new Mutex(false, MCR.M3);
 
    #region Doc
    // mmf = Memory Mapped File(s) Arguments
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    // args[0] = Full Path to mmf.
    // args[1] = Size of file in bytes,
    // args[2] = Start @ Byte (offset)
    // args[3] = What to write? (OR Shred? T/F)
    // args[4] = true; Read?
    // args[5] = this mapping's name.
    // args[6] = true; Delete after Read?
    // args[7] = View Length from Offset.
    // (if Given) Not Required, either way.8
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    #endregion
 
 
#region MemoryMapper Class: Common Code.
 
    private static void Writer(string path)
    {
      using (new Mutex(false, "Writer"))
      {
        var time = DateTime.Now;
        File.SetLastWriteTime(path, time);
        File.SetLastAccessTime(path, time);
      }
    }
 
    private static void EndGame(
      bool del, string path)
    {
      using (new Mutex(false, "EndGame"))
      {
        if (del && File.Exists(path))
          File.Delete(path);
        else if (File.Exists(path))
          File.SetLastAccessTime(
            path, DateTime.Now);
      }
    }
#endregion Common Code
    //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
 
 
#region Memory Mapped Files: Read & Write Bytes
 
    // Reads a List of Bytes from mmf.
    // v4.5.7.56 04-Jun-2018 for ReUseAbility.
    public static Collection<byte>
      ReadBytes(object[] args)
    {
      Mtx1.WaitOne();
      const string t = "Read Bytes";
      long size, offs, view = 0;
      if (args == null || args.Length < 7)
        throw new ArgumentException(t);
      bool read, dele, shred;
      string path, name;
      try // now unbox args.
      { path =args[0].ToString();//[0]);
        size = Convert.ToInt64(args[1]);
        offs = Convert.ToInt64(args[2]);
        try { shred =
          Convert.ToBoolean(   args[3]);}
        catch(FormatException){shred=false;}
        catch(InvalidCastException){shred=false;}
        read=Convert.ToBoolean(args[4]);
        name=args[5].ToString(); //[5]);
        dele=Convert.ToBoolean(args[6]);
        if (args.Length > 7)// args[7]);
        { try { view = Convert.ToInt64(args[7]); }
          catch (FormatException)    { view = 0; }
          catch(InvalidCastException){ view = 0;}}
      } catch (InvalidCastException)
        { throw new InvalidCastException(t); }
      catch (FormatException)
      { throw new FormatException(t); }
      var bites = ReadBytesKernal(path, name,
        size, read, offs, view, shred);
      EndGame(dele, path);
      Mtx1.ReleaseMutex();
      return bites;
    }
 
    /********************************************
     * Self Contained Instance-N ^v Methods:    *
     * ThreadFileSafe Useable by any instance.  *
     * so long as the file varies or such.-JpE- *
     ********************************************/
    public static bool WriteBytes(object[] args)
    {
      Mtx1.WaitOne();
      if(args==null||args.Length < 7) throw new
        ArgumentException("Write Bytes");
      string path,name;long size,offset,view = 0;
      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)
      { Mtx1.ReleaseMutex(); return false; }
      catch(InvalidCastException)
      { Mtx1.ReleaseMutex(); return false; }
      try { name = args[5].ToString(); }
      catch(InvalidCastException){name="mmf";}
      catch(FormatException) { name = "mmf"; }
      if (args.Length > 7)
      { try { view = Convert.ToInt64(args[7]); }
        catch (FormatException) { view = 0; }
        catch (InvalidCastException) { view = 0L; }
        catch(OverflowException) { view = 0; } }
      if (!WriteBytesKernal(path, name, size,
        offset, view, args[3]))
      { Mtx1.ReleaseMutex();
        return false; }
      Writer(path);
      Mtx1.ReleaseMutex();
      return true;
    }
#endregion Read/Write Bytes
    //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
 
 
#region Mmf: Int64 Words @ 8 bytes each.
 
    /// <summary> Server-Side Code
    /// Generic enough to reuse from
    /// either side, just watch for,
    /// like, file already open errors.
    /// Updated to return Generic List
    /// v4.5.7.56 04-May-2018 -JpE-
    /// NOTE: args[3] is now a List
    /// of Long Integers. Adds Reuseability.
    /// v4.6.9.65 29-Aug-2018 Mutex'd
    /// </summary>
    /// <param name="array"></param>
    /// <returns></returns>
    public static Collection<long>
      ReadInt64(object[] array)
    {
      Mtx2.WaitOne();
      if (array == null || array[2] == null
        || array.Length < 7) throw new
          ArgumentException("Read Int64");
      string t, h; 
      long s, o, v = 0L;
      bool r, d, b;
      var c = new Collection<long>();
      try{h =array[0].ToString();//[0]);
        s = Convert.ToInt64(  array[1]);
        o = Convert.ToInt64(  array[2]);
        try { b =
          Convert.ToBoolean(  array[3]); }
        catch (FormatException) { b = false;}
        catch(InvalidCastException){b=false;}
        r = Convert.ToBoolean(array[4]);
        t = array[5].ToString(); //[5]);
        d = Convert.ToBoolean(array[6]);
        if (array.Length > 7)
          v = Convert.ToInt64(array[7]); }
      catch (InvalidCastException)
      { Mtx2.ReleaseMutex(); return c; }
      catch (FormatException)
      { Mtx2.ReleaseMutex(); return c; }
      c = ReadInt64Kernal(s, h, t, r, o, v, b);
      if (!r) { Mtx1.ReleaseMutex();
        return c; }
      EndGame(d, h);
      Mtx2.ReleaseMutex();
      return c;
    }
 
    /// <summary> Client-Side Code
    /// v4.5.6.54nab 20-May-2018
    /// Generic enough to reuse from
    /// either side, just watch for,
    /// like, file already open errors in IO.
    /// v4.5.7.54 25-May-2018 Int64 @ 8 bytes ea.
    /// v4.5.7.56 04-Jun args[3] is now
    /// a List of Int64 = Long values.
    /// </summary>
    /// <param name="args"></param>
    public static bool
      WriteInt64(object[] args)
    {
      Mtx2.WaitOne();
      try { if (args == null
        ||  args[2]  == null
        ||  args.Length < 7
        || !args.Any()) return false; }
      catch(ArgumentException){return false;}
      const long k = 0L;
      const string m = "mm3";
      long  s, o, v = 0L; string n, h;
      try { h = args[0].ToString(); }
      catch (FormatException) { h = ""; }
      try { s = Convert.ToInt64(args[1]); }
      catch (InvalidCastException) { s = k; }
      catch (FormatException) { s = k; }
      try { o = Convert.ToInt64(args[2]); }
      catch (InvalidCastException){ o = 0L; }
      catch (FormatException) { o = 0L; }
      try { n = args[5].ToString(); }
      catch (FormatException) { n = m; }
      catch (InvalidCastException) { n = m; }
      if (args.Length > 7)
      { try { v = Convert.ToInt64(args[7]); }
        catch (FormatException) { v = 0; }
        catch (InvalidCastException){v = 0;}
        catch (OverflowException){v = 0; } }
      if (!WriteLongKernal(
        args[3], s, h, n, o, v))
      { Mtx2.ReleaseMutex();
        return false; }
      Writer(h);
      Mtx2.ReleaseMutex();
      return true;
    }
#endregion Mmf: Int64 Words @ 8 bytes each.
    //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
 
 
#region Read/Write Strings
 
    /// <summary> Read in List of strings.
    /// -JpE- v4.5.7.56 01-Jun-18 (from Mmf ^)
    /// SEE DOC ABOVE FOR REQUIRED ARG VALUES.
    /// Returns a List of string references.
    /// If size arg is 0, it calculates j.i.t.
    /// args[6], the 7th element now contains
    /// a bool for delete file when finished. T/F
    /// v4.9.3.86 Added the 8th element:
    /// View Length. November 11th, 2018 -JpE-
    /// </summary>
    /// <param name="args"></param>
    /// <returns></returns>
    public static Collection<string>
      ReadStrings(object[] args)
    {
      Mtx3.WaitOne();
      if (args == null || args.Length < 7
        || string.IsNullOrEmpty(
          args[0].ToString()))
      { Mtx3.ReleaseMutex(); return null; }
      string path, name;
      long size, offs, view = 0L;
      bool read, del, shred = false;
      try{path = args[0].ToString();//0]);
        size =   Convert.ToInt64(args[1]);
        offs =   Convert.ToInt64(args[2]);
        //  Only used for Writes args[3]); BUT...
        read = Convert.ToBoolean(args[4]);
        name = args[5].ToString(); //[5]);
        del  = Convert.ToBoolean(args[6]);
        if (args.Length > 7)
          view = Convert.ToInt64(args[7]);
        try // v Reused here as a Special Case.
        { if (args[3] != null) shred =
            Convert.ToBoolean(args[3]); }
        catch (FormatException) {   shred=false; }
        catch(InvalidCastException){shred=false;}}
      catch (ArgumentException)
      { Mtx3.ReleaseMutex(); return null; }
      catch (InvalidCastException)
      { Mtx3.ReleaseMutex(); return null; }
      if (!File.Exists(path))
      { Mtx3.ReleaseMutex(); return null; }
      var input = ReadStringsKernal(
        path, size, offs, name, read, view, shred);
      if (input == null || !read )
      { Mtx3.ReleaseMutex();
        return null; }
      EndGame(del, path);
      Mtx3.ReleaseMutex();
      return input;
    }
 
    /// <summary> Write List of strings
    /// to memory mapped file (args[0]).
    /// Return true only if EVERYTHING went ok.
    /// REM: args[3] is a List of Strings!
    /// Strings to write as UNICODE encoded bytes.
    /// SEE DOC ABOVE FOR REQUIRED ARG VALUES.
    /// </summary>
    /// <param name="args"></param>
    /// <returns></returns>
    public static bool WriteStrings(object[] args)
    {
      if (args == null
        || args.Length < 7) return false;
      Mtx3.WaitOne();
      Collection<string> strings;
      try { strings = args[3] as Collection<string>; }
      catch(ArgumentException)
      { Mtx3.ReleaseMutex(); return false; }
      catch(InvalidCastException)
      { Mtx3.ReleaseMutex(); return false; }
      if ( strings == null || strings.Count < 1
        || string.IsNullOrEmpty(args[0].ToString()))
      { Mtx3.ReleaseMutex(); return false; }
      string file, name; long size, offs, view = 0L;
      try// REM: args[4] doesn't apply to writes.
      { file = args[0].ToString();//[0]);
        size = Convert.ToInt64( args[1]);
        offs = Convert.ToInt64( args[2]);
        name = args[5].ToString(); //5]);
        if (args.Length > 7)
          view = Convert.ToInt64(args[7]); }
      catch (ArgumentException)
      { Mtx3.ReleaseMutex(); return false; }
      catch (InvalidCastException)
      { Mtx3.ReleaseMutex(); return false; }
      if (size == 0) size = offs + CalcSize(strings);
      //  This Call to CalcSize is ^ for AutoSize! 0
      var is1 = WriteStringsKernal(file,
        name, size, offs, view, strings);
      if (is1) Writer(file);
      Mtx3.ReleaseMutex();
      return is1;
    }
 
    private static long CalcSize(
      ICollection<string> strings)
    {
      if (strings == null || strings.Count < 1)
        throw new ArgumentException("CalcSize");
      long size; try
      { size = strings.Sum(s => s.Length);
        size = (size* 2) + (2* strings.Count); }
      catch(ArgumentNullException){size = 256; }
      catch (OverflowException) {  size = 256; }
        // =-> w/Int16 UniCode it's 2 bytes per char.
      return size;// 2 x 8 ^
      // NOTE: So 2x Chars + 2 ea. <-= <-=
    }// <-= EOM <-= for ^ int16 ^ lengths.
    //=-> =-> =-> (Length stored before ea string.)
#endregion Read/Write Strings
  //\\//\\//\\//\\//\\//\\//\\//\\//\\// EOC
 
 
  }
}

Comments