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);
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| }
 |