Rich 7ab6604534 Updated DocVersionInfo property name
Added parameter to ROFSTLookup constructor to support passing DocVersionInfo object
Changed FixUnitROs method to use new property name
Changed GetRoValue method to use new property name
2014-02-07 17:36:07 +00:00

1154 lines
40 KiB
C#

using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Text;
using System.ComponentModel;
using System.Text.RegularExpressions;
using System.IO;
namespace VEPROMS.CSLA.Library
{
[Serializable]
[TypeConverter(typeof(ExpandableObjectConverter))]
public class ROFSTLookup
{
#region Log4Net
private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
#endregion
#region Structs
[Serializable]
public struct roHdr
{
public int hSize;
public int hYear;
public byte hMonth;
public byte hDay;
public int hcYear;
public byte hcMonth;
public byte hcDay;
public byte hcHour;
public byte hcMin;
public byte hcSec;
public byte hcHund;
public rodbi[] myDbs;
};
[Serializable]
public struct rodbi
{
public int dbiID;
public int dbiType;
public int dbiAW;
public string dbiTitle;
public string dbiAP;
public int ID;
public int ParentID;
public rochild[] children;
};
public struct rogrp
{
public int ID;
public int ParentID;
public rochild[] children;
public string value;
public string appid;
};
public struct rochild
{
public int ID;
public int ParentID;
public int type;
public string title;
public string roid;
public string appid;
public string value;
public rochild[] children;
};
public class roChild
{
rochild _MyChild;
public rochild MyChild
{
get { return _MyChild; }
set { _MyChild = value; }
}
public roChild(rochild myChild)
{
_MyChild = myChild;
}
public override string ToString()
{
return _MyChild.title;
}
};
#endregion
#region Local Data
private string _ROValue = "";
private List<string> lstRoValues;
private List<string> multiRoValues;
private Dictionary<string, string> DictROVar = new Dictionary<string, string>();
#endregion
#region Constructors
private ROFst _ROFst;
private ROFstInfo _ROFstInfo;
private int _SelectedSlave;
private DocVersionInfo _MyDocVersionInfo;
public DocVersionInfo MyDocVersionInfo
{
get { return _MyDocVersionInfo; }
set
{
_MyDocVersionInfo = value;
if (_MyDocVersionInfo.DocVersionConfig.SelectedSlave != _SelectedSlave)
{
_SelectedSlave = _MyDocVersionInfo.DocVersionConfig.SelectedSlave;
Reset();
}
}
}
public ROFSTLookup(ROFst rofst, DocVersionInfo dvi)
{
_ROFst = rofst;
_ROFstInfo = null;
using (ROFstInfo rfi = ROFstInfo.GetJustROFst(_ROFst.ROFstID))
{
_MyDocVersionInfo = dvi;//==null?null: DocVersionInfo.Get(rfi.docVer.VersionID);
}
ParseIntoDictionary(rofst.ROLookup);
}
public ROFSTLookup(ROFstInfo rofstinfo, DocVersionInfo dvi)
{
_ROFstInfo = rofstinfo;
_ROFst = null;
// docversion will be null if we're working with an ro.fst that is not currently connected
// to a docversion. One example of this is when updating ro.fst and comparing the original
// with the new to find differences. The docversioninfo is only used to get unit/master
// slave info, thus is not needed to compare the raw values.
_MyDocVersionInfo = dvi;//==null?null: DocVersionInfo.Get(_ROFstInfo.docVer.VersionID);
ParseIntoDictionary(rofstinfo.ROLookup);
}
public ROFSTLookup(string filePath)
{
_ROFstInfo = null;
_ROFst = null;
_MyDocVersionInfo = null;
FileInfo rofstFile = new FileInfo(filePath);
FileStream fs = rofstFile.Open(FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
byte[] buf = new byte[rofstFile.Length];
fs.Read(buf, 0, buf.Length);
fs.Close();
ParseIntoDictionary(buf);
}
#endregion
#region PropertiesAndData
public roHdr myHdr;
private int TableID;
private Dictionary<string, rochild> dicRos;
private Dictionary<int, rochild> dicRosIntIDs;
public void Reset()
{
dicRos = null;
dicRosIntIDs = null;
}
#endregion
#region AppSupport
public void Close()
{
// remove the dictionary
if (dicRosIntIDs != null)dicRosIntIDs.Clear();
dicRosIntIDs = null;
if (dicRos != null)dicRos.Clear();
dicRos = null;
}
public List<string> GetValueDifferences(ROFSTLookup origROFst, ref List<string> delList)
{
// use this list to see what differences are between it and the original
List<string> modList = new List<string>();
// assume each rofstlookup has a parsed dictionary
foreach (string key in origROFst.dicRos.Keys)
{
string cvalue = null;
string ovalue = origROFst.dicRos[key].value;
if (dicRos.ContainsKey(key))
cvalue = dicRos[key].value;
if (cvalue == null && cvalue != ovalue)
delList.Add(key);
else if (cvalue != ovalue)
{
// Value Change
modList.Add(key);
//Console.WriteLine("RO{0}\t\"{1}\"\t\"{2}\"", key, cvalue, ovalue);
}
}
return modList;
}
//public static ROImageInfo Get(RODbInfo rodbinfo, string filename)
//{
// if (rodbinfo.RODbROImageCount != 0)
// {
// foreach (ROImageInfo ri in rodbinfo.RODbROImages)
// {
// if (ri.FileName == filename) return ri;
// }
// }
// return null;
//}
public string GetTranslatedRoValue(string ROID16, bool DoCaret)
{
string retval = GetRoValue(ROID16);
retval = ReplaceUnicode(retval, DoCaret);
retval = ConvertFortranFormatToScienctificNotation(retval);
return retval.Replace("\r\n", @"\par ");
}
private string ReplaceUnicode(string s2, bool DoCaret)
{
string orig = s2;
s2 = s2.Replace("`", @"\'b0"); // convert backquote to degree - left over from DOS days.
s2 = s2.Replace("\xf8", @"\'b0"); // convert \xf8 to degree.
s2 = s2.Replace("\xa0", @"\u160?"); // hardspace
s2 = s2.Replace("\xb0", @"\'b0"); // degree
s2 = s2.Replace("\x7f", @"\u916?"); // delta
s2 = s2.Replace("\x2265", @"\u8805?"); // greater than or equal
s2 = s2.Replace("\x2264", @"\u8804?"); // less than or equal
s2 = s2.Replace("\xB1", @"\'b1"); // plus minus
s2 = s2.Replace("\x3A3", @"\u931?"); // sigma
s2 = s2.Replace("\x3C4", @"\u947?"); // gamma
s2 = s2.Replace("\xBD", @"\'bd"); // half
s2 = s2.Replace("\x25A0", @"\u9604?"); // accum 2584
s2 = s2.Replace("\x7", @"\u9679?"); // bullet 25CF
s2 = s2.Replace("\x2248", @"\u8776?"); // approx eq
s2 = s2.Replace("\x2261", @"\u8773?"); // similar eq 2245
s2 = s2.Replace("\xF7", @"\'f7"); // division
s2 = s2.Replace("\x221A", @"\u8730?"); // square root
s2 = s2.Replace("\x393", @"\u961?"); // rho 3C1
s2 = s2.Replace("\x3C0", @"\u960?"); // pi
s2 = s2.Replace("\xb5", @"\u956?"); // micro 3BC (try e6, if not work try 109)
s2 = s2.Replace("\x3B4", @"\u948?"); // lower case delta
s2 = s2.Replace("\x3C3", @"\u963?"); // lower case sigma
s2 = s2.Replace("\xBC", @"\'bc"); // quarter
s2 = s2.Replace("\x3C6", @"\'d8"); // dist zero, D8
s2 = s2.Replace("\xC9", @"\u274?"); // energy, 112
s2 = s2.Replace("\xEC", @"\'ec"); // grave
s2 = s2.Replace("\x2502", @"\u9474?"); // bar
s2 = s2.Replace("\x3B5", @"\u949?"); // epsilon
s2 = s2.Replace("\x398", @"\u952?"); // theta, 3B8
s2 = s2.Replace("\x221E", @"\u8857?"); // dot in oval, 2299
s2 = s2.Replace("\xBF", @"\u964?"); // tau, 3C4
s2 = s2.Replace("\x2310", @"\u9830?"); // diamond, 2666
s2 = s2.Replace("\x2192", @"\u8594?");
s2 = s2.Replace("\x2190", @"\u8592?");
s2 = s2.Replace("\x2191", @"\u8593?");
s2 = s2.Replace("\x2193", @"\u8595?");
s2 = s2.Replace("\x2207", @"\u8711?");
s2 = s2.Replace("\x2591", @"\'b0"); // Degree Symbol
s2 = s2.Replace("\xFF", @"\u8593?"); // Up Arrow
s2 = s2.Replace("\xD6", @"\u8595?"); // Down Arrow
if (DoCaret) s2 = s2.Replace("^", @"\u916?");
// Convert dash to a non-breaking dash. This is a unicode character.
// This character will be used in veproms rather than a dash.
//if the dash is preceeded byte a token remove the space following the token
s2 = Regex.Replace(s2, @"(\\[^ \\?]*) \-", @"$1\u8209?");
s2 = s2.Replace("-", @"\u8209?");
return s2;
}
private string FixUnitROs(string val)
{
if (val.StartsWith("<U-"))
{
if (val.ToUpper() == "<U-TEXT>") val = MyDocVersionInfo.DocVersionConfig.Unit_Text;
else if (val.ToUpper() == "<U-NUMBER>") val = MyDocVersionInfo.DocVersionConfig.Unit_Number;
else if (val.ToUpper() == "<U-NAME>") val = MyDocVersionInfo.DocVersionConfig.Unit_Name;
else if (val.ToUpper() == "<U-ID>") val = MyDocVersionInfo.DocVersionConfig.Unit_ID;
else if (val.ToUpper() == "<U-OTHER TEXT>") val = MyDocVersionInfo.DocVersionConfig.Other_Unit_Text;
else if (val.ToUpper() == "<U-OTHER NUMBER>") val = MyDocVersionInfo.DocVersionConfig.Other_Unit_Number;
else if (val.ToUpper() == "<U-OTHER NAME>") val = MyDocVersionInfo.DocVersionConfig.Other_Unit_Name;
else if (val.ToUpper() == "<U-OTHER ID>") val = MyDocVersionInfo.DocVersionConfig.Other_Unit_ID;
}
return val;
}
// this only gets rochild values. Later we may want another
// dictionary to get groups.
public string GetRoValue(string ROID16)
{
string ROID = ROID16.Substring(0,12);
if (dicRos == null) ParseIntoDictionary(_ROFst!=null?_ROFst.ROLookup:_ROFstInfo.ROLookup);
// Use the ROID to get the value from the dictionary
if (dicRos.ContainsKey(ROID.ToUpper()))
{
rochild rochld = (rochild)dicRos[ROID.ToUpper()];
if (rochld.value != null && rochld.value != string.Empty)
return FixUnitROs( rochld.value);
if (rochld.children != null)
{
foreach (rochild child in rochld.children)
if (child.roid.ToUpper() == ROID16.ToUpper() || (child.roid.EndsWith("0041") && ROID16.EndsWith("0000")))
return FixUnitROs(child.value);
// if there isn't a specific match for multi-return values, default to the first child.
return FixUnitROs(rochld.children[0].value);
}
}
//if (ROID == "FFFF00000001") return _ROFstInfo.ROFstAssociations[0].MyDocVersion.DocVersionConfig.Unit_Number;
//if (ROID == "FFFF00000002") return _ROFstInfo.ROFstAssociations[0].MyDocVersion.DocVersionConfig.Other_Unit_Number;
//if (ROID == "FFFF00000003") return _ROFstInfo.ROFstAssociations[0].MyDocVersion.DocVersionConfig.Unit_Text;
//if (ROID == "FFFF00000004") return _ROFstInfo.ROFstAssociations[0].MyDocVersion.DocVersionConfig.Other_Unit_Text;
//if (ROID == "FFFF00000005") return _ROFstInfo.ROFstAssociations[0].MyDocVersion.DocVersionConfig.Unit_ID;
//if (ROID == "FFFF00000006") return _ROFstInfo.ROFstAssociations[0].MyDocVersion.DocVersionConfig.Other_Unit_ID;
//if (ROID == "FFFF00000007") return _ROFstInfo.ROFstAssociations[0].MyDocVersion.DocVersionConfig.Unit_Name;
//if (ROID == "FFFF00000008") return _ROFstInfo.ROFstAssociations[0].MyDocVersion.DocVersionConfig.Other_Unit_Name;
//new stuff
if (ROID == "FFFF00000001") return MyDocVersionInfo.DocVersionConfig.Unit_Number;// _ROFstInfo.docVer.DocVersionConfig.Unit_Number;
if (ROID == "FFFF00000002") return MyDocVersionInfo.DocVersionConfig.Other_Unit_Number;// _ROFstInfo.docVer.DocVersionConfig.Other_Unit_Number;
if (ROID == "FFFF00000003") return MyDocVersionInfo.DocVersionConfig.Unit_Text;// _ROFstInfo.docVer.DocVersionConfig.Unit_Text;
if (ROID == "FFFF00000004") return MyDocVersionInfo.DocVersionConfig.Other_Unit_Text;// _ROFstInfo.docVer.DocVersionConfig.Other_Unit_Text;
if (ROID == "FFFF00000005") return MyDocVersionInfo.DocVersionConfig.Unit_ID;// _ROFstInfo.docVer.DocVersionConfig.Unit_ID;
if (ROID == "FFFF00000006") return MyDocVersionInfo.DocVersionConfig.Other_Unit_ID;// _ROFstInfo.docVer.DocVersionConfig.Other_Unit_ID;
if (ROID == "FFFF00000007") return MyDocVersionInfo.DocVersionConfig.Unit_Name;// _ROFstInfo.docVer.DocVersionConfig.Unit_Name;
if (ROID == "FFFF00000008") return MyDocVersionInfo.DocVersionConfig.Other_Unit_Name;// _ROFstInfo.docVer.DocVersionConfig.Other_Unit_Name;
//end new stuff
if (ROID.StartsWith("FFFF")) return "?"; // string.Format("Invalid Unit RO '{0}'", ROID);
return "?"; // string.Format("Invalid RO '{0}'", ROID);
}
// Get the the RO's Accessory Page ID
public string GetRoACID(string ROID16)
{
string ROID = ROID16.Substring(0,12);
if (dicRos == null) ParseIntoDictionary(_ROFst!=null?_ROFst.ROLookup:_ROFstInfo.ROLookup);
// Use the ROID to get the value from the dictionary
if (dicRos.ContainsKey(ROID.ToUpper()))
{
rochild rochld = (rochild)dicRos[ROID.ToUpper()];
if (rochld.value != null && rochld.value != string.Empty)
return rochld.appid;
if (rochld.children != null)
{
foreach (rochild child in rochld.children)
if (child.roid.ToUpper() == ROID16 || (child.roid.EndsWith("0041") && ROID16.EndsWith("0000")))
return child.appid;
// if there isn't a specific match for multi-return values, default to the first child.
return rochld.children[0].appid;
}
}
return ""; // no accessory page ID found
}
public rochild GetRoChild12(string ROID16)
{
string ROID = ROID16.Substring(0, 12);
if (dicRos == null) ParseIntoDictionary(_ROFst != null ? _ROFst.ROLookup : _ROFstInfo.ROLookup);
// Use the ROID to get the value from the dictionary
if (dicRos.ContainsKey(ROID.ToUpper()))
{
rochild rochld = (rochild)dicRos[ROID.ToUpper()];
return rochld;
}
rochild tmp = new rochild();
tmp.ID = -1;
return tmp;
}
public rochild GetRoChild(string ROID)
{
if (dicRos == null) ParseIntoDictionary(_ROFst != null ? _ROFst.ROLookup : _ROFstInfo.ROLookup);
// Use the ROID to get the value from the dictionary
if (dicRos.ContainsKey(ROID.ToUpper()))
{
rochild rochld = (rochild)dicRos[ROID.ToUpper()];
return rochld;
}
if (ROID.StartsWith("FFFF"))
{
rochild roc = new rochild();
roc.roid = ROID;
roc.type = 1;
//int selectedSlave = _ROFstInfo.docVer.DocVersionConfig.SelectedSlave;
//_ROFstInfo.docVer.DocVersionConfig.SelectedSlave = 0;
roc.value = GetRoValue(ROID);
//_ROFstInfo.docVer.DocVersionConfig.SelectedSlave = selectedSlave;
switch (ROID)
{
case "FFFF00000001":
roc.appid = "U-Number";
break;
case "FFFF00000002":
roc.appid = "U-Other Number";
break;
case "FFFF00000003":
roc.appid = "U-Text";
break;
case "FFFF00000004":
roc.appid = "U-Other Text";
break;
case "FFFF00000005":
roc.appid = "U-ID";
break;
case "FFFF00000006":
roc.appid = "U-Other ID";
break;
case "FFFF00000007":
roc.appid = "U-Name";
break;
case "FFFF00000008":
roc.appid = "U-Other Name";
break;
default:
roc.appid = "U-Unknown";
break;
}
return roc;
}
rochild tmp = new rochild();
tmp.ID = -1;
return tmp;
}
public string GetROTitle(string ROID)
{
StringBuilder sb = new StringBuilder();
rochild roc = GetRoChild12(ROID);
if (roc.value == null)
roc = GetRoChild(ROID);
sb.Append(roc.title.Replace(roc.appid,"").Replace(roc.value,"").Trim());
do
{
string parent = ROID.Substring(0, 4) + string.Format("{0:X8}", roc.ParentID);
roc = GetRoChild12(parent);
if (roc.ID > 0)
sb.Insert(0, roc.title + " - ");
} while (roc.ID > 0);
return sb.ToString();
}
// Return the RO Title in a list of strings
// The last item in the list is the actual RO title, the items preceding it are the
// titles of the groups and sub-groups containing the RO
public List<string> GetROTitleAndGroupPath(string ROID)
{
List<string> titlePath = new List<string>();
rochild roc = GetRoChild12(ROID);
//string tmp = roc.title.Replace(roc.appid, "").Replace(roc.value, "").Trim();
string tmp = roc.title.Replace(roc.appid, string.Format("<{0}>",roc.appid)).Trim();
titlePath.Add(tmp);
do
{
string parent = ROID.Substring(0, 4) + string.Format("{0:X8}", roc.ParentID);
roc = GetRoChild12(parent);
if (roc.ID > 0)
titlePath.Add(roc.title);
} while (roc.ID > 0);
titlePath.Reverse();
return titlePath;
}
// The following Method is not correct. It needs to have a RO database id as well as an id. Without that,
// the first RO with a specific id will be found regardless of the RO Database id.
//public rochild GetRoChildFromID(int id)
//{
// if (dicRosIntIDs == null) ParseIntoDictionary(_ROFst != null ? _ROFst.ROLookup : _ROFstInfo.ROLookup);
// // Use the id to get the value from the dictionary
// if (dicRosIntIDs.ContainsKey(id))
// {
// rochild rochld = (rochild)dicRosIntIDs[id];
// return rochld;
// }
// rochild tmp = new rochild();
// tmp.ID = -1;
// return tmp;
//}
public rodbi[] GetRODatabaseList()
{
return myHdr.myDbs;
}
//public string GetDefaultROPrefix()
//{
// if (docVer != null)
// return docVer.DocVersionConfig.RODefaults_setpointprefix;
// else
// return "SP1"; // Not Sure about this...
//}
//public string GetDefaultGraphicsPrefix()
//{
// if (docVer != null)
// return docVer.DocVersionConfig.RODefaults_graphicsprefix;
// else
// return "IG1"; // Not Sure about this...
//}
#region Update Ro Values
/// <summary>
/// Updates an ro.fst into a sql database.
/// </summary>
/// <param name="rdi" - the Rodb to use as the path for updating the ro.fst, i.e.
/// import from there.
/// <param name="docver" - hook into this doc version></param>
/// <returns>ROFst: Returns the created rofst object</returns>
//public static ROFst UpdateRoFst(RODbInfo rdi, DocVersionAssociation dva, DocVersion docver)
//{
// // file validity checks are done before getting here - just do the import
// // here.
// string rofstfilepath = rdi.FolderPath + @"\ro.fst";
// DirectoryInfo di = new DirectoryInfo(rdi.FolderPath);
// // There may be more than 1 'ro' as the 'ROName' field (ROName is derived from the ropath).
// // Get new name be incrementing, if so.
// string newname = NewROName(di.Name);
// // Next read in the rofst & make the rofst record.
// FileStream fsIn = new FileStream(rofstfilepath, FileMode.Open, FileAccess.Read, FileShare.Read);
// // Create an instance of StreamReader that can read characters from the FileStream.
// BinaryReader r = new BinaryReader(fsIn);
// byte[] ab = r.ReadBytes((int)fsIn.Length);
// fsIn.Close();
// using (RODb rd = RODb.Get(rdi.RODbID))
// {
// ROFst rofst = ROFst.MakeROFst(rd, ab, null, di.LastWriteTimeUtc, rdi.UserID);
// // Hook this into the current docversion by replacing the rofstid field in the doc version
// // association object:
// dva.MyROFst = rofst;
// docver.Save();
// // Now load any images in... type 8 - integrated graphics ro type
// ROFstInfo rofstInfo = ROFstInfo.Get(rofst.ROFstID);
// rofstInfo.ParseIntoDictionary(rofstInfo.ROFST);
// for (int i = 0; i < rofstInfo.myHdr.myDbs.Length; i++)
// {
// // walk through the rofst 'database' searching for all nodes that are integrated graphics, type 8:
// if (rofstInfo.myHdr.myDbs[i].children != null) rofstInfo.MigrateRoFstGraphics(rdi, rofstInfo.myHdr.myDbs[i].children);
// }
// return rofst;
// }
//}
//private static string RoAppConfigExt(string fstPath)
//{
// string inipath = fstPath + @"\roapp.ini";
// if (!File.Exists(inipath)) return null;
// StreamReader myReader = new StreamReader(inipath);
// string sLine;
// int indx = -1;
// while ((sLine = myReader.ReadLine()) != null)
// {
// if (sLine.Length > 0 && sLine.Substring(0, 1) != ";")
// {
// if ((indx = sLine.ToLower().IndexOf("extention")) >= 0)
// {
// indx = sLine.IndexOf("=", indx + 9);
// return sLine.Substring(indx + 1, sLine.Length - indx - 1).Trim();
// }
// }
// }
// myReader.Close();
// return null;
//}
//private static string NewROName(string roName)
//{
// string retval = roName;
// int iSuffix = -1;
// RODbInfoList rodblist = RODbInfoList.Get();
// foreach (RODbInfo rdi in rodblist)
// {
// if (rdi.ROName.StartsWith(roName))
// {
// if (rdi.ROName == roName)
// iSuffix = 0;
// else if (Regex.IsMatch(rdi.ROName, roName + "[_][0-9]+"))
// {
// int ii = int.Parse(rdi.ROName.Substring(1 + roName.Length));
// if (ii > iSuffix) iSuffix = ii;
// }
// }
// }
// if (iSuffix >= 0)
// retval = string.Format("{0}_{1}", roName, iSuffix + 1);
// return retval;
//}
//private void MigrateRoFstGraphics(RODbInfo rdi, ROFstInfo.rochild[] rochild)
//{
// for (int i = 0; i < rochild.Length; i++)
// {
// if (rochild[i].type == 8) AddGraphic(rdi, rochild[i].value);
// if (rochild[i].children != null) MigrateRoFstGraphics(rdi, rochild[i].children);
// }
//}
//private void AddGraphic(RODbInfo rdi, string p)
//{
// if (p == null) return;
// string imgname = p.Substring(0, p.IndexOf('\n'));
// int thedot = imgname.LastIndexOf('.');
// string fname = imgname;
// if (thedot == -1 || (thedot != (imgname.Length - 4)))
// {
// RODbConfig roDbCfg = new RODbConfig(rdi.Config);
// fname += string.Format(".{0}", roDbCfg.GetDefaultGraphicExtension());
// }
// string imgfile = rdi.FolderPath + @"\" + fname;
// ROImage roImg = null;
// if (File.Exists(imgfile))
// {
// FileInfo fi = new FileInfo(imgfile);
// // if the roimage record exists, don't create a new one...
// using (roImg = ROImage.GetByRODbID_FileName_DTS(rdi.RODbID, imgname, fi.LastWriteTimeUtc))
// {
// if (roImg == null)
// {
// FileStream fsIn = new FileStream(imgfile, FileMode.Open, FileAccess.Read, FileShare.Read);
// BinaryReader r = new BinaryReader(fsIn);
// byte[] ab = r.ReadBytes((int)fsIn.Length);
// r.Close();
// fsIn.Close();
// using (RODb rodb = RODb.Get(rdi.RODbID))
// {
// roImg = ROImage.MakeROImage(rodb, imgname, ab, null, fi.LastWriteTimeUtc, "Migration");
// }
// }
// Figure figure = Figure.GetByROFstID_ImageID(this.ROFstID, roImg.ImageID);
// if (figure != null) return;
// using (ROFst rofst = ROFst.Get(this.ROFstID))
// {
// figure = Figure.MakeFigure(rofst, roImg, null);
// }
// }
// }
// else
// Console.WriteLine(string.Format("{0}", imgfile), "Cannot Find Image File");
//}
#endregion
#endregion
#region LoadStructs
private int StringLength(byte[] ab, int offset)
{
int i = 0;
while (ab[i + offset] != 0) i++;
return i;
}
private rogrp LoadGroup(byte[] ab, int offset)
{
rogrp myGrp = new rogrp();
myGrp.ID = BitConverter.ToInt32(ab, offset);
myGrp.ParentID = BitConverter.ToInt32(ab, offset + 4);
int howmany = BitConverter.ToInt16(ab, offset + 8);
if (howmany > 0)
{
myGrp.children = new rochild[howmany];
int myOffset = offset + 10;
for (int i = 0; i < myGrp.children.Length; i++)
{
int childOffset = BitConverter.ToInt32(ab, myOffset);
rochild tmp = new rochild();
//tmp.offset=BitConverter.ToInt32(ab,myOffset);
tmp.type = BitConverter.ToInt16(ab, myOffset + 4);
int slen = StringLength(ab, myOffset + 6);
tmp.title = Encoding.Default.GetString(ab, myOffset + 6, slen);
myOffset += (7 + slen);
rogrp tmpg = LoadGroup(ab, childOffset);
MultipleReturnValuesInheritType(ref tmpg, tmp.type);
tmp.ID = tmpg.ID;
tmp.ParentID = tmpg.ParentID;
tmp.children = tmpg.children;
tmp.value = tmpg.value;
tmp.appid = tmpg.appid;
tmp.roid = TableID.ToString("X4") + tmp.ID.ToString("X8");
// Add dictionary entries for children
if (tmp.children != null)
{
foreach (rochild child in tmp.children)
if (!dicRos.ContainsKey(child.roid.ToUpper()))
dicRos.Add(child.roid.ToUpper(), child);
}
dicRos.Add(tmp.roid.ToUpper(), tmp);
if (!dicRosIntIDs.ContainsKey(tmp.ID)) dicRosIntIDs.Add(tmp.ID, tmp);
int j;
for (j = i - 1; j >= 0 && tmp.ID < myGrp.children[j].ID; j--)
{
myGrp.children[j + 1] = myGrp.children[j];
}
myGrp.children[j + 1] = tmp;
}
}
else
{
int slen = StringLength(ab, offset + 12);
//myGrp.value = Encoding.Default.GetString(ab, offset + 12, slen);
ProcessROReturnValue(ref myGrp, Encoding.Default.GetString(ab, offset + 12, slen));
int slen2 = StringLength(ab, offset + 13 + slen);
myGrp.appid = Encoding.Default.GetString(ab, offset + 13 + slen, slen2);
}
return myGrp;
}
/// <summary>
/// This function will take the raw RO return value and resolve any macros, conditionals, and
/// generated the return value or a list of multiple return values.
/// </summary>
/// <param name="myGrp"></param>
/// <param name="rawvalue"></param>
private void ProcessROReturnValue(ref rogrp myGrp, string rawvalue)
{
if (dicRos == null) ParseIntoDictionary(_ROFst != null ? _ROFst.ROLookup : _ROFstInfo.ROLookup);
List<string> lstROVals = GetROReturnValue(rawvalue);
if (lstROVals.Count > 1) // mulitple return values
{
myGrp.children = new rochild[lstROVals.Count];
for (int i = 0; i < lstROVals.Count; i++)
{
string tsts = Convert.ToInt32(multiRoValues[i][0]).ToString("X4");
myGrp.children[i].value = lstROVals[i].Replace("\xFF", "\xa0");
myGrp.children[i].roid = TableID.ToString("X4") + myGrp.ID.ToString("X8") + tsts;
myGrp.children[i].type = -1; // Multiple return value inherit type from parent
myGrp.children[i].title = lstROVals[i].Replace("\xFF", "\xa0");
}
}
else
myGrp.value = lstROVals[0];
return;
}
/// <summary>
/// Multiple return values need to get the type from the parent node.
/// </summary>
/// <param name="myGrp"></param>
/// <param name="parenttype"></param>
private void MultipleReturnValuesInheritType(ref rogrp myGrp, int parenttype)
{
if (myGrp.children != null)
{
for (int cnt = 0; cnt < myGrp.children.Length; cnt++)
{
if (myGrp.children[cnt].type == -1)
{
myGrp.children[cnt].type = parenttype;
myGrp.children[cnt].appid = myGrp.appid;
}
}
}
}
private void ParseIntoDictionary(byte[] ab)
{
if (dicRos == null) dicRos = new Dictionary<string, rochild>();
if (dicRosIntIDs == null) dicRosIntIDs = new Dictionary<int, rochild>();
myHdr.hSize = BitConverter.ToInt32(ab, 0);
myHdr.hYear = BitConverter.ToInt16(ab, 4);
myHdr.hMonth = ab[6];
myHdr.hDay = ab[7];
myHdr.hcYear = BitConverter.ToInt16(ab, 8);
myHdr.hcMonth = ab[10];
myHdr.hcDay = ab[11];
myHdr.hcHour = ab[12];
myHdr.hcMin = ab[13];
myHdr.hcSec = ab[14];
myHdr.hcHund = ab[15];
int hdrOffset = BitConverter.ToInt32(ab, 16);
int howbig = BitConverter.ToInt32(ab, hdrOffset);
int dbs = BitConverter.ToInt16(ab, hdrOffset + 4);
myHdr.myDbs = new rodbi[dbs];
for (int i = 0; i < dbs; i++)
{
int offset = hdrOffset + 6 + (i * 30);
myHdr.myDbs[i].dbiID = BitConverter.ToInt16(ab, offset + 0);
TableID = myHdr.myDbs[i].dbiID;
myHdr.myDbs[i].dbiType = BitConverter.ToInt16(ab, offset + 2);
myHdr.myDbs[i].dbiAW = BitConverter.ToInt16(ab, offset + 4);
rogrp tmp = LoadGroup(ab, BitConverter.ToInt32(ab, offset + 6));
myHdr.myDbs[i].ID = tmp.ID;
myHdr.myDbs[i].children = tmp.children;
int iPtr = BitConverter.ToInt32(ab, offset + 22) + hdrOffset + 6;
myHdr.myDbs[i].dbiTitle = Encoding.Default.GetString(ab, iPtr, StringLength(ab, iPtr));
iPtr = BitConverter.ToInt32(ab, offset + 26) + hdrOffset + 6;
myHdr.myDbs[i].dbiAP = Encoding.Default.GetString(ab, iPtr, StringLength(ab, iPtr));
}
}
#endregion
#region GetRoValues
public List<string> GetROReturnValue(string roval)
{
lstRoValues = new List<string>();
multiRoValues = new List<string>();
DictROVar = new Dictionary<string, string>(); // set up a dictionary of RO defined Variables
string tmp = ProcessRO(_MyDocVersionInfo==null?roval:_MyDocVersionInfo.ProcessDocVersionSpecificInfo(roval), false);
if (tmp != null && lstRoValues.Count == 0) // was not a multiple return value
lstRoValues.Add(tmp);
return lstRoValues;
}
private string ProcessRO(string roval, bool multiRtnVal)
{
string str = roval;
string rtnstr = "";
int l = roval.Length;
while (l > 0)
{
int ptr = NextDelimiter("{", str);
if (ptr == -1)
{ // add remaining text
//add(new seText(str, l));
rtnstr += str;
l = 0; // break out of while loop
}
else
{
int cnt = ptr; //(int)(ptr - str);
if (cnt > 0)
{ // add text
//add(new seText(str, cnt));
rtnstr += str.Substring(0, cnt);
l -= cnt;
//str = ptr;
str = str.Substring(ptr);
}
ptr = MatchingBrace(str) + 1;
cnt = ptr; //(int)(ptr - str);
bool nfnd = false;
string pbstr = ProcessBrace(str.Substring(1, cnt - 2), cnt - 2, ref nfnd, multiRtnVal);
if (pbstr == null) return null;
if (nfnd)
rtnstr += str.Substring(0, cnt);
// add(new seText(str, cnt));
else
rtnstr += pbstr;
l -= cnt;
//str = ptr;
str = str.Substring(ptr);
}
}
//rtnstr = rtnstr.Replace("`", @"\'b0"); // convert backquote to degree - left over from DOS days.
rtnstr = ProcessMacros(rtnstr);
return rtnstr;
}
//
// Takes the ro text value and sees if a macro has been used. If so it will perform the macro
// operation on the substring in the text value
//
// right now the only macro is @HSP(), where every space between the "(" and ")" will be replaced with a hardspace
//
private string ProcessMacros(string str)
{
if( str == null || str == "" ) return str;
string rtnstr = str;
int indx = -1;
while ((indx = rtnstr.ToUpper().IndexOf("@HSP("))>-1)
{
string resstr = rtnstr.Substring(0,indx);
int endHsp = rtnstr.IndexOf(")",indx);
string tmpstr = rtnstr.Substring(indx+5,endHsp-indx-5);
tmpstr = tmpstr.Replace(" ", @"\u160?");
resstr = resstr + tmpstr;
rtnstr = resstr + rtnstr.Substring(endHsp+1);
}
return rtnstr;
}
private string ProcessConditional(string cnd, string opt, int lencnd, int lenopt, bool multiRtnVal)
{
// equaluate condition
string stat = (_MyDocVersionInfo != null) ? this._MyDocVersionInfo.Evaluate(cnd, lencnd) : "";
int ls = stat.Length;//strlen(stat);
if (ls == 0)
return ""; // if evaluation not defined then return an empty string - no matches can be made
// look for match - remember default
string match = null;
int matchlen = 0;
string def = null;
int deflen = 0;
while (lenopt > 0 && match == null)
{
int end = MatchingBrace(opt);
int eq = opt.IndexOf('=');// strchr(opt, '=');
int len = end + 1; //(int)((end + 1) - opt); // +1 to include the '}'
int li = eq - 1;//(int)(eq - opt) - 1;
int ld = len - li - 3;// One for '{', '=' and '}'
if (def == null || eq == 1) // (!def || eq == opt+1)
{
def = opt.Substring(eq + 1); //def=eq+1;
deflen = ld;
}
if (ls == li && opt.Substring(1).StartsWith(stat+"=")) // (stat.IndexOf(opt.Substring(1), li) > -1)) //(ls == li && !strncmp(stat, opt + 1, li))
{
match = opt.Substring(eq + 1, ld);// match = eq + 1;
matchlen = ld;
}
opt = opt.Substring(len); //opt += len;// point to the next piece
lenopt -= len;
}
// if match process option - or process default
if (match == null) //(!match)
{
match = def.Substring(0, deflen);
matchlen = deflen;
}
return ProcessRO(match, multiRtnVal); //process(match, matchlen);
}
private string ProcessBrace(string str, int l, ref bool nfnd, bool multiRtnVal)
{
string rtnstr = "";
int nxt = NextDelimiter("{=", str); //nextDelimiter("{=", str, l);
if (nxt == -1) // no delimiter found
{ // VarUse
//strList *found=vl->lookFor(str,l);
bool found = DictROVar.ContainsKey(str);
if (found)
rtnstr = DictROVar[str];
//add(new seVarUse(found));
else
nfnd = true;
}
else
{
if (str[nxt] == '{')
{ // conditonal or menu
if (nxt == 0) // if (nxt == str)
{ // menu
// TODO: implement Menu logic
//ml->process(str, l, vl);
//add(new seMenuUse(ml));
//lstRoValues.Add(ProcessRO(str.Substring(0,l), true));
ProcessMultiReturnValues(str, l);
}
else
{ // conditional
rtnstr = ProcessConditional(str, str.Substring(nxt), nxt, str.Length - nxt - 1, multiRtnVal);//processCondition(str, nxt, (int)(nxt - str), l - (int)(nxt - str));
}
}
else
{ // must be variable definiton
//vl->add(str, nxt+1, (int)(nxt-str), (l - (int)(nxt-str))-1, ml);
// 'l' is the lenght up to the matching brace of the variable definition
string tmpval = ProcessRO(str.Substring(nxt + 1, l - nxt - 1), multiRtnVal);
if (tmpval.Equals(string.Empty)) tmpval = " "; // nothing assinged to variable
if (!DictROVar.ContainsKey(str.Substring(0, nxt))) // need a try/catch here.
{
DictROVar.Add(str.Substring(0, nxt), tmpval);
if(nxt == 1)
multiRoValues.Add(str.Substring(0, nxt));
}
else
return null;
if (multiRtnVal)
rtnstr = tmpval;
}
}
return rtnstr;
}
private Dictionary<string, List<roChild>> _ValueLookupDictionary = null;
public List<roChild> GetRosByValue(string value)
{
if (_ValueLookupDictionary == null)
BuildValueDictionary();
if (value == string.Empty)
return null;
if(_ValueLookupDictionary.ContainsKey(value.ToUpper()))
return _ValueLookupDictionary[value.ToUpper()];
return null;
}
private void BuildValueDictionary()
{
_ValueLookupDictionary = new Dictionary<string, List<roChild>>();
if (dicRos == null)
ParseIntoDictionary(_ROFst != null ? _ROFst.ROLookup : _ROFstInfo.ROLookup);
foreach (rochild child in dicRos.Values)
{
if (child.value != null)
{
string value = child.value.ToUpper();
if (_ValueLookupDictionary.ContainsKey(value))
_ValueLookupDictionary[value].Add(new roChild(child));
else
{
List<roChild> children = new List<roChild>();
children.Add(new roChild(child));
_ValueLookupDictionary.Add(value, children);
}
}
}
}
private Dictionary<string, rochild> _dicROAPID = null;
public rochild? GetROChildByAccPageID(string accPageID, string spDefault, string igDefault)
{
rochild? child = GetRoChildByAccPagID(accPageID, spDefault, igDefault);
if (child == null)
{
if(Regex.IsMatch(accPageID, @".*\.[A-Z]"))
{
string accpage = accPageID.Substring(0, accPageID.Length - 3);
int index = accPageID.Substring(accPageID.Length - 2, 1)[0] - 'A';
child = GetRoChildByAccPagID(accpage, spDefault, igDefault);
if (child == null) return null;
if (((rochild)child).children != null && ((rochild)child).children.Length > 0 && ((rochild)child).children.Length > index)
return ((rochild)child).children[index];
}
return null;
}
if (((rochild)child).children != null && ((rochild)child).children.Length > 0)
return ((rochild)child).children[0];
return (rochild)child;
}
public string GetROValueByAccPagID(string accPageID, string spDefault, string igDefault)
{
rochild? child = GetROChildByAccPageID(accPageID, spDefault, igDefault);
if (child == null) return null;
return ((rochild)child).value;
}
public int? GetROTypeByAccPagID(string accPageID, string spDefault, string igDefault)
{
rochild? child = GetROChildByAccPageID(accPageID, spDefault, igDefault);
if (child == null) return null;
return ((rochild)child).type;
}
public string GetROIDByAccPagID(string accPageID, string spDefault, string igDefault)
{
rochild? child = GetROChildByAccPageID(accPageID, spDefault, igDefault);
if (child == null) return null;
return ((rochild)child).roid;
}
public rochild? GetRoChildByAccPagID(string accPageID, string spDefault, string igDefault)
{
if (_dicROAPID == null)
BuildROAPIDDictionary();
accPageID = accPageID.Replace("<SP-", "<" + spDefault + "-");
accPageID = accPageID.Replace("<IG-", "<" + igDefault + "-");
accPageID = accPageID.Trim("<>".ToCharArray()); // String < and >
if (_dicROAPID.ContainsKey(accPageID))
return _dicROAPID[accPageID];
return null;
}
private void BuildROAPIDDictionary()
{
if (dicRos == null)
ParseIntoDictionary(_ROFst != null ? _ROFst.ROLookup : _ROFstInfo.ROLookup);
_dicROAPID = new Dictionary<string, rochild>();
foreach (rodbi dbi in myHdr.myDbs)
{
if (dbi.children != null)
BuildROAPIDDictionary(dbi.dbiAP, dbi.children);
}
}
private void BuildROAPIDDictionary(string prefix, rochild[] children)
{
foreach (rochild child in children)
{
if (child.appid != null && child.appid != "" && child.ID != 0)
{
string key = string.Format("{0}-{1}", prefix, child.appid);
if (!_dicROAPID.ContainsKey(key))
_dicROAPID.Add(key, child);
}
if (child.children != null)
BuildROAPIDDictionary(prefix, child.children);
}
}
private void ProcessMultiReturnValues(string str, int len)
{
string tstr = str.Substring(0, len);
while (tstr.Length > 0)
{
int idx = MatchingBrace(tstr);
string tmpVal = ProcessRO(tstr.Substring(0, idx + 1), true);
if (tmpVal != null) lstRoValues.Add(tmpVal); // duplicates get returned as null
tstr = tstr.Substring(idx + 1);
}
}
private int MatchingBrace(string str)
{
int level = 1;
int idx = 0; // the while will skip the first position (the first brace)
while (level > 0 && idx++ < str.Length)
{
switch (str[idx])
{
case '{':
level++;
break;
case '}':
level--;
break;
}
}
if (level != 0)
idx = -1; // didn't find matching brace
return idx; //length including end brace
}
private int NextDelimiter(string delim, string str)
{
int idx;
idx = str.IndexOfAny(delim.ToCharArray());
return idx;
}
public List<rochild> GetRoChildrenByType(int type)
{
List<rochild> children = new List<rochild>();
AddRoChildByType(children, type);
return children;
}
private void AddRoChildByType(List<rochild> children, int type)
{
foreach (rodbi dbi in myHdr.myDbs)
{
if (dbi.children != null)
AddRoChildByType(dbi.children,children,type);
}
}
private void AddRoChildByType(rochild[] roChildren, List<rochild> children, int type)
{
foreach (rochild child in roChildren)
{
if (child.type == type && child.value != null)
children.Add(child);
if (child.children != null)
AddRoChildByType(child.children,children,type);
}
}
#endregion
#region FortranFormat
public static string ConvertFortranFormatToScienctificNotation(string str)
{
// ([+-]?|\\u8209\?) either an optional single character Plus (+) or Minus (-) or non-breaking dash (\u8209?)
// ([0-9]+) a group of at least one digits
// [.] a decimal point
// ([0-9]*?) a group of zero or more digits
// 0*E optional zeros (spare zeros) followed
// ([+-]?|\\u8209\?) either an optional single character Plus (+) or Minus (-) or non-breaking dash (\u8209?)
// ([0-9]+) a group of at least one digits
string retval = Regex.Replace(str, @"([+-]?|\\u8209\?)([0-9]+)[.]([0-9]*?)0*E([+-]?|\\u8209\?)([0-9]+)", new MatchEvaluator(FixFortranNumber));
// don't convert # and ~ to super/subscripts, this is a DOS holdout and is done only for non-procedure step sections
//retval = Regex.Replace(retval, "[#](.*?)[#]", "\\up2 $1\\up0 ");// DOS Superscript
//retval = Regex.Replace(retval, "[~](.*?)[~]", "\\dn2 $1\\up0 ");// DOS Subscript
return retval;
}
private static string FixFortranNumber(Match match)
{
StringBuilder sb = new StringBuilder(match.Groups[1].Value.Replace("-",@"\u8209?"));
if (match.Groups[3].Length == 0) // Nothing to the right of the decimal
if (match.Groups[2].Value != "1") // Other than "1", multiply it times 10 raised to a power
sb.Append(match.Groups[2].Value + "x10");
else // The number is simply 1 so it can be ignored and 10 can be raised to a power
sb.Append("10");
else // A number with a decimal point
sb.Append(match.Groups[2].Value + "." + match.Groups[3].Value + "x10");
// Add the exponent as superscript
return sb.ToString() + "\\up2 " + match.Groups[4].Value.Replace("-",@"\u8209?") + match.Groups[5].Value + "\\up0 ";
}
#endregion
}
[Flags]
public enum E_ROValueType : uint
{
All = 0,
Text = 1,
Table = 2,
Graph = 4,
Image = 8,
Video = 16,
Hologram = 32
}
}