3074 lines
77 KiB
C#
3074 lines
77 KiB
C#
/*********************************************************************************************
|
|
* Copyright 2005 - Volian Enterprises, Inc. All rights reserved.
|
|
* Volian Enterprises - Proprietary Information - DO NOT COPY OR DISTRIBUTE
|
|
* ------------------------------------------------------------------------------
|
|
* $Workfile: ROFST.cs $ $Revision: 13 $
|
|
* $Author: Kathy $ $Date: 8/31/05 11:32a $
|
|
*
|
|
* $History: ROFST.cs $
|
|
*
|
|
* ***************** Version 13 *****************
|
|
* User: Kathy Date: 8/31/05 Time: 11:32a
|
|
* Updated in $/LibSource/ROFST
|
|
* B2005-032: new groups crashed when writing to ro.fst during approve
|
|
* sel.
|
|
*
|
|
* ***************** Version 12 *****************
|
|
* User: Kathy Date: 8/16/05 Time: 2:52p
|
|
* Updated in $/LibSource/ROFST
|
|
* B2005-030: crash when writing ro.fst for new ro
|
|
*
|
|
* ***************** Version 11 *****************
|
|
* User: Kathy Date: 6/21/05 Time: 1:36p
|
|
* Updated in $/LibSource/ROFST
|
|
* FindModROs for approve selected, crash on xyplot with missing end ">"
|
|
*
|
|
* ***************** Version 10 *****************
|
|
* User: Jsj Date: 6/02/05 Time: 11:31a
|
|
* Updated in $/LibSource/ROFST
|
|
* fix for approving with conditional ROs
|
|
*
|
|
* ***************** Version 9 *****************
|
|
* User: Jsj Date: 5/20/05 Time: 9:21a
|
|
* Updated in $/LibSource/ROFST
|
|
* fixed getro for cases when using unit specific info to process the RO
|
|
* return value.
|
|
*
|
|
* ***************** Version 8 *****************
|
|
* User: Jsj Date: 5/17/05 Time: 11:48a
|
|
* Updated in $/LibSource/ROFST
|
|
* fixed approve graphic bug, added default graphic extension as part of
|
|
* ROFST class initialization, code cleanup
|
|
*
|
|
* ***************** Version 7 *****************
|
|
* User: Kathy Date: 5/11/05 Time: 9:26a
|
|
* Updated in $/LibSource/ROFST
|
|
* add close method
|
|
*
|
|
* ***************** Version 6 *****************
|
|
* User: Jsj Date: 4/07/05 Time: 11:15a
|
|
* Updated in $/LibSource/ROFST
|
|
* fixes
|
|
*
|
|
* ***************** Version 5 *****************
|
|
* User: Jsj Date: 3/31/05 Time: 9:16a
|
|
* Updated in $/LibSource/ROFST
|
|
*
|
|
* ***************** Version 4 *****************
|
|
* User: Jsj Date: 3/28/05 Time: 12:18p
|
|
* Updated in $/LibSource/ROFST
|
|
*
|
|
* ***************** Version 3 *****************
|
|
* User: Jsj Date: 3/22/05 Time: 9:52a
|
|
* Updated in $/LibSource/ROFST
|
|
* March 22 2005 update for merge
|
|
*
|
|
* ***************** Version 2 *****************
|
|
* User: Jsj Date: 3/14/05 Time: 1:36p
|
|
* Updated in $/LibSource/ROFST
|
|
* update
|
|
*
|
|
* ***************** Version 1 *****************
|
|
* User: Jsj Date: 3/10/05 Time: 3:53p
|
|
* Created in $/LibSource/ROFST
|
|
*
|
|
* ***************** Version 1 *****************
|
|
* User: Jsj Date: 3/10/05 Time: 3:49p
|
|
* Created in $/LibSource/ROFST/ROFST
|
|
*
|
|
*********************************************************************************************/
|
|
using System;
|
|
using System.IO;
|
|
using System.Windows.Forms;
|
|
using System.Text;
|
|
using System.Collections;
|
|
using VlnStatus;
|
|
using Utils;
|
|
|
|
/*
|
|
* This namespace is used in both VE-PROMS and the RO Editor programs.
|
|
*/
|
|
namespace ROFST_FILE
|
|
{
|
|
/*
|
|
* Globally used functions amoung a few of the classes in this namespace
|
|
*/
|
|
public class ROProcessTools
|
|
{
|
|
// For now, have hooks to set and get the current
|
|
// procedure number along with the Maxium Procedure
|
|
// Number length. The 16-bit code used globals
|
|
// jsj - 6/2/2005
|
|
|
|
private static string PNumber = " "; // default to blank
|
|
private static int mxPrcLen = 30; // default to 30 chars
|
|
|
|
static ROProcessTools()
|
|
{
|
|
}
|
|
|
|
public static string ProcedureNumber
|
|
{
|
|
set { PNumber = value.ToString();}
|
|
get { return PNumber; }
|
|
}
|
|
|
|
public static int MaxProcNumLen
|
|
{
|
|
set { mxPrcLen = (int)value;}
|
|
get { return mxPrcLen;}
|
|
}
|
|
|
|
public static string UnitSpecific(string str, int len, int trm, int maxPrcNumLen)
|
|
{
|
|
// This routine retrieves the procedure number format from the
|
|
// current directory and uses it to adjust the procedure number
|
|
// in the specified string
|
|
string retvalu="";
|
|
string asis="#";
|
|
string pnum;
|
|
if( str == null || str.Length == 0 ) return null;
|
|
/*
|
|
* Bug fix: B2005-017 3/2/2005
|
|
* Need to use the largest procedure number length that's in the
|
|
* SET.DFF file. "LargestNumber" is the largest length after the
|
|
* procedure number is replaced via the SET.INI file "replace" list.
|
|
*
|
|
if(len==0)len=LargestNumber;
|
|
*/
|
|
if(len==0)len=maxPrcNumLen; //LargestRawSetNumber
|
|
string mstr;
|
|
PrivateProfile proc_ini = new PrivateProfile("proc.ini");
|
|
mstr = proc_ini.Attr("unit", "procedure number");
|
|
if (mstr == null) mstr = asis;
|
|
pnum=mstr;
|
|
if(pnum.Equals(asis))
|
|
{
|
|
retvalu=str;
|
|
}
|
|
else if (!pnum.Equals("") && pnum[0] == '!')
|
|
{
|
|
if (File.Exists("set.ini"))
|
|
{
|
|
string p = str;
|
|
string q, tonum;
|
|
StringBuilder rbldr = new StringBuilder();
|
|
int newl, dw, cnt=0, lstr;
|
|
|
|
p = p.TrimStart(" ".ToCharArray());
|
|
lstr = p.Length;
|
|
if (len > lstr) len = lstr;
|
|
mstr = p.Substring(0,len);
|
|
mstr = mstr.TrimEnd(" \t\r\n".ToCharArray());
|
|
/* debug
|
|
string debugstr = "|" + mstr + "|";
|
|
*/
|
|
|
|
PrivateProfile set_ini = new PrivateProfile("set.ini");
|
|
|
|
tonum = set_ini.Attr("replace", mstr);
|
|
if (tonum == null || tonum.Equals("")) tonum = mstr;
|
|
newl = tonum.Length;
|
|
dw = newl - (lstr);
|
|
|
|
q = str; p = tonum;
|
|
int strptr=0;
|
|
for (strptr=0; str[strptr] == ' '; strptr++)
|
|
rbldr.Append(" ");//initial spaces
|
|
int pptr=0;
|
|
while (cnt < len)
|
|
{
|
|
if (tonum!=null && pptr < tonum.Length)
|
|
rbldr.Append(tonum[pptr++]);
|
|
else if (trm == 1) break;
|
|
else if (cnt < lstr) rbldr.Append(" ");
|
|
else break;
|
|
cnt++;
|
|
}
|
|
if (trm==0)
|
|
{
|
|
strptr+=len;
|
|
while (str!=null && strptr < str.Length)
|
|
rbldr.Append(str[strptr++]);
|
|
}
|
|
retvalu = rbldr.ToString();
|
|
}
|
|
else
|
|
{
|
|
retvalu=str;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
StringBuilder rbldr = new StringBuilder();
|
|
// create pointers to use to transfer info
|
|
int pnumPtr = 0, strPtr=0, endStrPtr = str.Length-1;
|
|
string pad = "";
|
|
// determine if the procedure number should be padded instead
|
|
if(str[0]==' ')pad=" ";
|
|
// copy from the procedure number definition to the pound symbol
|
|
if (!pnum.Equals(""))
|
|
{
|
|
while(pnumPtr < pnum.Length && pnum[pnumPtr] != '#')
|
|
{
|
|
rbldr.Append(((!pad.Equals(""))? pad : pnum[pnumPtr].ToString()));
|
|
pnumPtr++;
|
|
}
|
|
// skip the pound sign
|
|
if(pnumPtr < pnum.Length && pnum[pnumPtr]!=0)pnumPtr++;
|
|
}
|
|
// assuming that the procedure number occurs at the beginning of
|
|
// str, check to see where it ends
|
|
if(str.Length > len)endStrPtr=len-1;
|
|
// find the end of the procedure number
|
|
while(endStrPtr > strPtr && str[endStrPtr]==' ')endStrPtr--;
|
|
// copy the procedure number
|
|
while(strPtr <= endStrPtr)rbldr.Append(str[strPtr++]);
|
|
// copy the rest of the format
|
|
while(pnumPtr < pnum.Length)
|
|
{
|
|
rbldr.Append(((!pad.Equals(""))? pad : pnum[pnumPtr].ToString()));
|
|
pnumPtr++;
|
|
}
|
|
// copy the rest of the given string
|
|
while(strPtr < str.Length)rbldr.Append(str[strPtr++]);
|
|
retvalu = rbldr.ToString();
|
|
}
|
|
return retvalu;
|
|
}
|
|
|
|
public static int matchingBrace(string str)
|
|
{
|
|
int strptr = 0;
|
|
int level=1;
|
|
while(level > 0)
|
|
{
|
|
strptr++;
|
|
switch(str[strptr])
|
|
{
|
|
case '{':
|
|
level++;
|
|
break;
|
|
case '}':
|
|
level--;
|
|
break;
|
|
}
|
|
}
|
|
return strptr;
|
|
}
|
|
|
|
public static int nextDelimiter(string delim,string str,int l)
|
|
{
|
|
int nxtdelim = -1;
|
|
int strptr = 0;
|
|
while(l-- > 0 && (nxtdelim == -1))
|
|
{
|
|
if (delim.IndexOf(str[strptr])>-1)
|
|
nxtdelim = strptr;
|
|
strptr++;
|
|
}
|
|
return nxtdelim;
|
|
}
|
|
|
|
public static string getProfile(string grp, string nam)
|
|
{
|
|
return getProfile(grp,nam,0);
|
|
}
|
|
|
|
public static string getProfile(string grp, string nam, int flag)
|
|
{
|
|
string buff=null;
|
|
if( grp==null ) return null;
|
|
PrivateProfile proc_ini = new PrivateProfile("proc.ini");
|
|
buff = proc_ini.Attr(grp,nam);
|
|
if (buff == null)
|
|
buff = "";
|
|
if(buff.Equals(""))
|
|
{
|
|
if (flag == 0)
|
|
buff = "<" + grp + "-" + nam + ">";
|
|
else
|
|
return null;
|
|
}
|
|
return buff;
|
|
}
|
|
|
|
public static string evaluate(string str,int len)
|
|
{
|
|
string retval=null;
|
|
string swhir = "PSU"; /* order inwhich to check */
|
|
string pn;
|
|
if(str[1]=='-')
|
|
{
|
|
int swptr = swhir.IndexOf((str.ToUpper())[0]);
|
|
byte swchar = 0;
|
|
if( swptr > -1 ) swchar = (byte)swhir[swptr];
|
|
|
|
byte sav=(byte)str[len];
|
|
str = str.Substring(0,len);
|
|
while ((swptr > -1) && (swhir[swptr] != 0) && retval == null)
|
|
{
|
|
if (swchar == 0) swchar = (byte)str[0];
|
|
switch((char)swchar)
|
|
{
|
|
case 'U':
|
|
retval=getProfile("Unit",str.Substring(2),swhir[swptr]);
|
|
break;
|
|
case 'S':
|
|
retval=getProfile("Procedure Set",str.Substring(2),swhir[swptr]);
|
|
break;
|
|
case 'P':
|
|
pn = UnitSpecific(PNumber, 0, 1, mxPrcLen);
|
|
retval=getProfile(pn,str.Substring(2),swhir[swptr]);
|
|
break;
|
|
}
|
|
if (retval == null)
|
|
swchar= (byte)swhir[++swptr];
|
|
}
|
|
StringBuilder sb1 = new StringBuilder(str);
|
|
sb1.Insert(len,sav);
|
|
str = sb1.ToString();
|
|
}
|
|
else if(len==1 && (str.ToUpper())[0]=='U')
|
|
{
|
|
retval=getProfile("Unit","Number");
|
|
}
|
|
else if(len==2 && str.ToUpper().StartsWith("ID"))
|
|
{
|
|
retval=getProfile("Unit","ID");
|
|
}
|
|
if(retval == null)
|
|
{
|
|
retval=str.Substring(0,len+2>str.Length?str.Length:len+2);
|
|
}
|
|
return retval;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Summary description for ROFSTHeader.
|
|
/// </summary>
|
|
|
|
public class FST_FileHeader
|
|
{
|
|
public int hSize; // size of header structure (record)
|
|
public short hYear;// year this header was designed (1993)
|
|
public byte hMonth;// month this header was designed (10)
|
|
public byte hDay;// day this header was designed (25)
|
|
public short hcYear;// FST file creation year
|
|
public byte hcMonth;// FST file creation month
|
|
public byte hcDay;// FST file creation day
|
|
public byte hcHour;// FST file creation hour
|
|
public byte hcMin;// FST file creation minute
|
|
public byte hcSec;// FST file creation seconds
|
|
public byte hcHund;// FST file creation hundredth seconds
|
|
public uint dboffset;// end of RO data, start of database list
|
|
|
|
|
|
// Constructors
|
|
// default constructor creates with zero'd out values
|
|
public FST_FileHeader()
|
|
{
|
|
hSize = 0;
|
|
hYear = 0;
|
|
hMonth = 0;
|
|
hDay = 0;
|
|
hcYear = 0;
|
|
hcMonth = 0;
|
|
hcDay = 0;
|
|
hcHour = 0;
|
|
hcMin = 0;
|
|
hcSec = 0;
|
|
hcHund = 0;
|
|
dboffset = 0;
|
|
}
|
|
|
|
|
|
// Constructor that initializes with pass in values
|
|
FST_FileHeader(int Size, short Year, byte Month, byte Day, short cYear, byte cMonth,
|
|
byte cDay, byte cHour, byte cMin, byte cSec, byte cHund, uint offset)
|
|
{
|
|
hSize = Size;
|
|
hYear = Year;
|
|
hMonth = Month;
|
|
hDay = Day;
|
|
hcYear = cYear;
|
|
hcMonth = cMonth;
|
|
hcDay = cDay;
|
|
hcHour = cHour;
|
|
hcMin = cMin;
|
|
hcSec = cSec;
|
|
hcHund = cHund;
|
|
dboffset = offset;
|
|
}
|
|
|
|
|
|
public void Read (BinaryReader br)
|
|
{
|
|
hSize = br.ReadInt32();
|
|
hYear = br.ReadInt16();
|
|
hMonth = br.ReadByte();
|
|
hDay = br.ReadByte();
|
|
hcYear = br.ReadInt16();
|
|
hcMonth = br.ReadByte();
|
|
hcDay = br.ReadByte();
|
|
hcHour = br.ReadByte();
|
|
hcMin = br.ReadByte();
|
|
hcSec = br.ReadByte();
|
|
// byte tbyte = br.ReadByte();
|
|
// hcHund = (sbyte)tbyte;
|
|
hcHund = br.ReadByte();
|
|
dboffset = br.ReadUInt32();
|
|
|
|
// return new FST_FileHeader(fSize,fYear,fMonth,fDay,
|
|
// fcYear,fcMonth,fcDay,fcHour,fcMin,fcSec,fcHund,fdboffset);
|
|
}
|
|
|
|
|
|
public void Write (BinaryWriter bw)
|
|
{
|
|
bw.Write(hSize);
|
|
bw.Write(hYear);
|
|
bw.Write(hMonth);
|
|
bw.Write(hDay);
|
|
bw.Write(hcYear);
|
|
bw.Write(hcMonth);
|
|
bw.Write(hcDay);
|
|
bw.Write(hcHour);
|
|
bw.Write(hcMin);
|
|
bw.Write(hcSec);
|
|
bw.Write(hcHund);
|
|
bw.Write(dboffset);
|
|
}
|
|
|
|
|
|
public int GetStructSize()
|
|
{
|
|
int rtval = 0;
|
|
|
|
// You can only use sizeof() in unsafe compiles
|
|
// so we'll do it by hand...
|
|
// each number is the number of bytes
|
|
|
|
rtval += 4; //sizeof(hSize);
|
|
rtval += 2; //sizeof(hYear);
|
|
rtval += 1; //sizeof(hMonth);
|
|
rtval += 1; //sizeof(hDay);
|
|
rtval += 2; //sizeof(hcYear);
|
|
rtval += 1; //sizeof(hcMonth);
|
|
rtval += 1; //sizeof(hcDay);
|
|
rtval += 1; //sizeof(hcHour);
|
|
rtval += 1; //sizeof(hcMin);
|
|
rtval += 1; //sizeof(hcSec);
|
|
rtval += 1; //sizeof(hcHund);
|
|
rtval += 4; //sizeof(dboffset);
|
|
|
|
return rtval;
|
|
}
|
|
|
|
|
|
public void SetHeader(uint offset)
|
|
{
|
|
hSize = GetStructSize();
|
|
hYear = 1993;
|
|
hMonth = 10;
|
|
hDay = 25;
|
|
DateTime dt = DateTime.Now;
|
|
hcYear = (short)dt.Year;
|
|
hcMonth = (byte)dt.Month;
|
|
hcDay = (byte)dt.Day;
|
|
hcHour = (byte)dt.Hour;
|
|
hcMin = (byte)dt.Minute;
|
|
hcSec = (byte)dt.Second;
|
|
hcHund = (byte)dt.Millisecond;
|
|
dboffset = offset;
|
|
}
|
|
}
|
|
|
|
|
|
public class ROFST_DbInfo
|
|
{
|
|
public ushort dbiID; // Number part of table name (RO000002 => 02)
|
|
public ushort dbiType; // database type (Setpoint,Graphics,User defined)
|
|
public ushort dbiAW; // length of widest AccPageID
|
|
public uint dbiGL; // FST file position of this group
|
|
public uint dbiIL; // FST file position of list of ROIDs
|
|
public uint dbiAL; // FST file position of list of AccPageIDs
|
|
public uint dbiEND; // FST file position of the end of this group
|
|
// !!! make sure to convert strings to char arrays when writing
|
|
public string dbiTitle; // database title
|
|
public string dbiAP; // AccPageID Prefix (ex. SP- )
|
|
|
|
|
|
// Constructors
|
|
// default constructor creates with zero'd out values
|
|
public ROFST_DbInfo()
|
|
{
|
|
dbiID = 0;
|
|
dbiType = 0;
|
|
dbiAW = 0;
|
|
dbiGL = 0;
|
|
dbiIL = 0;
|
|
dbiAL = 0;
|
|
dbiEND = 0;
|
|
dbiTitle = "";
|
|
dbiAP = "";
|
|
}
|
|
|
|
|
|
// Constructor that initializes with pass in values
|
|
ROFST_DbInfo(ushort ID, ushort Type, ushort AW, uint GL, uint IL, uint AL, uint END,
|
|
string Title, string dbiAP)
|
|
{
|
|
dbiID = ID;
|
|
dbiType = Type;
|
|
dbiAW = AW;
|
|
dbiGL = GL;
|
|
dbiIL = IL;
|
|
dbiAL = AL;
|
|
dbiEND = END;
|
|
dbiTitle = Title;
|
|
dbiAP = dbiAP;
|
|
}
|
|
|
|
|
|
public void WriteUntAndShort(BinaryWriter bw)
|
|
{
|
|
bw.Write(dbiID);
|
|
bw.Write(dbiType);
|
|
bw.Write(dbiAW);
|
|
bw.Write(dbiGL);
|
|
bw.Write(dbiIL);
|
|
bw.Write(dbiAL);
|
|
bw.Write(dbiEND);
|
|
}
|
|
|
|
|
|
void WriteString(BinaryWriter bw, string str)
|
|
{
|
|
byte nullbyte = 0;
|
|
byte []wrBytes = new byte[str.Length + 1];
|
|
int i;
|
|
for(i =0; i < str.Length; i++)
|
|
{
|
|
// byte WrByte;
|
|
// WrByte = (byte)str[i];
|
|
// bw.Write(WrByte);
|
|
wrBytes[i] = (byte)str[i];
|
|
}
|
|
wrBytes[i] = nullbyte;
|
|
bw.Write(wrBytes);
|
|
// bw.Write(nullbyte);
|
|
}
|
|
|
|
|
|
public void WriteStrings(BinaryWriter bw)
|
|
{
|
|
WriteString(bw,dbiTitle);
|
|
WriteString(bw,dbiAP);
|
|
}
|
|
|
|
|
|
public uint GetStructSize()
|
|
{
|
|
uint rtval = 0;
|
|
|
|
// You can only use sizeof() in unsafe compiles
|
|
// so we'll do it by hand...
|
|
// each number is the number of bytes
|
|
|
|
rtval += 2; //sizeof(dbiID);
|
|
rtval += 2; //sizeof(dbiType);
|
|
rtval += 2; //sizeof(dbiAW);
|
|
rtval += 4; //sizeof(dbiGL);
|
|
rtval += 4; //sizeof(dbiIL);
|
|
rtval += 4; //sizeof(dbiAL);
|
|
rtval += 4; //sizeof(dbiEND);
|
|
rtval += 4; //sizeof(uint); // to simulate the (char *) in the old code (16 datatypes)
|
|
rtval += 4; //sizeof(uint); // to simulate the (char *) in the old code (16 datatypes)
|
|
|
|
return rtval;
|
|
}
|
|
|
|
|
|
public void Load(BinaryReader br)
|
|
{
|
|
ReadValues(br);
|
|
}
|
|
|
|
// public void ReadStrings(BinaryReader br)
|
|
// {
|
|
// dbiTitle = ROFST_File.LoadString(br);
|
|
// dbiAP = ROFST_File.LoadString(br);
|
|
// }
|
|
|
|
|
|
public void ReadValues(BinaryReader br)
|
|
{
|
|
dbiID = br.ReadUInt16();
|
|
dbiType = br.ReadUInt16();
|
|
dbiAW = br.ReadUInt16();
|
|
dbiGL = br.ReadUInt32();
|
|
dbiIL = br.ReadUInt32();
|
|
dbiAL = br.ReadUInt32();
|
|
dbiEND = br.ReadUInt32();
|
|
uint tmp = br.ReadUInt32();
|
|
uint tmp1 = br.ReadUInt32();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// structure to hold information to add a new group
|
|
public struct AddGroup
|
|
{
|
|
public uint grp_id;
|
|
public uint grp_parid;
|
|
public string grp_name;
|
|
public short grp_type;
|
|
public short grp_stat;
|
|
public uint grp_offset;
|
|
public int grp_pargrpidx;
|
|
|
|
|
|
// These functions are needed to update values when
|
|
// referenced from the ArrayLists (allNewGrps)
|
|
// public void OR_grp_type(short val)
|
|
// {
|
|
// ushort gtype = (ushort)grp_type;
|
|
// gtype |= (ushort)val;
|
|
// grp_type = (short)gtype;
|
|
// }
|
|
//
|
|
//
|
|
// public void SET_grp_parid(uint val)
|
|
// {
|
|
// grp_parid = val;
|
|
// }
|
|
//
|
|
//
|
|
// public void SET_grp_pargrpidx(int val)
|
|
// {
|
|
// grp_pargrpidx = val;
|
|
// }
|
|
//
|
|
//
|
|
// public void SET_grp_stat(short val)
|
|
// {
|
|
// grp_stat = val;
|
|
// }
|
|
//
|
|
//
|
|
// public void SET_grp_offset(uint val)
|
|
// {
|
|
// grp_offset = val;
|
|
// }
|
|
}
|
|
|
|
|
|
// structure to hold information to add a new RO
|
|
public struct AddRO
|
|
{
|
|
public uint ro_id;
|
|
public uint ro_parid;
|
|
public string ro_num;
|
|
public string ro_desc;
|
|
public string ro_val;
|
|
public short ro_type;
|
|
public short ro_stat;
|
|
public int ro_offset;
|
|
public int ro_pargrpidx; // index into allNewGrps
|
|
|
|
|
|
// These functions are needed to update values when
|
|
// referenced from the ArrayLists (allNewRos)
|
|
// public void SET_ro_pargrpidx(int val)
|
|
// {
|
|
// ro_pargrpidx = val;
|
|
// }
|
|
//
|
|
//
|
|
// public void SET_ro_parid(uint val)
|
|
// {
|
|
// ro_parid = val;
|
|
// }
|
|
//
|
|
//
|
|
// public void SET_ro_stat(short val)
|
|
// {
|
|
// ro_stat = val;
|
|
// }
|
|
//
|
|
//
|
|
// public void SET_ro_offset(int val)
|
|
// {
|
|
// ro_offset = val;
|
|
// }
|
|
}
|
|
|
|
|
|
// structure to hold RO difference information
|
|
public struct DiffRO
|
|
{
|
|
public uint id;
|
|
public short type;
|
|
public string desc;
|
|
public string val;
|
|
public uint oldoff; // index into old RO.FST file (approved)
|
|
}
|
|
|
|
|
|
// RO update info arrays.
|
|
// one of these structures is created from each RO database
|
|
// (Setpoints, Graphics, User Defined, etc.)
|
|
public struct dbinew
|
|
{
|
|
public ArrayList aryAddedRO;
|
|
public ArrayList aryAddedGroup;
|
|
public ArrayList aryAddedDiff;
|
|
}
|
|
|
|
|
|
// structure to store file positions in the RO.FST file
|
|
public struct locinc
|
|
{
|
|
public uint maxloc;
|
|
public int inc;
|
|
}
|
|
|
|
|
|
/*
|
|
** Structure of the graphics' values.
|
|
** LocalGrfStats ( in ROFST_File class) is used to hold the current
|
|
** values "locally" in memory
|
|
*/
|
|
public struct GrfStats
|
|
{
|
|
public string PixFileName;
|
|
public int PixFileTime;
|
|
public short PixFileHeight;
|
|
public short PixFileWidth;
|
|
|
|
public void Clear()
|
|
{
|
|
PixFileName="";
|
|
PixFileTime = 0;
|
|
PixFileHeight = 0;
|
|
PixFileWidth = 0;
|
|
}
|
|
|
|
public void Load(string instr)
|
|
{
|
|
short DeciPerRow = 120;
|
|
short DeciPerCol = 60;
|
|
StringBuilder sb = new StringBuilder();
|
|
int i=0;
|
|
bool nl = false;
|
|
/*
|
|
sscanf(retval,"%s\n%08lx\n%04x\n%04x",LocalGrfStats.PixFileName,
|
|
&LocalGrfStats.PixFileTime,&LocalGrfStats.PixFileHeight,
|
|
&LocalGrfStats.PixFileWidth);
|
|
LocalGrfStats.PixFileHeight *= DeciPerRow;
|
|
LocalGrfStats.PixFileWidth *= DeciPerCol;
|
|
*/
|
|
while (!nl && (instr[i]!= 0))
|
|
{
|
|
if (instr[i]=='\n')
|
|
nl=true;
|
|
else
|
|
sb.Append(instr[i]);
|
|
i++;
|
|
}
|
|
if (nl)
|
|
{
|
|
PixFileName = sb.ToString();
|
|
}
|
|
|
|
nl = false;
|
|
sb.Remove(0,sb.Length);
|
|
while (!nl && (instr[i]!=0))
|
|
{
|
|
if (instr[i]=='\n')
|
|
nl=true;
|
|
else
|
|
sb.Append(instr[i]);
|
|
i++;
|
|
}
|
|
PixFileTime = Convert.ToInt32(sb.ToString(),16);
|
|
|
|
nl = false;
|
|
sb.Remove(0,sb.Length);
|
|
while (!nl && (instr[i]!=0))
|
|
{
|
|
if (instr[i]=='\n')
|
|
nl=true;
|
|
else
|
|
sb.Append(instr[i]);
|
|
i++;
|
|
}
|
|
PixFileHeight = Convert.ToInt16(sb.ToString(),16);
|
|
PixFileHeight *= DeciPerRow;
|
|
|
|
sb.Remove(0,sb.Length);
|
|
while ((i < instr.Length) && (instr[i]!=0))
|
|
{
|
|
sb.Append(instr[i]);
|
|
i++;
|
|
}
|
|
PixFileWidth = Convert.ToInt16(sb.ToString(),16);
|
|
PixFileWidth *= DeciPerCol;
|
|
}
|
|
}
|
|
|
|
|
|
public class ROFST_File
|
|
{
|
|
public enum ROTypes
|
|
{
|
|
None=0, Text=1, Table=2, Plot=4, Figure=8
|
|
};
|
|
|
|
private string [] UnitVariables =
|
|
{
|
|
"All of the following",//
|
|
"Number", // 1L; - 1, 2 etc.
|
|
"Other Number", // 2L; - 2, 1 etc.
|
|
"Text", // 3L; - One, Two etc. or Unit One, Unit Two
|
|
"Other Text", // 4L; - Two, One etc. or Unit Two, Unit One
|
|
"ID", // 5L; - 1Bw, 2Bw etc.
|
|
"Other ID", // 6L; - 2Bw, 1Bw etc.
|
|
"Name", // 7L; - Braidwood Unit 1
|
|
"Other Name" // 8L; - Braidwood Unit 2
|
|
};
|
|
private uint NumUnitVariables =9;
|
|
|
|
|
|
private ArrayList [] allNewRos; // new ROs
|
|
private ArrayList [] allDifferences; // changed ROs
|
|
private ArrayList [] allNewGrps; // new Groups
|
|
private ArrayList allLocations; // positions in RO.FST
|
|
|
|
|
|
private int curTblIdx=0; // index into allxxxxx arraylists
|
|
private uint NewID = 0xFFFF0000;
|
|
private uint whereisgl = 0;
|
|
private ushort maxaw=0;
|
|
private ushort maxtype=0;
|
|
private int lastLocationIdx = 0;
|
|
|
|
public BinaryReader brROFst; // file handle into RO.FST
|
|
public ArrayList DatabasesInfo; // Holds the current RO.FST data
|
|
public ArrayList dbiNewInfo; // will hold new RO.FST data
|
|
|
|
public short numDatabases; // number of databases in RO.FST
|
|
public FST_FileHeader Header;
|
|
// public UserRunTime usrRunTime;
|
|
public string DirPath;
|
|
|
|
public string DefaultGraphicFileExt = "";
|
|
|
|
// RO Graphics information
|
|
GrfStats LocalGrfStats;
|
|
|
|
// constructor loads ro.fst databases
|
|
// public ROFST(string path, UserRunTime urt)
|
|
public ROFST_File(string path)
|
|
{
|
|
try
|
|
{
|
|
brROFst = new BinaryReader(File.Open(path,System.IO.FileMode.Open,System.IO.FileAccess.ReadWrite,FileShare.ReadWrite));
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
MessageBox.Show("Open "+path+"\n\n" + e.Message,"RO.FST Error");
|
|
return;
|
|
}
|
|
DirPath = path; // path of RO.FST file
|
|
|
|
// usrRunTime = urt;
|
|
|
|
// Read the RO.FST header information
|
|
Header = new FST_FileHeader();
|
|
Header.Read(brROFst);
|
|
brROFst.BaseStream.Seek(Header.dboffset,SeekOrigin.Begin);
|
|
uint howbig = brROFst.ReadUInt32();
|
|
short howmany = brROFst.ReadInt16();
|
|
|
|
numDatabases = howmany;
|
|
// dbcount = numDatabases;
|
|
DatabasesInfo = new ArrayList();
|
|
dbiNewInfo = new ArrayList();
|
|
|
|
// Load the database into the arrays
|
|
for (int i=0;i<numDatabases;i++)
|
|
{
|
|
dbinew dbinewItem;
|
|
ROFST_DbInfo tmpDBinfo;
|
|
tmpDBinfo = new ROFST_DbInfo();
|
|
tmpDBinfo.Load(brROFst);
|
|
DatabasesInfo.Add(tmpDBinfo);
|
|
dbinewItem = new dbinew();
|
|
dbiNewInfo.Add(dbinewItem);
|
|
}
|
|
for (int i=0;i<numDatabases;i++)
|
|
{
|
|
// load the titles and accessory page ids
|
|
// ((ROFST_DbInfo)DatabasesInfo[i]).ReadStrings(brROFst);
|
|
((ROFST_DbInfo)DatabasesInfo[i]).dbiTitle = GetAsciiString(brROFst);
|
|
((ROFST_DbInfo)DatabasesInfo[i]).dbiAP = GetAsciiString(brROFst);
|
|
}
|
|
// get the default graphic file extension
|
|
GetDefaultGraphicFileExtension();
|
|
}
|
|
|
|
|
|
~ ROFST_File()
|
|
{
|
|
if (brROFst!=null)brROFst.Close();
|
|
}
|
|
|
|
public void Close()
|
|
{
|
|
if (brROFst!=null)brROFst.Close();
|
|
brROFst=null;
|
|
}
|
|
|
|
private void GetDefaultGraphicFileExtension()
|
|
{
|
|
// get the full path to the VEPROMS.INI file
|
|
string ApplicationPath = Application.StartupPath;
|
|
string ApplPathUp = ApplicationPath.ToUpper();
|
|
int idx = ApplPathUp.IndexOf("VE-PROMS.NET\\BIN");
|
|
string PromsINI = ApplicationPath.Substring(0,idx);
|
|
PromsINI += "VE-PROMS\\VEPROMS.INI";
|
|
|
|
PrivateProfile extINI = new PrivateProfile(PromsINI);
|
|
string defGrExt=extINI.Attr("Graphics", "defaultext");
|
|
if (defGrExt == null || defGrExt == "")
|
|
{
|
|
// check the ROAPP.INI in the RO directory
|
|
string ropath = extINI.Attr("RO Defaults","ROPATH");
|
|
if (ropath == null || ropath == "") ropath = "..\\RO";
|
|
string src = ropath + "\\ROAPP.INI";
|
|
if (File.Exists(src))
|
|
{
|
|
PrivateProfile roappINI = new PrivateProfile(src);
|
|
defGrExt = roappINI.Attr("ROApp","Extention");
|
|
}
|
|
if (defGrExt == null || defGrExt == "")
|
|
defGrExt="TIF";
|
|
}
|
|
DefaultGraphicFileExt = defGrExt;
|
|
}
|
|
|
|
|
|
// Find the location of an RO value in the RO.FST file
|
|
private uint FindRO(uint id, uint start, uint end)
|
|
{
|
|
uint retval=0;
|
|
uint topid=0,botid=0,recs=0,siz=0;
|
|
siz=8; // c code:sizeof(topid)*2;
|
|
recs=(end-start)/siz;
|
|
uint guessr,guess=0,guessid=0;
|
|
uint botr=0,topr=recs;
|
|
//getID(end-siz,&topoff);
|
|
brROFst.BaseStream.Seek(end-siz,SeekOrigin.Begin);
|
|
topid=brROFst.ReadUInt32();
|
|
|
|
if(id==topid)return end-siz; // Last record
|
|
|
|
//getID(start,&botoff);
|
|
brROFst.BaseStream.Seek(start,SeekOrigin.Begin);
|
|
botid=brROFst.ReadUInt32();
|
|
|
|
if(id==botid)return start; // First record
|
|
|
|
if(id < botid || id > topid)return 0; // Beyond range
|
|
while (topr > botr+1)
|
|
{
|
|
guessr=botr+((topr-botr)*(id-botid))/(topid-botid);
|
|
|
|
if (guessr==botr) guessr=botr+1;
|
|
else if (guessr==topr) guessr=topr-1;
|
|
|
|
guess=start+guessr*siz;
|
|
brROFst.BaseStream.Seek(guess,SeekOrigin.Begin);
|
|
//getID(guess,&retval)
|
|
guessid=brROFst.ReadUInt32();
|
|
|
|
if(guessid==id)
|
|
{
|
|
break; // found, break out of while loop
|
|
}
|
|
else if(guessid < id)
|
|
{
|
|
botr=guessr;
|
|
botid=guessid;
|
|
}
|
|
else
|
|
{
|
|
topr=guessr;
|
|
topid=guessid;
|
|
}
|
|
}
|
|
if(guessid==id)retval=guess; // Any other record
|
|
return retval;
|
|
}
|
|
|
|
private uint _getID(uint off,ref uint nxtoff)
|
|
{
|
|
uint retval = 0;
|
|
if (off > 0)
|
|
{
|
|
brROFst.BaseStream.Seek(off,SeekOrigin.Begin);
|
|
retval = brROFst.ReadUInt32();
|
|
nxtoff = brROFst.ReadUInt32();
|
|
}
|
|
return retval;
|
|
}
|
|
|
|
// Find the location of an RO value in the RO.FST file
|
|
private uint toolsFindRO(uint id, uint start, uint end)
|
|
{
|
|
uint retval=0;
|
|
uint topid=0,botid=0,recs=0,siz=0;
|
|
siz=8; // c code:sizeof(topid)*2;
|
|
recs=(end-start)/siz; //c code: (end-start)>>3
|
|
uint guessr,guess=0,guessid=0;
|
|
uint botr=0,topr=recs;
|
|
uint topoff =0, botoff=0;
|
|
//getID(end-siz,&topoff);
|
|
topid=_getID(end-siz,ref topoff);
|
|
if(id==topid)return topoff; // Last record
|
|
|
|
//getID(start,&botoff);
|
|
botid=_getID(start,ref botoff);
|
|
if(id==botid)return botoff; // First record
|
|
|
|
if(id < botid || id > topid)return 0; // Beyond range
|
|
while (topr > botr+1)
|
|
{
|
|
guessr=botr+((topr-botr)/2);
|
|
|
|
if (guessr==botr) guessr++;
|
|
else if (guessr==topr) guessr--;
|
|
|
|
//getID(guess,&retval)
|
|
guessid=_getID(start+guessr*siz,ref retval);
|
|
|
|
if(guessid==id)
|
|
{
|
|
break; // found, break out of while loop
|
|
}
|
|
else if(guessid < id)
|
|
{
|
|
botr=guessr;
|
|
botid=guessid;
|
|
}
|
|
else
|
|
{
|
|
topr=guessr;
|
|
topid=guessid;
|
|
}
|
|
}
|
|
if (guessid == id) return retval;
|
|
return 0;
|
|
}
|
|
|
|
|
|
// return the type of the given RO
|
|
private ROTypes FindROType(uint rec, uint start, uint end)
|
|
{
|
|
short retval=0;
|
|
byte[] tbyte= new byte[100];
|
|
uint fnd;
|
|
if((fnd=FindRO(rec,start,end))>0)
|
|
{
|
|
uint offset=brROFst.ReadUInt32();
|
|
brROFst.BaseStream.Seek((long)offset,SeekOrigin.Begin);
|
|
uint guessid=brROFst.ReadUInt32();
|
|
uint parid=brROFst.ReadUInt32();
|
|
short count=brROFst.ReadInt16();
|
|
retval=brROFst.ReadInt16(); // RO Type
|
|
}
|
|
return (ROTypes)retval;
|
|
}
|
|
|
|
|
|
// Get the RO Type from the ROID
|
|
public ROTypes GetROType(string ROID)
|
|
{
|
|
// break up ROID into table and record
|
|
ushort tbl = System.Convert.ToUInt16(ROID.Substring(0,4),16);
|
|
uint rec = System.Convert.ToUInt32(ROID.Substring(4,8),16);
|
|
ushort opt=0;
|
|
if (ROID.Length>12) opt = System.Convert.ToUInt16(ROID.Substring(8,ROID.Length-12),16);
|
|
if (tbl==0xFFFF)
|
|
return ROTypes.None; // 0xFFFF is ro from proc.ini file
|
|
int num=0;
|
|
for (int i=0; i < numDatabases && ((ROFST_DbInfo)DatabasesInfo[i]).dbiID!=tbl;i++) num++;
|
|
if (num < numDatabases)
|
|
{
|
|
return FindROType(rec,((ROFST_DbInfo)DatabasesInfo[num]).dbiIL,((ROFST_DbInfo)DatabasesInfo[num]).dbiAL);
|
|
}
|
|
return ROTypes.None;
|
|
}
|
|
|
|
|
|
private string FindROText(uint id, uint start,uint end)
|
|
{
|
|
string retval=null;
|
|
uint fnd;
|
|
if((fnd=FindRO(id,start,end))>0)
|
|
{
|
|
uint offset=brROFst.ReadUInt32();
|
|
brROFst.BaseStream.Seek((long)offset,SeekOrigin.Begin);
|
|
uint guessid=brROFst.ReadUInt32();
|
|
uint parid=brROFst.ReadUInt32();
|
|
short count=brROFst.ReadInt16();
|
|
ushort typ=brROFst.ReadUInt16();
|
|
if (count<0)retval=GetAsciiString(brROFst);
|
|
}
|
|
return retval;
|
|
}
|
|
|
|
|
|
// return the RO defined in the PROC.INI file
|
|
// (master / slave logic)
|
|
private string roUnitValue(uint rec)
|
|
{
|
|
string buff="";
|
|
PrivateProfile proc_ini = new PrivateProfile("proc.ini");
|
|
for(int i=0; i < NumUnitVariables; i++)
|
|
{
|
|
if((i+1) == rec)
|
|
{
|
|
buff = proc_ini.Attr("Unit",UnitVariables[i+1]);
|
|
if (buff == null || buff.Equals(""))
|
|
buff = "{"+ UnitVariables[i+1] + "}";
|
|
break; // break out of for loop
|
|
}
|
|
}
|
|
return buff;
|
|
}
|
|
|
|
|
|
//
|
|
// this function will take the ro text value and see 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
|
|
//
|
|
public string processMacros(string rostring)
|
|
{
|
|
StringBuilder bldstr = new StringBuilder();
|
|
int cptr = -1;
|
|
int stptr = 0;
|
|
if( rostring == null ) return rostring;
|
|
while( (cptr = rostring.IndexOf("@HSP(",stptr)) != -1 )
|
|
{
|
|
bldstr.Append(rostring.Substring(0,cptr-stptr));
|
|
int cptr2 = rostring.IndexOf(")",cptr);
|
|
if (cptr2 != -1)
|
|
{
|
|
int numspaces = cptr2 - cptr - 5;
|
|
for (int i=0; i< numspaces; i++)
|
|
bldstr.Append("\xFF");
|
|
stptr = cptr2 + 1;
|
|
}
|
|
else
|
|
{
|
|
bldstr.Append(rostring.Substring(cptr,5));
|
|
stptr += 5;
|
|
}
|
|
}
|
|
if (stptr < rostring.Length)
|
|
bldstr.Append(rostring.Substring(stptr));
|
|
return bldstr.ToString();
|
|
}
|
|
|
|
|
|
|
|
private string processROString(string rostr, short menuitem)
|
|
{
|
|
string newstr="";
|
|
strList2 strlst2 = new strList2(rostr);
|
|
strList strlst = new strList(strlst2.toText());
|
|
newstr = strlst.toText((int)menuitem);
|
|
|
|
newstr = newstr.Replace("\\n","\n");
|
|
newstr = processMacros(newstr);
|
|
return newstr;
|
|
}
|
|
|
|
|
|
public string GetRO(string ROID)
|
|
{
|
|
return _GetRO(ROID,1);
|
|
}
|
|
|
|
public string GetEntireRO(string ROID)
|
|
{
|
|
return _GetRO(ROID,0);
|
|
}
|
|
|
|
public string GetRO(string ROID, string ProcNum)
|
|
{
|
|
ROProcessTools.ProcedureNumber = ProcNum;
|
|
return GetRO(ROID);
|
|
}
|
|
|
|
public string GetEntireRO(string ROID, string ProcNum)
|
|
{
|
|
ROProcessTools.ProcedureNumber = ProcNum;
|
|
return GetEntireRO(ROID);
|
|
}
|
|
|
|
// Get the RO value from the ROID
|
|
private string _GetRO(string ROID_in, short procopt)
|
|
{
|
|
string ROID = ROID_in;
|
|
if (ROID.Length == 12)
|
|
ROID = ROID + "0000";
|
|
ushort tbl = System.Convert.ToUInt16(ROID.Substring(0,4),16);
|
|
uint rec = System.Convert.ToUInt32(ROID.Substring(4,8),16);
|
|
ushort opt=0;
|
|
// clear graphics info
|
|
LocalGrfStats.Clear();
|
|
opt = System.Convert.ToUInt16(ROID.Substring(12,ROID.Length-12),16);
|
|
|
|
if (tbl==0xFFFF)
|
|
return roUnitValue(rec); // RO in PROC.INI file
|
|
|
|
int num=0;
|
|
for(int i=0; i < numDatabases && ((ROFST_DbInfo)DatabasesInfo[i]).dbiID!=tbl;i++) num++;
|
|
|
|
string retval = null;
|
|
if(num < numDatabases)
|
|
{
|
|
retval=FindROText(rec,((ROFST_DbInfo)DatabasesInfo[num]).dbiIL,((ROFST_DbInfo)DatabasesInfo[num]).dbiAL);
|
|
}
|
|
if ((retval!=null&&retval!="") && (GetROType(ROID)==ROTypes.Figure))
|
|
{
|
|
// load graphic stats
|
|
StringBuilder sbtmp = new StringBuilder();
|
|
LocalGrfStats.Load(retval);
|
|
sbtmp.Append(LocalGrfStats.PixFileName);
|
|
sbtmp.Append("\n");
|
|
sbtmp.Append(LocalGrfStats.PixFileTime.ToString("x8"));
|
|
sbtmp.Append("\n");
|
|
sbtmp.Append(LocalGrfStats.PixFileHeight.ToString("x4"));
|
|
sbtmp.Append("\n");
|
|
sbtmp.Append(LocalGrfStats.PixFileWidth.ToString("x4"));
|
|
retval = sbtmp.ToString();
|
|
|
|
}
|
|
if(retval!=null && retval.Length>0 && !(GetROType(ROID)==ROTypes.Figure))
|
|
{
|
|
retval = retval.Replace("\r","");
|
|
if (procopt!=0)
|
|
{
|
|
string newstr = processROString(retval,(short)opt);
|
|
if (newstr!=null && !newstr.Equals(""))
|
|
retval = newstr;
|
|
}
|
|
}
|
|
return retval;
|
|
}
|
|
|
|
|
|
// Get the RO's parent ID
|
|
private uint GetParent(uint rec, uint start,uint end,ref uint offset)
|
|
{
|
|
uint parid=0;
|
|
uint fnd;
|
|
if((fnd=FindRO(rec,start,end))>0)
|
|
{
|
|
offset=brROFst.ReadUInt32();
|
|
brROFst.BaseStream.Seek((long)offset,SeekOrigin.Begin);
|
|
uint guessid=brROFst.ReadUInt32();
|
|
parid=brROFst.ReadUInt32();
|
|
}
|
|
return parid;
|
|
}
|
|
|
|
|
|
// Get the RO's parent ID from the ROID
|
|
public uint GetROParent(string ROID)
|
|
{
|
|
ushort tbl = Convert.ToUInt16(ROID.Substring(0,4),16);
|
|
uint rec = Convert.ToUInt32(ROID.Substring(4,8),16);
|
|
uint retval=0;
|
|
int indx=0;
|
|
for(int i=0; i < numDatabases && ((ROFST_DbInfo)DatabasesInfo[i]).dbiID!=tbl; i++) indx++; // position to the RO database
|
|
|
|
if(indx < numDatabases)
|
|
{
|
|
uint offset=0;
|
|
retval=GetParent(rec,((ROFST_DbInfo)DatabasesInfo[indx]).dbiIL,((ROFST_DbInfo)DatabasesInfo[indx]).dbiAL,ref offset);
|
|
}
|
|
return retval;
|
|
}
|
|
|
|
|
|
// Get the group title
|
|
private string GetDescription(ushort tbl, uint rec)
|
|
{
|
|
string retval=null;
|
|
if(tbl==0xFFFF)
|
|
{
|
|
if(rec == 0)
|
|
{
|
|
retval="Unit Information";
|
|
}
|
|
|
|
else if (rec <= NumUnitVariables)
|
|
{
|
|
int irec = (int)rec;
|
|
retval=UnitVariables[irec];
|
|
}
|
|
}
|
|
else
|
|
{
|
|
int indx=0;
|
|
for(int i=0; i < numDatabases && ((ROFST_DbInfo)DatabasesInfo[i]).dbiID!=tbl; i++) indx++;
|
|
|
|
if(indx < numDatabases)
|
|
{
|
|
uint id;
|
|
brROFst.BaseStream.Seek(((ROFST_DbInfo)DatabasesInfo[indx]).dbiGL,SeekOrigin.Begin);
|
|
id = brROFst.ReadUInt32();
|
|
|
|
if((rec==0) || rec==id)
|
|
{
|
|
retval=((ROFST_DbInfo)DatabasesInfo[indx]).dbiTitle;
|
|
}
|
|
else
|
|
{
|
|
uint offset=0;
|
|
uint parid = this.GetParent(rec,((ROFST_DbInfo)DatabasesInfo[indx]).dbiIL,((ROFST_DbInfo)DatabasesInfo[indx]).dbiAL,ref offset);
|
|
if(parid!=0)
|
|
{
|
|
uint t1 = FindRO(parid,((ROFST_DbInfo)DatabasesInfo[indx]).dbiIL,((ROFST_DbInfo)DatabasesInfo[indx]).dbiAL);
|
|
t1 = brROFst.ReadUInt32();
|
|
uint guessid;
|
|
brROFst.BaseStream.Seek(t1,SeekOrigin.Begin);
|
|
guessid = brROFst.ReadUInt32();
|
|
parid = brROFst.ReadUInt32();
|
|
short count;
|
|
count = brROFst.ReadInt16();
|
|
for(int i=0; i < count && retval == null; i++)
|
|
{
|
|
uint off;
|
|
off=brROFst.ReadUInt32();
|
|
ushort typ;
|
|
typ=brROFst.ReadUInt16();
|
|
if(off==offset)
|
|
{
|
|
retval = GetAsciiString(brROFst);
|
|
}
|
|
else
|
|
{
|
|
SkipString(brROFst);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return retval;
|
|
}
|
|
|
|
|
|
// Get the group title by ROID
|
|
public string GetRODescription(string ROID)
|
|
{
|
|
ushort tbl = Convert.ToUInt16(ROID.Substring(0,4),16);
|
|
uint rec = Convert.ToUInt32(ROID.Substring(4,8),16);
|
|
return (GetDescription(tbl,rec));
|
|
}
|
|
|
|
|
|
// get the Accessory Page ID
|
|
string FindROAccID(uint id, uint start, uint end)
|
|
{
|
|
// Returns allocated space
|
|
string retval=null;
|
|
if(FindRO(id,start,end)!=0)
|
|
{
|
|
uint offset = brROFst.ReadUInt32();
|
|
brROFst.BaseStream.Seek(offset,SeekOrigin.Begin);
|
|
uint guessid = brROFst.ReadUInt32();
|
|
uint parid = brROFst.ReadUInt32();
|
|
short count = brROFst.ReadInt16();
|
|
ushort ltyp = brROFst.ReadUInt16();
|
|
SkipString(brROFst);
|
|
retval = GetAsciiString(brROFst);
|
|
}
|
|
return retval;
|
|
}
|
|
|
|
|
|
private string roUnitAccID(uint rec)
|
|
{
|
|
string rotbuf="";
|
|
for(int i=0; i < NumUnitVariables; i++)
|
|
{
|
|
if((i+1L)==rec)
|
|
{
|
|
rotbuf = "U-"+UnitVariables[i+1];
|
|
break; // break out of for loop
|
|
}
|
|
}
|
|
return rotbuf;
|
|
}
|
|
|
|
|
|
// Get accessory page ID via the table and record
|
|
// also include unit specs from ini file
|
|
private string GetAccID(ushort tbl, uint rec)
|
|
{
|
|
string retval=null;
|
|
|
|
if (tbl==0xFFFF)
|
|
{
|
|
return roUnitAccID(rec); // PROC.INI ro
|
|
}
|
|
int indx=0;
|
|
for(int i=0; i < numDatabases && ((ROFST_DbInfo)DatabasesInfo[i]).dbiID!=tbl; i++)indx++;
|
|
|
|
if(indx < numDatabases)
|
|
{
|
|
retval=FindROAccID(rec,((ROFST_DbInfo)DatabasesInfo[indx]).dbiIL,((ROFST_DbInfo)DatabasesInfo[indx]).dbiAL);
|
|
if (retval == null)
|
|
retval=""; // RO not found, has ? in procedures
|
|
else
|
|
retval = ((ROFST_DbInfo)DatabasesInfo[indx]).dbiAP + "-" + retval;
|
|
}
|
|
return retval;
|
|
}
|
|
|
|
|
|
// Get the accessory page ID from the ROID
|
|
// includes unit specs from ini file
|
|
public string RoidToAccId(string ROID)
|
|
{
|
|
ushort tbl = Convert.ToUInt16(ROID.Substring(0,4),16);
|
|
uint rec = Convert.ToUInt32(ROID.Substring(4,8),16);
|
|
if(tbl != 0)
|
|
return GetAccID(tbl,rec);
|
|
return null;
|
|
}
|
|
|
|
|
|
// Get the accessory page ID
|
|
private string GetAppID(ushort tbl)
|
|
{
|
|
string retval = null;
|
|
if (tbl==0xFFFF)
|
|
{
|
|
return "U"; // PROC.INI ro
|
|
}
|
|
int indx=0;
|
|
for(int i=0; i < numDatabases && ((ROFST_DbInfo)DatabasesInfo[i]).dbiID!=tbl; i++) indx++;
|
|
|
|
if(indx < numDatabases)
|
|
return ((ROFST_DbInfo)DatabasesInfo[indx]).dbiAP;
|
|
return retval;
|
|
}
|
|
|
|
|
|
// Get the accessory page ID from the ROID
|
|
public string GetROAppID(string ROID)
|
|
{
|
|
ushort tbl = Convert.ToUInt16(ROID.Substring(0,4),16);
|
|
uint rec = Convert.ToUInt32(ROID.Substring(4,8),16);
|
|
return GetAppID(tbl);
|
|
}
|
|
|
|
|
|
public uint FindROFromTblRec(ushort tbl, uint id)
|
|
{
|
|
if(tbl==0xFFFF)
|
|
{
|
|
//PROC.INI ro
|
|
if (id < NumUnitVariables) return 1;
|
|
return 0;
|
|
}
|
|
int indx=0;
|
|
for(int i=0; i < numDatabases && ((ROFST_DbInfo)DatabasesInfo[i]).dbiID!=tbl;i++) indx++;
|
|
if (indx==numDatabases) return 0;
|
|
return FindRO(id,((ROFST_DbInfo)DatabasesInfo[indx]).dbiIL,((ROFST_DbInfo)DatabasesInfo[indx]).dbiAL);
|
|
}
|
|
|
|
|
|
public bool ROExists(string ROID)
|
|
{
|
|
ushort tbl = Convert.ToUInt16(ROID.Substring(0,4),16);
|
|
uint rec = Convert.ToUInt32(ROID.Substring(4,8),16);
|
|
uint off = FindROFromTblRec(tbl,rec);
|
|
return (off!=0);
|
|
}
|
|
|
|
|
|
public static void SkipString(BinaryReader br)
|
|
{
|
|
byte []input = {0};
|
|
do
|
|
{
|
|
try
|
|
{
|
|
input[0] = br.ReadByte();
|
|
}
|
|
catch (System.IO.EndOfStreamException)
|
|
{
|
|
input[0] = 0;
|
|
}
|
|
}while (input[0] != 0);
|
|
return;
|
|
}
|
|
|
|
|
|
public static string GetAsciiString(BinaryReader br, int len)
|
|
{
|
|
StringBuilder inpstr = new StringBuilder();
|
|
byte input = 0;
|
|
int cnt = 0;
|
|
do
|
|
{
|
|
try
|
|
{
|
|
input = br.ReadByte();
|
|
inpstr.Append(Convert.ToChar(input));
|
|
}
|
|
catch (System.IO.EndOfStreamException)
|
|
{
|
|
input = 0;
|
|
while (cnt < len)
|
|
{
|
|
inpstr.Append(Convert.ToChar(input));
|
|
cnt++;
|
|
}
|
|
}
|
|
cnt++;
|
|
}while (cnt < len);
|
|
|
|
return (inpstr.ToString());
|
|
}
|
|
|
|
|
|
public static string GetAsciiString(BinaryReader br)
|
|
{
|
|
StringBuilder inpstr = new StringBuilder();
|
|
byte input = 0;
|
|
do
|
|
{
|
|
try
|
|
{
|
|
input = br.ReadByte();
|
|
if (input > 0)
|
|
{
|
|
inpstr.Append(Convert.ToChar(input));
|
|
}
|
|
}
|
|
catch (System.IO.EndOfStreamException)
|
|
{
|
|
input = 0;
|
|
}
|
|
}while (input != 0);
|
|
return (inpstr.ToString());
|
|
}
|
|
|
|
|
|
// return the index into the the DatabasesInfo array
|
|
private short GetTable(ushort tblid)
|
|
{
|
|
short found = -1;
|
|
for(short i = 0; (i < numDatabases) && (found == -1); i++)
|
|
{
|
|
if (tblid == ((ROFST_DbInfo)DatabasesInfo[i]).dbiID)
|
|
found = i;
|
|
}
|
|
|
|
if (found == -1)
|
|
{
|
|
// add a new item to the list
|
|
found = numDatabases;
|
|
ROFST_DbInfo tmpDbInfo = new ROFST_DbInfo();
|
|
tmpDbInfo.dbiID = tblid;
|
|
DatabasesInfo.Add(tmpDbInfo);
|
|
dbinew dbinewItem;
|
|
dbinewItem = new dbinew();
|
|
dbiNewInfo.Add(dbinewItem);
|
|
numDatabases++;
|
|
}
|
|
return found;
|
|
}
|
|
|
|
|
|
// Add a new RO record to the arraylist of allNewRos
|
|
private int AddNewRO(uint id,string num,string desc,string val,short type,uint grpn)
|
|
{
|
|
int rtval;
|
|
AddRO tmpAddRO = new AddRO();
|
|
tmpAddRO.ro_id = id;
|
|
tmpAddRO.ro_num = num;
|
|
tmpAddRO.ro_desc = desc;
|
|
tmpAddRO.ro_val = val;
|
|
tmpAddRO.ro_type = type;
|
|
tmpAddRO.ro_parid = grpn;
|
|
(allNewRos[curTblIdx]).Add(tmpAddRO);
|
|
rtval = (allNewRos[curTblIdx]).Count -1;
|
|
return rtval;
|
|
}
|
|
|
|
|
|
private int AddNewRO(string num,string desc,string val,short type,uint grpn)
|
|
{
|
|
return AddNewRO(NewID++, num, desc, val, type, grpn);
|
|
}
|
|
|
|
|
|
// Add a new Group record to the arraylist of allNewGrps
|
|
private int AddNewGroup(uint id,string grpname,short type)
|
|
{
|
|
int rtval;
|
|
AddGroup tmpAddGroup = new AddGroup();
|
|
tmpAddGroup.grp_id = id;
|
|
tmpAddGroup.grp_name = grpname;
|
|
tmpAddGroup.grp_type = type;
|
|
(allNewGrps[curTblIdx]).Add(tmpAddGroup);
|
|
rtval = (allNewGrps[curTblIdx]).Count -1;
|
|
return rtval;
|
|
}
|
|
|
|
|
|
private int AddNewGroup(string grpname,short type)
|
|
{
|
|
return AddNewGroup(NewID++,grpname,type);
|
|
}
|
|
|
|
|
|
// Return the index into the allNewGrps arraylist
|
|
private int FindNewGroup(uint rec)
|
|
{
|
|
int rtval = -1;
|
|
for (int i=0; i < (allNewGrps[curTblIdx]).Count && rtval == -1; i++)
|
|
{
|
|
if (((AddGroup)(allNewGrps[curTblIdx])[i]).grp_id == rec)
|
|
rtval = i;
|
|
}
|
|
return rtval;
|
|
}
|
|
|
|
|
|
private int connectToNewGroupfRO(int lastaddROIDX,uint rec,uint parid,string desc)
|
|
{
|
|
int newgrpIDX;
|
|
// position to the correct RO group
|
|
if((newgrpIDX=FindNewGroup(rec))== -1)
|
|
{
|
|
// group not found, add a new one
|
|
newgrpIDX=AddNewGroup(rec,desc,0);
|
|
}
|
|
//update parent info
|
|
AddRO taddro = (AddRO)(allNewRos[curTblIdx][lastaddROIDX]);
|
|
taddro.ro_pargrpidx = newgrpIDX;
|
|
taddro.ro_parid = rec;
|
|
allNewRos[curTblIdx].RemoveAt(lastaddROIDX);
|
|
allNewRos[curTblIdx].Insert(lastaddROIDX,taddro);
|
|
|
|
//update group info
|
|
AddGroup taddgroup = (AddGroup)(allNewGrps[curTblIdx][newgrpIDX]);
|
|
taddgroup.grp_type |= ((AddRO)(allNewRos[curTblIdx])[lastaddROIDX]).ro_type;
|
|
taddgroup.grp_parid = parid;
|
|
allNewGrps[curTblIdx].RemoveAt(newgrpIDX);
|
|
allNewGrps[curTblIdx].Insert(newgrpIDX,taddgroup);
|
|
return newgrpIDX;
|
|
}
|
|
|
|
|
|
private int connectToNewGroup(int lastaddgrpIDX,uint rec,uint parid,string desc)
|
|
{
|
|
// update group info
|
|
int newgrpIDX;
|
|
// position to the correct RO group
|
|
if((newgrpIDX=FindNewGroup(rec))== -1)
|
|
{
|
|
// group not found, add a new one
|
|
newgrpIDX=AddNewGroup(rec,desc,0);
|
|
}
|
|
AddGroup taddgroup = (AddGroup)(allNewGrps[curTblIdx][lastaddgrpIDX]);
|
|
taddgroup.grp_pargrpidx = newgrpIDX;
|
|
taddgroup.grp_parid = rec;
|
|
allNewGrps[curTblIdx].RemoveAt(lastaddgrpIDX);
|
|
allNewGrps[curTblIdx].Insert(lastaddgrpIDX,taddgroup);
|
|
|
|
taddgroup = (AddGroup)(allNewGrps[curTblIdx][newgrpIDX]);
|
|
taddgroup.grp_type |= ((AddGroup)(allNewGrps[curTblIdx])[lastaddgrpIDX]).grp_type;
|
|
taddgroup.grp_parid = parid;
|
|
allNewGrps[curTblIdx].RemoveAt(newgrpIDX);
|
|
allNewGrps[curTblIdx].Insert(newgrpIDX,taddgroup);
|
|
return newgrpIDX;
|
|
}
|
|
|
|
|
|
private void addDifference(uint id,string val,string desc,short type,uint offset)
|
|
{
|
|
DiffRO tmpDiff = new DiffRO();
|
|
tmpDiff.id=id;
|
|
tmpDiff.type=type;
|
|
tmpDiff.desc=desc;
|
|
tmpDiff.val=val;
|
|
tmpDiff.oldoff=offset;
|
|
allDifferences[curTblIdx].Add(tmpDiff);
|
|
}
|
|
|
|
|
|
private short ReadShort(BinaryReader br)
|
|
{
|
|
short rtnval = -1;
|
|
try
|
|
{
|
|
rtnval = br.ReadInt16();
|
|
}
|
|
catch (Exception)
|
|
{
|
|
rtnval = -1;
|
|
}
|
|
return rtnval;
|
|
}
|
|
|
|
/*
|
|
* Read in the ROFST Update file. Put the changes in array lists
|
|
* to that will be used to organize and merge the differences into
|
|
* the target RO.FST file (usually in the Approved directory). For
|
|
* array lists, use the number of databases from the working draft
|
|
* (there may be new databases created since last approval)
|
|
*/
|
|
public void processAppUpdFile(string sAppUpdFile, short nDB)
|
|
{
|
|
BinaryReader brAppUpd;
|
|
string num, desc, val;
|
|
short typ, inch;
|
|
uint rec;
|
|
ushort tbl;
|
|
uint parid;
|
|
int LastAddedROIDX=-1, LastAddedGrpIDX=-1;
|
|
curTblIdx = 0; // initialize Current Table Index
|
|
allNewRos = (ArrayList [])new ArrayList[nDB];
|
|
allNewGrps = (ArrayList [])new ArrayList[nDB];
|
|
allDifferences = (ArrayList [])new ArrayList[nDB];
|
|
allLocations = new ArrayList();
|
|
|
|
for (int i=0; i<nDB; i++)
|
|
{
|
|
allNewRos[i] = new ArrayList();
|
|
allNewGrps[i] = new ArrayList();
|
|
allDifferences[i] = new ArrayList();
|
|
}
|
|
// Initialize the allLocations array
|
|
locinc tmplocinc = new locinc();
|
|
tmplocinc.inc = 0;
|
|
tmplocinc.maxloc = 0xFFFFFFFF;
|
|
allLocations.Add(tmplocinc);
|
|
|
|
// Open the AppUpd file and read in the RO.FST changes
|
|
try
|
|
{
|
|
brAppUpd = new BinaryReader(File.Open(sAppUpdFile,System.IO.FileMode.Open,System.IO.FileAccess.Read,FileShare.Read));
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
MessageBox.Show("Open "+sAppUpdFile+"\n\n" + e.Message,"Approval Error");
|
|
return;
|
|
}
|
|
|
|
while ((inch = ReadShort(brAppUpd)) != -1)
|
|
{
|
|
if (inch == 0 || inch == 1)
|
|
{
|
|
// Read the ROID for the Table and Record Number
|
|
tbl = brAppUpd.ReadUInt16(); // table number
|
|
rec = brAppUpd.ReadUInt32(); // RO Record number
|
|
|
|
// Position to the correct RO database
|
|
// ex. Setpoint, Graphics, User Defined, etc.
|
|
curTblIdx = GetTable(tbl);
|
|
|
|
// Read in the RO FST record information
|
|
parid = brAppUpd.ReadUInt32(); // Parid
|
|
typ = brAppUpd.ReadInt16(); // type
|
|
desc = GetAsciiString(brAppUpd); // description
|
|
val = GetAsciiString(brAppUpd); // value
|
|
num = GetAsciiString(brAppUpd); // acc ID
|
|
if (inch==0)
|
|
// New RO FST record
|
|
LastAddedROIDX = AddNewRO(rec,num,desc,val,typ,parid);
|
|
else
|
|
{
|
|
// Find existing RO FST record in Approved RO.FST
|
|
uint start = ((ROFST_DbInfo)DatabasesInfo[curTblIdx]).dbiIL;
|
|
uint end = ((ROFST_DbInfo)DatabasesInfo[curTblIdx]).dbiAL;
|
|
//NOTE: the FindRO() used in the old rofstupd.c code
|
|
// had some differences, but we will try the following
|
|
// version of this function since its logic appears in
|
|
// other areas of VE-PROMS code.
|
|
uint OldOff = toolsFindRO(rec,start,end);
|
|
// Save the differences
|
|
addDifference(rec,val,desc,typ,OldOff);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
rec = brAppUpd.ReadUInt32(); // RO Record number
|
|
parid = brAppUpd.ReadUInt32();
|
|
desc = GetAsciiString(brAppUpd);
|
|
if (parid == 0)
|
|
{
|
|
string apid= GetAsciiString(brAppUpd);
|
|
((ROFST_DbInfo)DatabasesInfo[curTblIdx]).dbiTitle = desc;
|
|
((ROFST_DbInfo)DatabasesInfo[curTblIdx]).dbiAP = apid;
|
|
}
|
|
if (LastAddedROIDX != -1)
|
|
// update value in allNewRos
|
|
LastAddedGrpIDX = connectToNewGroupfRO(LastAddedROIDX,rec,parid,desc);
|
|
else
|
|
// update value in allNewGrps
|
|
LastAddedGrpIDX = connectToNewGroup(LastAddedGrpIDX,rec,parid,desc);
|
|
LastAddedROIDX = -1;
|
|
}
|
|
}
|
|
brAppUpd.Close();
|
|
}
|
|
|
|
|
|
// format strings used in the RO.FST menus that are displayed
|
|
// in the VE-PROMS Editor
|
|
private void placeText(StringBuilder buff,ushort doff,ushort wid,string instr)
|
|
{
|
|
ushort siznum=0;
|
|
string str = instr;
|
|
int idx =0;
|
|
if(doff != 0)
|
|
{
|
|
str = str.TrimStart(' '); // skip leading spaces
|
|
ushort l=(ushort)str.Length;
|
|
string numandsigns = "0123456789+-";
|
|
while (numandsigns.IndexOf(str[idx])!=-1)
|
|
{
|
|
siznum++;
|
|
idx++;
|
|
}
|
|
if(siznum==0)
|
|
{// doff is calculated to keep the values positive
|
|
doff=((ushort)(siznum+(wid-l)/2)); // if no digits - center
|
|
}
|
|
else if(((doff-siznum)+l) > wid)
|
|
{
|
|
doff=(ushort)(wid-siznum-l);
|
|
}
|
|
while(wid > 0 && siznum < doff)
|
|
{ // add spaces if necessary for alignment
|
|
buff.Append(' ');
|
|
siznum++;
|
|
wid--;
|
|
}
|
|
}
|
|
idx = 0;
|
|
while(wid > 0)
|
|
{ // output the value or spaces to the specified width
|
|
if (idx < str.Length && str[idx] != 0 && str[idx] != '\n')
|
|
buff.Append(str[idx]);
|
|
else
|
|
buff.Append(" ");
|
|
wid--;
|
|
idx++;
|
|
}
|
|
}
|
|
|
|
|
|
private string getMenuString(short type,string val,string desc)
|
|
{
|
|
StringBuilder buff = new StringBuilder();
|
|
switch(type)
|
|
{
|
|
case 1:
|
|
placeText(buff,5,17,val);
|
|
buff.Append(" ");
|
|
break;
|
|
case 2:
|
|
placeText(buff,5,17,"(Table)");
|
|
buff.Append(" ");
|
|
break;
|
|
case 4:
|
|
placeText(buff,5,17,"(Graph)");
|
|
buff.Append(" ");
|
|
break;
|
|
}
|
|
buff.Append(desc);
|
|
return buff.ToString();
|
|
}
|
|
|
|
|
|
public void WriteString(BinaryWriter NewFSTFile, string str,bool AddNull)
|
|
{
|
|
int n=str.Length;
|
|
if (AddNull)
|
|
n++;
|
|
byte [] b = new byte[n];
|
|
for(int i =0; i < str.Length; i++)
|
|
{
|
|
b[i] = (byte)str[i];
|
|
}
|
|
NewFSTFile.Write(b,0,n);
|
|
}
|
|
|
|
|
|
public uint saveNewMenuEntries(BinaryWriter NewFSTFile,uint id)
|
|
{
|
|
long start=NewFSTFile.Seek(0,System.IO.SeekOrigin.Current);
|
|
int numNewRos = (allNewRos[curTblIdx]).Count;
|
|
int cntNewRos = 0;
|
|
while (cntNewRos < numNewRos)
|
|
{
|
|
// Skip to the one to be saved
|
|
while ((cntNewRos < numNewRos) &&
|
|
(((AddRO)(allNewRos[curTblIdx])[cntNewRos]).ro_stat != 1) &&
|
|
((AddRO)(allNewRos[curTblIdx])[cntNewRos]).ro_parid != id)
|
|
cntNewRos++;
|
|
// If one exists, save it and skip to the next one
|
|
if (cntNewRos < numNewRos)
|
|
{
|
|
AddRO taddro = (AddRO)(allNewRos[curTblIdx][cntNewRos]);
|
|
taddro.ro_stat = 2;
|
|
allNewRos[curTblIdx].RemoveAt(cntNewRos);
|
|
allNewRos[curTblIdx].Insert(cntNewRos,taddro);
|
|
// Save the offset
|
|
NewFSTFile.Write(((AddRO)(allNewRos[curTblIdx])[cntNewRos]).ro_offset);
|
|
// Save the type
|
|
NewFSTFile.Write(((AddRO)(allNewRos[curTblIdx])[cntNewRos]).ro_type);
|
|
// Get the menu string
|
|
string mnustr = getMenuString(((AddRO)(allNewRos[curTblIdx])[cntNewRos]).ro_type,((AddRO)(allNewRos[curTblIdx])[cntNewRos]).ro_val,((AddRO)(allNewRos[curTblIdx])[cntNewRos]).ro_desc);
|
|
// Save menu entry
|
|
WriteString(NewFSTFile,mnustr,true);
|
|
cntNewRos++;
|
|
}
|
|
}
|
|
int cntNewGrps = 0;
|
|
int numNewGrps = (allNewGrps[curTblIdx]).Count;
|
|
while (cntNewGrps < numNewGrps)
|
|
{
|
|
// Skip to the one to be saved
|
|
while ((cntNewGrps < numNewGrps) &&
|
|
(((AddGroup)(allNewGrps[curTblIdx])[cntNewGrps]).grp_stat != 1 ||
|
|
((AddGroup)(allNewGrps[curTblIdx])[cntNewGrps]).grp_parid != id))
|
|
cntNewGrps++;
|
|
// If one exists, save it and skip to the next one
|
|
if(cntNewGrps < numNewGrps)
|
|
{
|
|
// Change stat to menu entry saved
|
|
AddGroup taddgroup = (AddGroup)(allNewGrps[curTblIdx][cntNewGrps]);
|
|
taddgroup.grp_stat = 2;
|
|
allNewGrps[curTblIdx].RemoveAt(cntNewGrps);
|
|
allNewGrps[curTblIdx].Insert(cntNewGrps,taddgroup);
|
|
// Save the offset
|
|
NewFSTFile.Write(((AddGroup)(allNewGrps[curTblIdx])[cntNewGrps]).grp_offset);
|
|
// Save the type
|
|
NewFSTFile.Write(((AddGroup)(allNewGrps[curTblIdx])[cntNewGrps]).grp_type);
|
|
// Save menu entry
|
|
WriteString(NewFSTFile,((AddGroup)(allNewGrps[curTblIdx])[cntNewGrps]).grp_name,true);
|
|
cntNewGrps++;
|
|
}
|
|
}
|
|
return ((uint)((NewFSTFile.Seek(0,System.IO.SeekOrigin.Current)) - start));
|
|
}
|
|
|
|
|
|
|
|
public void AddLocation(uint location,int inc)
|
|
{
|
|
int t_inc = ((locinc)allLocations[lastLocationIdx]).inc;
|
|
if (location == ((locinc)allLocations[lastLocationIdx]).maxloc)
|
|
{
|
|
// update the current record
|
|
// - need to remove current item, then insert new item.
|
|
locinc tmploc = (locinc)(allLocations[lastLocationIdx]);
|
|
tmploc.inc += inc;
|
|
allLocations.RemoveAt(lastLocationIdx);
|
|
allLocations.Insert(lastLocationIdx,tmploc);
|
|
}
|
|
else
|
|
{
|
|
locinc tmploc = (locinc)(allLocations[lastLocationIdx]);
|
|
locinc newloc = new locinc();
|
|
// new item gets last item's maxloc
|
|
newloc.maxloc = tmploc.maxloc;
|
|
newloc.inc = tmploc.inc + inc;
|
|
// update the current record
|
|
// - need to remove current item, then insert new item.
|
|
tmploc.maxloc = location; //update maxloc
|
|
allLocations.RemoveAt(lastLocationIdx);
|
|
allLocations.Insert(lastLocationIdx,tmploc);
|
|
// append the new item
|
|
allLocations.Add(newloc);
|
|
lastLocationIdx++;
|
|
}
|
|
}
|
|
|
|
|
|
public short saveAdditions(BinaryWriter NewFSTFile,uint parid,uint start)
|
|
{
|
|
// Initialize count of added entries
|
|
short count = 0;
|
|
// Initialize count of added bytes
|
|
int bytes = 0;
|
|
|
|
int numgroups = (allNewGrps[curTblIdx]).Count;
|
|
int grpcnt = 0;
|
|
while (grpcnt < numgroups)
|
|
{
|
|
if (((AddGroup)(allNewGrps[curTblIdx])[grpcnt]).grp_stat == 0 && ((AddGroup)(allNewGrps[curTblIdx])[grpcnt]).grp_parid == parid)
|
|
{
|
|
// Save new group
|
|
// Change stat to inprogress
|
|
AddGroup taddgroup = (AddGroup)(allNewGrps[curTblIdx][grpcnt]);
|
|
taddgroup.grp_stat = 99;
|
|
allNewGrps[curTblIdx].RemoveAt(grpcnt);
|
|
allNewGrps[curTblIdx].Insert(grpcnt,taddgroup);
|
|
count++;
|
|
// Save any children
|
|
short howmany = saveAdditions(NewFSTFile,((AddGroup)(allNewGrps[curTblIdx])[grpcnt]).grp_id,start);
|
|
|
|
// Remember the offset
|
|
taddgroup = (AddGroup)(allNewGrps[curTblIdx][grpcnt]);
|
|
taddgroup.grp_offset = (uint)NewFSTFile.Seek(0,System.IO.SeekOrigin.Current); // ftell(ofile)
|
|
allNewGrps[curTblIdx].RemoveAt(grpcnt);
|
|
allNewGrps[curTblIdx].Insert(grpcnt,taddgroup);
|
|
|
|
// Save ID
|
|
if (((AddGroup)(allNewGrps[curTblIdx])[grpcnt]).grp_parid == 0)
|
|
{
|
|
whereisgl = (uint)NewFSTFile.Seek(0,System.IO.SeekOrigin.Current);
|
|
}
|
|
NewFSTFile.Write(((AddGroup)(allNewGrps[curTblIdx])[grpcnt]).grp_id);
|
|
// Save the Parent ID
|
|
NewFSTFile.Write(((AddGroup)(allNewGrps[curTblIdx])[grpcnt]).grp_parid);
|
|
// save howmany
|
|
NewFSTFile.Write(howmany);
|
|
// save children
|
|
saveNewMenuEntries(NewFSTFile,((AddGroup)(allNewGrps[curTblIdx])[grpcnt]).grp_id);
|
|
taddgroup = (AddGroup)(allNewGrps[curTblIdx][grpcnt]);
|
|
taddgroup.grp_stat = 1;
|
|
allNewGrps[curTblIdx].RemoveAt(grpcnt);
|
|
allNewGrps[curTblIdx].Insert(grpcnt,taddgroup);
|
|
bytes += (int)(NewFSTFile.Seek(0,System.IO.SeekOrigin.Current) - ((AddGroup)(allNewGrps[curTblIdx])[grpcnt]).grp_offset);
|
|
}
|
|
grpcnt++;
|
|
}
|
|
// Second check new ROs
|
|
int rocnt = 0;
|
|
int numros = (allNewRos[curTblIdx]).Count;
|
|
while (rocnt < numros)
|
|
{
|
|
// save new RO
|
|
if (((AddRO)(allNewRos[curTblIdx])[rocnt]).ro_stat == 0 &&
|
|
((AddRO)(allNewRos[curTblIdx])[rocnt]).ro_parid == parid)
|
|
{
|
|
// change the stat
|
|
AddRO taddro = (AddRO)(allNewRos[curTblIdx][rocnt]);
|
|
taddro.ro_stat = 1;
|
|
// Increment count
|
|
count++;
|
|
taddro.ro_offset = (int)NewFSTFile.Seek(0,System.IO.SeekOrigin.Current);
|
|
allNewRos[curTblIdx].RemoveAt(rocnt);
|
|
allNewRos[curTblIdx].Insert(rocnt,taddro);
|
|
// Save the ID
|
|
NewFSTFile.Write(((AddRO)(allNewRos[curTblIdx])[rocnt]).ro_id);
|
|
// Save the Parent ID
|
|
NewFSTFile.Write(((AddRO)(allNewRos[curTblIdx])[rocnt]).ro_parid);
|
|
// Save -1
|
|
NewFSTFile.Write((short)-1);
|
|
// Save type
|
|
NewFSTFile.Write(((AddRO)(allNewRos[curTblIdx])[rocnt]).ro_type);
|
|
maxtype |= (ushort)((AddRO)(allNewRos[curTblIdx])[rocnt]).ro_type;
|
|
// Save value
|
|
WriteString(NewFSTFile,((AddRO)(allNewRos[curTblIdx])[rocnt]).ro_val,true);
|
|
// Save accid
|
|
short aw = (short)((AddRO)(allNewRos[curTblIdx])[rocnt]).ro_num.Length;
|
|
if (aw > maxaw) maxaw = (ushort)aw;
|
|
WriteString(NewFSTFile,((AddRO)(allNewRos[curTblIdx])[rocnt]).ro_num,true);
|
|
// Calculate the number of extra bytes output
|
|
bytes+=(int)(NewFSTFile.Seek(0,System.IO.SeekOrigin.Current) - ((AddRO)(allNewRos[curTblIdx])[rocnt]).ro_offset);
|
|
}
|
|
rocnt++;
|
|
}
|
|
// Adjust the location information
|
|
if (bytes != 0 && start > 0)
|
|
AddLocation(start - 1,bytes);
|
|
return count;
|
|
}
|
|
|
|
|
|
// was a difference flagged for this RO
|
|
// - check via saved offsets into the RO.fST file
|
|
public int isDifferent(uint off)
|
|
{
|
|
int allDiffCnt = 0;
|
|
int NumAllDiff = (allDifferences[curTblIdx]).Count;
|
|
while (allDiffCnt < NumAllDiff)
|
|
{
|
|
if (((DiffRO)(allDifferences[curTblIdx])[allDiffCnt]).oldoff == off)
|
|
return allDiffCnt;
|
|
allDiffCnt++;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
|
|
|
|
public uint newLocation(uint oldlocation)
|
|
{
|
|
int idx = 0;
|
|
while (oldlocation > ((locinc)allLocations[idx]).maxloc) idx++;
|
|
return oldlocation + (uint)((locinc)allLocations[idx]).inc;
|
|
}
|
|
|
|
|
|
public void processGroupRecords(BinaryWriter NewFSTFile,uint end)
|
|
{
|
|
uint start;
|
|
while ((start=(uint)brROFst.BaseStream.Seek(0,System.IO.SeekOrigin.Current)) < end)
|
|
{
|
|
// Read ID
|
|
uint id = brROFst.ReadUInt32();
|
|
// Read Parent ID
|
|
uint parid = brROFst.ReadUInt32();
|
|
// Read How Many
|
|
short howmany = brROFst.ReadInt16();
|
|
// Check of additions and write them
|
|
short howmanyplus = howmany;
|
|
if (howmany >= 0)
|
|
howmanyplus += saveAdditions(NewFSTFile,id,start);
|
|
if (parid == 0)
|
|
whereisgl = (uint)NewFSTFile.Seek(0,System.IO.SeekOrigin.Current); // ftell(ofile)
|
|
// Write ID
|
|
NewFSTFile.Write(id);
|
|
// Write Parent ID
|
|
NewFSTFile.Write(parid);
|
|
// Write howmany
|
|
NewFSTFile.Write(howmanyplus);
|
|
// If group - read and write menu list
|
|
int starti = (int)brROFst.BaseStream.Seek(0,System.IO.SeekOrigin.Current); // ftell(rofstfile)
|
|
int starto = (int)NewFSTFile.Seek(0,System.IO.SeekOrigin.Current); // ftell(ofile)
|
|
if (howmanyplus >= 0)
|
|
{
|
|
// for orignal entries
|
|
for (int i=0;i<howmany;i++)
|
|
{
|
|
// Read Offset
|
|
uint offset = brROFst.ReadUInt32();
|
|
// Read Type
|
|
short type = brROFst.ReadInt16();
|
|
// Read Menu
|
|
string menustr = GetAsciiString(brROFst);
|
|
// Look for differences
|
|
int thisdiff = isDifferent(offset);
|
|
if (thisdiff != -1)
|
|
{
|
|
type = ((DiffRO)(allDifferences[curTblIdx])[thisdiff]).type;
|
|
menustr = getMenuString(type,((DiffRO)(allDifferences[curTblIdx])[thisdiff]).val,((DiffRO)(allDifferences[curTblIdx])[thisdiff]).desc);
|
|
}
|
|
// Save new offset
|
|
NewFSTFile.Write(newLocation(offset));
|
|
// Save type
|
|
NewFSTFile.Write(type);
|
|
// Save menu
|
|
WriteString(NewFSTFile,menustr,true);
|
|
}
|
|
// Save new entries
|
|
if (howmanyplus > howmany)
|
|
{
|
|
saveNewMenuEntries(NewFSTFile,id);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// if RO - read RO record
|
|
// Read type
|
|
short type = brROFst.ReadInt16();
|
|
// Read value
|
|
string val = GetAsciiString(brROFst);
|
|
// Read accid
|
|
string num = GetAsciiString(brROFst);
|
|
// check if changed
|
|
int thisdiff = isDifferent(start);
|
|
if (thisdiff != -1)
|
|
{
|
|
type = ((DiffRO)(allDifferences[curTblIdx])[thisdiff]).type;
|
|
val = ((DiffRO)(allDifferences[curTblIdx])[thisdiff]).val;
|
|
}
|
|
// Save type
|
|
NewFSTFile.Write(type);
|
|
// Save value
|
|
WriteString(NewFSTFile,val,true);
|
|
// Save accid
|
|
WriteString(NewFSTFile,num,true);
|
|
}
|
|
int originalSize = (int)brROFst.BaseStream.Seek(0,System.IO.SeekOrigin.Current) - starti;
|
|
int copySize = (int)NewFSTFile.Seek(0,System.IO.SeekOrigin.Current) - starto;
|
|
if (copySize != originalSize)
|
|
AddLocation(start,copySize - originalSize);
|
|
}
|
|
if (end == 0)
|
|
{
|
|
maxtype = 0;
|
|
maxaw = 0;
|
|
saveAdditions(NewFSTFile,0,0);
|
|
}
|
|
}
|
|
|
|
|
|
public int getROAccLess(string minnum)
|
|
{
|
|
int romin = -1;
|
|
int roptr = 0;
|
|
int numroptr = (allNewRos[curTblIdx]).Count;
|
|
while (roptr < numroptr)
|
|
{
|
|
// skip processed entries
|
|
while ((roptr < numroptr) &&
|
|
((AddRO)(allNewRos[curTblIdx])[roptr]).ro_stat == 4) roptr++;
|
|
if ((roptr < numroptr))
|
|
{
|
|
// Look for "smallest"
|
|
if ((minnum==null)||
|
|
((AddRO)(allNewRos[curTblIdx])[roptr]).ro_num.CompareTo(minnum) < 0)
|
|
{
|
|
romin = roptr;
|
|
minnum = ((AddRO)(allNewRos[curTblIdx])[roptr]).ro_num;
|
|
}
|
|
roptr++;
|
|
}
|
|
}
|
|
return romin;
|
|
}
|
|
|
|
|
|
public void putFixed(BinaryWriter NewFstFile, string str, short len)
|
|
{
|
|
int n=len; //str.Length;
|
|
int strlen = str.Length;
|
|
byte [] b = new byte[len];
|
|
// write a fixed length of a string.
|
|
for (int i =0; n > 0; i++)
|
|
{
|
|
if (i < strlen)
|
|
b[i] = (byte)str[i];
|
|
else
|
|
b[i] = (byte)0; // pad with NULLs if smaller than "len"
|
|
n--;
|
|
}
|
|
NewFstFile.Write(b,0,len);
|
|
}
|
|
|
|
|
|
public void processAccIdRecords(BinaryWriter NewFSTFile,uint end,short len)
|
|
{
|
|
int extra = 0;
|
|
int roptr = 0;
|
|
while (brROFst.BaseStream.Seek(0,System.IO.SeekOrigin.Current) < end)
|
|
{
|
|
// Read ID
|
|
uint id = brROFst.ReadUInt32();
|
|
// Read accID
|
|
string num = GetAsciiString(brROFst,len);
|
|
// Check other accIDs in new records and save
|
|
while ((roptr = getROAccLess(num)) != -1)
|
|
{
|
|
extra+=(len + 4); //sizeof(ulong 16bit)+len
|
|
NewFSTFile.Write(((AddRO)(allNewRos[curTblIdx])[roptr]).ro_id);
|
|
putFixed(NewFSTFile,((AddRO)(allNewRos[curTblIdx])[roptr]).ro_num,len);
|
|
AddRO taddro = (AddRO)(allNewRos[curTblIdx][roptr]);
|
|
taddro.ro_stat = 4;
|
|
allNewRos[curTblIdx].RemoveAt(roptr);
|
|
allNewRos[curTblIdx].Insert(roptr,taddro);
|
|
}
|
|
// Write ID
|
|
NewFSTFile.Write(id);
|
|
// Write accID
|
|
putFixed(NewFSTFile,num,len);
|
|
}
|
|
// Save remaining RO info
|
|
while ((roptr = getROAccLess(null))!=-1)
|
|
{
|
|
extra += (len+4); //sizeof(ulong 16bit)+len
|
|
NewFSTFile.Write(((AddRO)(allNewRos[curTblIdx])[roptr]).ro_id);
|
|
putFixed(NewFSTFile,((AddRO)(allNewRos[curTblIdx])[roptr]).ro_num,len);
|
|
AddRO taddro = (AddRO)(allNewRos[curTblIdx][roptr]);
|
|
taddro.ro_stat = 4;
|
|
allNewRos[curTblIdx].RemoveAt(roptr);
|
|
allNewRos[curTblIdx].Insert(roptr,taddro);
|
|
}
|
|
if (extra > 0)
|
|
AddLocation(end-1,extra);
|
|
}
|
|
|
|
|
|
public void nextIDandOffset(ref uint nxtid, ref uint nxtoff)
|
|
{
|
|
int roptr = 0, romin = -1;
|
|
int numroptr = (allNewRos[curTblIdx]).Count;
|
|
int grpptr = 0, grpmin = -1;
|
|
int numgrpptr = (allNewGrps[curTblIdx]).Count;
|
|
|
|
while (roptr < numroptr)
|
|
{
|
|
if (((AddRO)(allNewRos[curTblIdx])[roptr]).ro_id > nxtid &&
|
|
(romin == -1 || ((AddRO)(allNewRos[curTblIdx])[roptr]).ro_id < ((AddRO)(allNewRos[curTblIdx])[romin]).ro_id))
|
|
romin = roptr;
|
|
roptr++;
|
|
}
|
|
|
|
while (grpptr < numgrpptr)
|
|
{
|
|
if (((AddGroup)(allNewGrps[curTblIdx])[grpptr]).grp_id > nxtid &&
|
|
(grpmin == -1 || ((AddGroup)(allNewGrps[curTblIdx])[grpptr]).grp_id < ((AddGroup)(allNewGrps[curTblIdx])[grpmin]).grp_id))
|
|
grpmin = grpptr;
|
|
grpptr++;
|
|
}
|
|
if (grpmin != -1)
|
|
{
|
|
if ((romin != -1) && ((AddRO)(allNewRos[curTblIdx])[romin]).ro_id < ((AddGroup)(allNewGrps[curTblIdx])[grpmin]).grp_id)
|
|
{
|
|
AddRO taddro = (AddRO)(allNewRos[curTblIdx][romin]);
|
|
taddro.ro_stat = 3;
|
|
allNewRos[curTblIdx].RemoveAt(romin);
|
|
allNewRos[curTblIdx].Insert(romin,taddro);
|
|
nxtid = ((AddRO)(allNewRos[curTblIdx])[romin]).ro_id;
|
|
nxtoff = (uint)((AddRO)(allNewRos[curTblIdx])[romin]).ro_offset;
|
|
}
|
|
else
|
|
{
|
|
AddGroup taddgroup = (AddGroup)(allNewGrps[curTblIdx][grpmin]);
|
|
taddgroup.grp_stat = 3;
|
|
allNewGrps[curTblIdx].RemoveAt(grpmin);
|
|
allNewGrps[curTblIdx].Insert(grpmin,taddgroup);
|
|
nxtid = ((AddGroup)(allNewGrps[curTblIdx])[grpmin]).grp_id;
|
|
nxtoff = ((AddGroup)(allNewGrps[curTblIdx])[grpmin]).grp_offset;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (romin != -1)
|
|
{
|
|
AddRO taddro = (AddRO)(allNewRos[curTblIdx][romin]);
|
|
taddro.ro_stat = 3;
|
|
allNewRos[curTblIdx].RemoveAt(romin);
|
|
allNewRos[curTblIdx].Insert(romin,taddro);
|
|
nxtid = ((AddRO)(allNewRos[curTblIdx])[romin]).ro_id;
|
|
nxtoff = (uint)((AddRO)(allNewRos[curTblIdx])[romin]).ro_offset;
|
|
}
|
|
else
|
|
{
|
|
nxtid = 0;
|
|
nxtoff = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
public void processIdRecords(BinaryWriter NewFstFile,uint end)
|
|
{
|
|
int extra = 0;
|
|
uint nxtid =0, nxtoff=0;
|
|
nextIDandOffset(ref nxtid,ref nxtoff);
|
|
while (brROFst.BaseStream.Seek(0,System.IO.SeekOrigin.Current) < end)
|
|
{
|
|
// Read ID
|
|
uint id = brROFst.ReadUInt32();
|
|
// Look for new entries that precede ID
|
|
while (nxtid != 0 && nxtid < id)
|
|
{
|
|
extra += 8; // sizeof(ulong 16bit) * 2
|
|
NewFstFile.Write(nxtid);
|
|
NewFstFile.Write(nxtoff);
|
|
nextIDandOffset(ref nxtid,ref nxtoff); // passed by reference
|
|
}
|
|
// Write ID
|
|
NewFstFile.Write(id);
|
|
// Read Offset
|
|
uint off = brROFst.ReadUInt32();
|
|
// Write new offset
|
|
NewFstFile.Write(newLocation(off));
|
|
}
|
|
// Save new RO entries and Group entries
|
|
while (nxtid != 0)
|
|
{
|
|
extra += 8; // sizeof(ulong 16bit)*2
|
|
NewFstFile.Write(nxtid);
|
|
NewFstFile.Write(nxtoff);
|
|
nextIDandOffset(ref nxtid,ref nxtoff); // passed by reference
|
|
}
|
|
if (extra != 0)
|
|
AddLocation(end-1,extra);
|
|
}
|
|
|
|
|
|
/*
|
|
* Merge the changes into the RO.FST file (usually Approved directory)
|
|
*/
|
|
public void CreateMergedFSTFile(string NewFStName)
|
|
{
|
|
BinaryWriter NewFSTFile=null;
|
|
|
|
// Open a new FST file for writing
|
|
try
|
|
{
|
|
NewFSTFile = new BinaryWriter(File.Open(NewFStName,System.IO.FileMode.Create,System.IO.FileAccess.ReadWrite,FileShare.None));
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
MessageBox.Show("Error Opening "+NewFStName +"\n\n" + e.Message,"Approval Error");
|
|
}
|
|
|
|
// Write the RO.FST header
|
|
Header.Write(NewFSTFile);
|
|
|
|
// Position the old FST file past the header
|
|
brROFst.BaseStream.Seek(Header.GetStructSize(),System.IO.SeekOrigin.Begin);
|
|
|
|
// Loop through each database
|
|
for (short i=0; i < numDatabases; i++)
|
|
{
|
|
// Set the current table index used to access the allNewRos,
|
|
// allNewGrps, and allDifferences arrays
|
|
curTblIdx = i;
|
|
|
|
// Loop through the Group and RO records
|
|
// Update the RO Group information
|
|
processGroupRecords(NewFSTFile,((ROFST_DbInfo)DatabasesInfo[i]).dbiIL);
|
|
if (((ROFST_DbInfo)DatabasesInfo[i]).dbiAW == 0)
|
|
((ROFST_DbInfo)DatabasesInfo[i]).dbiAW = maxaw;
|
|
|
|
if (((ROFST_DbInfo)DatabasesInfo[i]).dbiType == 0)
|
|
((ROFST_DbInfo)DatabasesInfo[i]).dbiType = maxtype;
|
|
|
|
((ROFST_DbInfo)DatabasesInfo[i]).dbiGL = whereisgl;
|
|
((ROFST_DbInfo)DatabasesInfo[i]).dbiIL = (uint)NewFSTFile.Seek(0,System.IO.SeekOrigin.Current);
|
|
|
|
// Loop through the ID list
|
|
processIdRecords(NewFSTFile,((ROFST_DbInfo)DatabasesInfo[i]).dbiAL);
|
|
((ROFST_DbInfo)DatabasesInfo[i]).dbiAL = (uint)NewFSTFile.Seek(0,System.IO.SeekOrigin.Current);
|
|
// Loop through the accid list
|
|
processAccIdRecords(NewFSTFile,((ROFST_DbInfo)DatabasesInfo[i]).dbiEND,(short)((ROFST_DbInfo)DatabasesInfo[i]).dbiAW);
|
|
((ROFST_DbInfo)DatabasesInfo[i]).dbiEND = (uint)NewFSTFile.Seek(0,System.IO.SeekOrigin.Current);
|
|
}
|
|
// Save the Database info
|
|
uint lngbuf = 0;
|
|
// Save the current location in the new fst file
|
|
uint dblength = (uint)NewFSTFile.Seek(0,System.IO.SeekOrigin.Current);
|
|
NewFSTFile.Write(lngbuf);
|
|
NewFSTFile.Write(numDatabases);
|
|
uint lngval;
|
|
ROFST_DbInfo tmpdbinfo = new ROFST_DbInfo();
|
|
lngval = (uint)(tmpdbinfo.GetStructSize() * numDatabases);
|
|
for (int i=0;i<numDatabases;i++)
|
|
{
|
|
NewFSTFile.Write(((ROFST_DbInfo)DatabasesInfo[i]).dbiID);
|
|
NewFSTFile.Write(((ROFST_DbInfo)DatabasesInfo[i]).dbiType);
|
|
NewFSTFile.Write(((ROFST_DbInfo)DatabasesInfo[i]).dbiAW);
|
|
NewFSTFile.Write(((ROFST_DbInfo)DatabasesInfo[i]).dbiGL);
|
|
NewFSTFile.Write(((ROFST_DbInfo)DatabasesInfo[i]).dbiIL);
|
|
NewFSTFile.Write(((ROFST_DbInfo)DatabasesInfo[i]).dbiAL);
|
|
NewFSTFile.Write(((ROFST_DbInfo)DatabasesInfo[i]).dbiEND);
|
|
NewFSTFile.Write(lngval);
|
|
lngval += (uint)((ROFST_DbInfo)DatabasesInfo[i]).dbiTitle.Length + 1;
|
|
NewFSTFile.Write(lngval);
|
|
lngval += (uint)((ROFST_DbInfo)DatabasesInfo[i]).dbiAP.Length + 1;
|
|
}
|
|
for (short i=0;i<numDatabases;i++)
|
|
{
|
|
WriteString(NewFSTFile,((ROFST_DbInfo)DatabasesInfo[i]).dbiTitle,true);
|
|
WriteString(NewFSTFile,((ROFST_DbInfo)DatabasesInfo[i]).dbiAP,true);
|
|
}
|
|
// locate the end
|
|
uint dbend = (uint)NewFSTFile.Seek(0,System.IO.SeekOrigin.Current); // ftell(ofile)
|
|
// How long is the db info
|
|
NewFSTFile.Seek((int)dblength,System.IO.SeekOrigin.Begin);
|
|
lngbuf = dbend-dblength-4; //dbend-dblength-sizeof(dblength)
|
|
NewFSTFile.Write(lngbuf);
|
|
// Go to the beginning of the new file
|
|
NewFSTFile.Seek(0,System.IO.SeekOrigin.Begin);
|
|
// Save the header again
|
|
if (Header.hcYear==0)
|
|
Header.SetHeader(dblength); // sets the header and date/time
|
|
else
|
|
Header.dboffset = dblength;
|
|
Header.Write(NewFSTFile);
|
|
NewFSTFile.Flush();
|
|
NewFSTFile.Close();
|
|
uint test = (uint) Header.hcHund;
|
|
// stamp the new FST file with the RO.FST header date/time
|
|
DateTime dt = new DateTime((int)Header.hcYear,(int)Header.hMonth,(int)Header.hDay,(int)Header.hcHour,(int)Header.hcMin,(int)Header.hcSec,(int)Header.hcHund);
|
|
File.SetLastWriteTime(NewFStName,dt);
|
|
}
|
|
}
|
|
/*************************************************************************/
|
|
|
|
public class strEntry
|
|
{
|
|
|
|
public strEntry()
|
|
{
|
|
}
|
|
|
|
public virtual string toText(int mi){return "";}
|
|
|
|
public virtual int getLength(int mi){return 0;}
|
|
|
|
}
|
|
|
|
|
|
|
|
public class seText : strEntry
|
|
{
|
|
public string str;
|
|
public int len;
|
|
|
|
public seText(string instr, int inlen)
|
|
{
|
|
str = instr.Substring(0,inlen);
|
|
len = inlen;
|
|
}
|
|
|
|
public override string toText(int mi)
|
|
{
|
|
return str;
|
|
}
|
|
|
|
public override int getLength(int mi)
|
|
{
|
|
return len;
|
|
}
|
|
}
|
|
|
|
|
|
public class seUser : strEntry
|
|
{
|
|
string uvalue;
|
|
int len;
|
|
|
|
public seUser(string str, int l)
|
|
{
|
|
uvalue = ROProcessTools.evaluate(str,l);
|
|
len = uvalue.Length;
|
|
}
|
|
|
|
public override string toText(int mi)
|
|
{
|
|
return uvalue;
|
|
}
|
|
|
|
public override int getLength(int mi)
|
|
{
|
|
return len;
|
|
}
|
|
}
|
|
|
|
public class strList
|
|
{
|
|
public varList vList;
|
|
public menuList mList;
|
|
private ArrayList aryStrEntry;
|
|
|
|
public strList(string str)
|
|
{
|
|
vList = new varList();
|
|
mList = new menuList();
|
|
aryStrEntry = new ArrayList();
|
|
Process(str,str.Length);
|
|
}
|
|
|
|
public strList(string str, int l, varList vl, menuList ml)
|
|
{
|
|
if (vl == null)
|
|
vList = new varList();
|
|
else
|
|
vList = vl;
|
|
if (ml == null)
|
|
mList = new menuList();
|
|
else
|
|
mList = ml;
|
|
if (aryStrEntry == null)
|
|
aryStrEntry = new ArrayList();
|
|
Process(str.Substring(0,l),l);
|
|
}
|
|
|
|
public void Add(strEntry se)
|
|
{
|
|
aryStrEntry.Add(se);
|
|
}
|
|
|
|
public void processCondition(string cnd, string opt, int lc, int lo)
|
|
{
|
|
// equaluate condition
|
|
string stat = ROProcessTools.evaluate(cnd,lc);
|
|
int ls = stat.Length;
|
|
// look for match - remember default
|
|
string match=null;
|
|
int matchlen = 0;
|
|
string def = null;
|
|
int deflen = 0;
|
|
while (lo > 0 && match == null)
|
|
{
|
|
int end = ROProcessTools.matchingBrace(opt);
|
|
int eq = opt.IndexOf('=');
|
|
int len = end + 1; // +1 to include the '}'
|
|
int li = eq-1;
|
|
int ld = len-li-3; // One for '{', '=' and '}'
|
|
if (def == null || eq == 1)
|
|
{
|
|
def = opt.Substring(eq+1,ld);
|
|
deflen = ld;
|
|
}
|
|
if (ls == li && stat.StartsWith(opt.Substring(1,li)))
|
|
{
|
|
match = opt.Substring(eq+1,ld);
|
|
matchlen = ld;
|
|
}
|
|
opt = opt.Substring(len);
|
|
lo -= len;
|
|
}
|
|
// if match process option - or process default
|
|
if (match == null)
|
|
{
|
|
match = def;
|
|
matchlen = deflen;
|
|
}
|
|
Process(match,matchlen);
|
|
}
|
|
|
|
public void processBrace(string str, int l, ref int nfnd)
|
|
{
|
|
int nxt = ROProcessTools.nextDelimiter("{=",str,l); // -1 means not found
|
|
if(nxt == -1) // varUse
|
|
{
|
|
strList found = null;
|
|
found = vList.lookFor(str,l);
|
|
if (found != null)
|
|
Add(new seVarUse(found));
|
|
else
|
|
nfnd = 1;
|
|
}
|
|
else
|
|
{
|
|
if (str[nxt] == '{') // conditonal or menu
|
|
{
|
|
if(nxt==0)
|
|
{ // menu
|
|
mList.Process(str,l,vList);
|
|
Add(new seMenuUse(mList));
|
|
}
|
|
else
|
|
{ // conditional
|
|
processCondition(str, str.Substring(nxt), nxt, l -nxt);
|
|
}
|
|
}
|
|
else
|
|
{ // must be variable definiton
|
|
vList.Add(str, str.Substring(nxt+1), nxt, l - nxt - 1, mList);
|
|
}
|
|
}
|
|
}
|
|
|
|
public void Process (string str, int len)
|
|
{
|
|
int nxtDlm = -1; // -1 = not found
|
|
while (len > 0)
|
|
{
|
|
nxtDlm = ROProcessTools.nextDelimiter("{",str,len);
|
|
if (nxtDlm == -1)
|
|
{
|
|
// add entire string as is
|
|
Add(new seText(str,len));
|
|
//str = str.Substring(len); don't think we need to do this
|
|
len = 0;
|
|
}
|
|
else
|
|
{
|
|
int cnt = 0;
|
|
if (nxtDlm > 0)
|
|
{
|
|
// add preceeding text
|
|
Add(new seText(str,nxtDlm));
|
|
str = str.Substring(nxtDlm);
|
|
len-=nxtDlm;
|
|
}
|
|
// add text group by delimiter, including
|
|
// the delimiters
|
|
nxtDlm = ROProcessTools.matchingBrace(str)+1;
|
|
cnt = nxtDlm;
|
|
int nfnd = 0;
|
|
processBrace(str.Substring(1),cnt-2,ref nfnd);
|
|
if (nfnd > 0)
|
|
{
|
|
Add(new seText(str,cnt));
|
|
}
|
|
// position to next delimiter grouping
|
|
len -= cnt;
|
|
str = str.Substring(nxtDlm);
|
|
}
|
|
}
|
|
}
|
|
|
|
public string toText(int mi)
|
|
{
|
|
StringBuilder bldstr = new StringBuilder();
|
|
for (int i=0; i < aryStrEntry.Count; i++)
|
|
{
|
|
bldstr.Append(((strEntry)aryStrEntry[i]).toText(mi));
|
|
}
|
|
return bldstr.ToString();
|
|
}
|
|
|
|
public int getLength(int mi)
|
|
{
|
|
int rtnval = 0;
|
|
for (int i=0; i < aryStrEntry.Count; i++)
|
|
{
|
|
rtnval += (((strEntry)aryStrEntry[i]).getLength(mi));
|
|
}
|
|
return rtnval;
|
|
}
|
|
|
|
public int menuCount()
|
|
{
|
|
return mList.getCount();
|
|
}
|
|
|
|
public string getIds(ref int cnt)
|
|
{
|
|
// return a string of the IDs
|
|
return mList.getIds(ref cnt);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
public class strList2
|
|
{
|
|
|
|
private ArrayList aryStrEntry;
|
|
|
|
public strList2(string str)
|
|
{
|
|
int l=str.Length;
|
|
if (aryStrEntry == null)
|
|
aryStrEntry = new ArrayList();
|
|
while(l > 0)
|
|
{
|
|
int ptr=ROProcessTools.nextDelimiter("<",str,l);
|
|
int cptr = (ptr==-1)?-1:ROProcessTools.nextDelimiter(">",str.Substring(ptr,str.Length - ptr),str.Length-ptr);
|
|
if(ptr == -1 || (ptr>-1 && cptr == -1))
|
|
{
|
|
Add(new seText(str,l));
|
|
l=0;
|
|
}
|
|
else
|
|
{
|
|
int cnt = ptr; //(int)(ptr-str);
|
|
if(cnt > 0)
|
|
{
|
|
Add(new seText(str,cnt));
|
|
l-=cnt;
|
|
str = str.Substring(ptr); // str=ptr
|
|
}
|
|
ptr=ROProcessTools.nextDelimiter(">",str,l)+1;
|
|
cnt = ptr;//(int)(ptr-str);
|
|
string tmpstr = str.Substring(1);
|
|
Add(new seUser(tmpstr,cnt-2));
|
|
l-=cnt;
|
|
str = str.Substring(ptr);//str=ptr;
|
|
}
|
|
}
|
|
}
|
|
|
|
public void Add (strEntry se)
|
|
{
|
|
aryStrEntry.Add(se);
|
|
}
|
|
|
|
public string toText()
|
|
{
|
|
StringBuilder bldstr = new StringBuilder();
|
|
for (int i=0; i < aryStrEntry.Count; i++)
|
|
{
|
|
bldstr.Append(((strEntry)aryStrEntry[i]).toText(0));
|
|
}
|
|
return bldstr.ToString();
|
|
}
|
|
}
|
|
|
|
public class varEntry
|
|
{
|
|
string Name;
|
|
int Len;
|
|
strList Definition;
|
|
|
|
public varEntry(string InName, string InDef, int lenInName, int lenInDef, varList vlist, menuList mlist)
|
|
{
|
|
Definition = new strList(InDef,lenInDef,vlist,mlist);
|
|
Name = InName.Substring(0,lenInName);
|
|
Len = lenInName;
|
|
}
|
|
|
|
public strList lookFor(string nam, int l)
|
|
{
|
|
string tname = nam.Substring(0,l);
|
|
if (l == Len && (Name.CompareTo(tname)==0))
|
|
return Definition; // found
|
|
return null; // not found
|
|
}
|
|
}
|
|
|
|
public class varList
|
|
{
|
|
ArrayList varEntryAry;
|
|
|
|
public varList()
|
|
{
|
|
varEntryAry = new ArrayList();
|
|
}
|
|
|
|
public void Add(string InName, string InDef, int lenInName, int lenInDef, menuList mlist)
|
|
{
|
|
varEntry tmpEntry = new varEntry(InName,InDef,lenInName,lenInDef,null,mlist);
|
|
varEntryAry.Add(tmpEntry);
|
|
}
|
|
|
|
public strList lookFor(string str, int len)
|
|
{
|
|
strList rtnval = null;
|
|
for (int i = 0; (rtnval == null) && (i < varEntryAry.Count); i++)
|
|
{
|
|
rtnval = ((varEntry)varEntryAry[i]).lookFor(str,len);
|
|
}
|
|
return rtnval;
|
|
}
|
|
}
|
|
|
|
public class seVarUse : strEntry
|
|
{
|
|
strList Def;
|
|
|
|
public seVarUse(strList d)
|
|
{
|
|
Def = d;
|
|
}
|
|
|
|
|
|
public override string toText(int mi)
|
|
{
|
|
return Def.toText(mi);
|
|
}
|
|
|
|
public override int getLength(int mi)
|
|
{
|
|
return Def.getLength(mi);
|
|
}
|
|
}
|
|
|
|
public class menuEntry
|
|
{
|
|
byte id;
|
|
strList definition;
|
|
|
|
public menuEntry(string idptr,string def,int li,int ld,varList vlst)
|
|
{
|
|
definition = new strList(def, ld, vlst,null);
|
|
// save the id
|
|
if(li != 0)
|
|
id=(byte)idptr[0];
|
|
else
|
|
id=0;
|
|
}
|
|
|
|
public int getLength(int mi)
|
|
{
|
|
if(mi==(int)id || mi==-1)
|
|
return definition.getLength(mi);
|
|
else
|
|
return 0;
|
|
}
|
|
|
|
public virtual string toText(int mi)
|
|
{
|
|
if (mi == id || mi==-1)
|
|
return definition.toText(mi);
|
|
else
|
|
return "";
|
|
}
|
|
|
|
public string getID()
|
|
{
|
|
string rtnstr = id.ToString();
|
|
return rtnstr;
|
|
}
|
|
|
|
public int getCount()
|
|
{
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
|
|
public class menuList : strEntry
|
|
{
|
|
ArrayList aryMenuList;
|
|
|
|
public menuList()
|
|
{
|
|
aryMenuList = new ArrayList();
|
|
}
|
|
|
|
public void Add(menuEntry MnuEntry)
|
|
{
|
|
aryMenuList.Add(MnuEntry);
|
|
}
|
|
|
|
private int _getLength(int mi)
|
|
{
|
|
int lcnt = aryMenuList.Count;
|
|
int rtnval =0;
|
|
|
|
for (int i=0; i < lcnt; i++)
|
|
{
|
|
rtnval += (((menuEntry)aryMenuList[i])).getLength(mi);
|
|
}
|
|
return rtnval;
|
|
}
|
|
|
|
private int _getLenAndLookat(int mi, ref int lookat)
|
|
{
|
|
int len =0;
|
|
lookat = mi;
|
|
|
|
if (aryMenuList.Count > 0)
|
|
{
|
|
len=_getLength(lookat);
|
|
if (len ==0)
|
|
{
|
|
lookat = 0;
|
|
len = _getLength(lookat);
|
|
}
|
|
if (len == 0)
|
|
{
|
|
lookat = -1;
|
|
len = _getLength(lookat);
|
|
}
|
|
}
|
|
|
|
return len;
|
|
}
|
|
|
|
public override int getLength(int mi)
|
|
{
|
|
int lookat=0;
|
|
return _getLenAndLookat(mi,ref lookat);
|
|
}
|
|
|
|
public override string toText(int mi)
|
|
{
|
|
StringBuilder rtnstr = new StringBuilder();
|
|
int lookat=0;
|
|
|
|
int len = _getLenAndLookat(mi,ref lookat);
|
|
if (aryMenuList.Count > 0)
|
|
{
|
|
for (int i = 0; i< aryMenuList.Count; i++)
|
|
{
|
|
string roval = ((menuEntry)aryMenuList[i]).toText(lookat);
|
|
if (lookat == -1)
|
|
{
|
|
// For Approve Individual, show all possible RO
|
|
// values (for conditional RO's)
|
|
// We may need to add a flag here later on when
|
|
// this logic is used in the Procedure Editor.
|
|
if (i > 0 && !roval.Equals(""))
|
|
rtnstr.Append("\n");
|
|
}
|
|
rtnstr.Append(roval);
|
|
}
|
|
}
|
|
return rtnstr.ToString();
|
|
}
|
|
|
|
public string getIds(ref int cnt)
|
|
{
|
|
StringBuilder rtnstr = new StringBuilder();
|
|
cnt = getCount();
|
|
int arycnt = aryMenuList.Count;
|
|
|
|
for (int i=0; i<arycnt; i++)
|
|
{
|
|
rtnstr.Append(((menuEntry)aryMenuList[i]).getID());
|
|
}
|
|
return rtnstr.ToString();
|
|
}
|
|
|
|
public int getCount()
|
|
{
|
|
int rtncnt=0;
|
|
int arycnt = aryMenuList.Count;
|
|
for (int i=0; i<arycnt; i++)
|
|
{
|
|
rtncnt+=(((menuEntry)aryMenuList[i]).getCount());
|
|
}
|
|
return rtncnt;
|
|
}
|
|
|
|
public void Process(string str,int l, varList v)
|
|
{
|
|
// get each piece and add a new entry
|
|
do
|
|
{
|
|
int end= ROProcessTools.matchingBrace(str);
|
|
int eq=str.IndexOf('=');
|
|
int len = end + 1; // +1 to include the '}'
|
|
int li = eq - 1;
|
|
int ld = len-li-3; // One for '{', '=' and '}'
|
|
Add(new menuEntry(str.Substring(1),str.Substring(eq+1),li,ld,v));
|
|
// point to the next piece
|
|
str = str.Substring(len);
|
|
l -= len;
|
|
} while(l > 0);
|
|
}
|
|
}
|
|
|
|
public class seMenuUse : strEntry
|
|
{
|
|
menuList ml;
|
|
|
|
public seMenuUse(menuList m)
|
|
{
|
|
ml=m;
|
|
}
|
|
|
|
public override string toText(int mi)
|
|
{
|
|
return ml.toText(mi);
|
|
}
|
|
|
|
public override int getLength(int mi)
|
|
{
|
|
return ml.getLength(mi);
|
|
}
|
|
}
|
|
|
|
}
|