Rich be814b9743 Improve ROFst Update Performance
Add RoFstLookup Dicitonary Entries for Multiple Return Values
AddByROFstIDImageIDs - Add a list of figures based upon a List of ImageIDs
Fix regular expression to find RO Text to replace
GetDROUsagesByROIDs - get a list of ROUSages for a list of ROIDs
GetJustRODB - Get Just RODB object without children
GetJustROFst - Get Just ROFst or ROFstInfo object without children
Reduce duplicate gets of RODB and ROFst
Improve ROFst Update Performance
GetByRODbIDNoData - Get RoImageInfo objects without graphic data for ROFst Update comparison
GetROUSagesByROIDs - Get a list of ROUSages by ROIDs.  This reduces the number of ROIDs to be checked when updating ROFst.
Use GetJustRoFst and GetJustRoDB to improve the performance to see if the "Update ROFst" button should be active.
2011-07-18 14:57:47 +00:00

885 lines
28 KiB
C#

using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Text;
using System.ComponentModel;
using System.Text.RegularExpressions;
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 Dictionary<string, string> DictROVar = new Dictionary<string, string>();
#endregion
#region Constructors
private ROFst _ROFst;
private ROFstInfo _ROFstInfo;
private DocVersionInfo _DocVersionInfo;
public ROFSTLookup(ROFst rofst)
{
_ROFst = rofst;
_ROFstInfo = null;
using (ROFstInfo rfi = ROFstInfo.GetJustROFst(_ROFst.ROFstID))
{
_DocVersionInfo = rfi.docVer==null?null: DocVersionInfo.Get(rfi.docVer.VersionID);
}
ParseIntoDictionary(rofst.ROLookup);
}
public ROFSTLookup(ROFstInfo rofstinfo)
{
_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.
_DocVersionInfo = _ROFstInfo.docVer==null?null: DocVersionInfo.Get(_ROFstInfo.docVer.VersionID);
ParseIntoDictionary(rofstinfo.ROLookup);
}
#endregion
#region PropertiesAndData
public roHdr myHdr;
private int TableID;
private Dictionary<string, rochild> dicRos;
private Dictionary<int, rochild> dicRosIntIDs;
#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;
//}
// 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))
{
rochild rochld = (rochild)dicRos[ROID];
if (rochld.value != null && rochld.value != string.Empty)
return rochld.value;
if (rochld.children != null)
{
foreach (rochild child in rochld.children)
if (child.roid.ToUpper() == ROID16)
return child.value;
}
}
if (ROID.StartsWith("FFFF")) return "?"; // string.Format("Invalid Unit RO '{0}'", ROID);
return "?"; // string.Format("Invalid RO '{0}'", ROID);
}
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))
{
rochild rochld = (rochild)dicRos[ROID];
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))
{
rochild rochld = (rochild)dicRos[ROID];
return rochld;
}
rochild tmp = new rochild();
tmp.ID = -1;
return tmp;
}
// 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.LastWriteTime, 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.LastWriteTime))
// {
// 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.LastWriteTime, "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))
dicRos.Add(child.roid, child);
}
dicRos.Add(tmp.roid, 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++)
{
myGrp.children[i].value = lstROVals[i];
myGrp.children[i].roid = TableID.ToString("X4") + myGrp.ID.ToString("X8") + (0x41+i).ToString("X4");
myGrp.children[i].type = -1; // Multiple return value inherit type from parent
myGrp.children[i].title = lstROVals[i];
}
}
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>();
DictROVar = new Dictionary<string, string>(); // set up a dictionary of RO defined Variables
string tmp = ProcessRO(_DocVersionInfo==null?roval:_DocVersionInfo.ProcessDocVersionSpecificInfo(roval), false);
if (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 (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 = (_DocVersionInfo != null) ? this._DocVersionInfo.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 && (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
DictROVar.Add(str.Substring(0, nxt), tmpval);
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 string GetROValueByAccPagID(string accPageID, string spDefault, string igDefault)
{
rochild? child = GetRoChildByAccPagID(accPageID, spDefault, igDefault);
if (child != null) return ((rochild)child).value;
return null;
}
public int? GetROTypeByAccPagID(string accPageID, string spDefault, string igDefault)
{
rochild? child = GetRoChildByAccPagID(accPageID, spDefault, igDefault);
if (child != null) return ((rochild)child).type;
return null;
}
public string GetROIDByAccPagID(string accPageID, string spDefault, string igDefault)
{
rochild? child = GetRoChildByAccPagID(accPageID, spDefault, igDefault);
if (child != null) return ((rochild)child).roid;
return null;
}
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);
lstRoValues.Add(ProcessRO(tstr.Substring(0, idx + 1), true));
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)
{
string retval = Regex.Replace(str, "([+-]?)([0-9]+)[.]([0-9]*?)0*E([+-]?[0-9]+)", new MatchEvaluator(FixFortranNumber));
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);
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 + "\\up0 ";
}
#endregion
}
[Flags]
public enum E_ROValueType : uint
{
All = 0,
Text = 1,
Table = 2,
Graph = 4,
Image = 8,
Video = 16,
Hologram = 32
}
}