/********************************************************************************************* * 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 description for ROFSTHeader. /// 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 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 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) { 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 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 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); } } }