// ======================================================================== // Copyright 2006 - Volian Enterprises, Inc. All rights reserved. // Volian Enterprises - Proprietary Information - DO NOT COPY OR DISTRIBUTE // ------------------------------------------------------------------------ // $Workfile: $ $Revision: $ // $Author: $ $Date: $ // // $History: $ // ======================================================================== using System; using System.Collections.Generic; using System.Collections.Specialized; using System.Text; using System.IO; using System.Xml.Serialization; using System.Xml; using System.Xml.XPath; namespace DataLoader { public class ROFST { #region Log4Net private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); #endregion [Serializable] public struct roHdr { public int hSize; public int hYear; public byte hMonth; public byte hDay; public int hcYear; public byte hcMonth; public byte hcDay; public byte hcHour; public byte hcMin; public byte hcSec; public byte hcHund; public rodbi[] myDbs; }; [Serializable] public struct rodbi { public int dbiID; public int dbiType; public int dbiAW; public string dbiTitle; public string dbiAP; public int ID; public int ParentID; public rochild[] children; }; public struct rogrp { public int ID; public int ParentID; public rochild[] children; public string value; public string appid; }; public struct rochild { public int ID; public int ParentID; public int type; public string title; public string roid; public string appid; public string value; public rochild[] children; }; private roHdr myHdr; private int TableID; private string fstPath; private HybridDictionary dicRos; public ROFST(string path) { fstPath = path; if (!File.Exists(fstPath)) { log.ErrorFormat("RO FST Does not exist: {0}", path); return; } dicRos = new HybridDictionary(); ParseIntoDictionary(); } public void Close() { // remove the dictionary dicRos.Clear(); dicRos = null; } // this only gets rochild values. Later we may want another // dictionary to get groups. public string GetRoValue(string ROID) { // Use the ROID to get the value from the dictionary if (dicRos.Contains(ROID)) { rochild rochld = (rochild)dicRos[ROID]; return rochld.value; } return null; } private int StringLength(byte[] ab, int offset) { int i = 0; while (ab[i + offset] != 0) i++; return i; } private rogrp LoadGroup(byte[] ab, int offset) { rogrp myGrp = new rogrp(); myGrp.ID = BitConverter.ToInt32(ab, offset); myGrp.ParentID = BitConverter.ToInt32(ab, offset + 4); int howmany = BitConverter.ToInt16(ab, offset + 8); if (howmany > 0) { myGrp.children = new rochild[howmany]; int myOffset = offset + 10; for (int i = 0; i < myGrp.children.Length; i++) { int childOffset = BitConverter.ToInt32(ab, myOffset); rochild tmp = new rochild(); //tmp.offset=BitConverter.ToInt32(ab,myOffset); tmp.type = BitConverter.ToInt16(ab, myOffset + 4); int slen = StringLength(ab, myOffset + 6); tmp.title = Encoding.Default.GetString(ab, myOffset + 6, slen); myOffset += (7 + slen); rogrp tmpg = LoadGroup(ab, childOffset); tmp.ID = tmpg.ID; tmp.ParentID = tmpg.ParentID; tmp.children = tmpg.children; tmp.value = tmpg.value; tmp.appid = tmpg.appid; tmp.roid = TableID.ToString("X4") + tmp.ID.ToString("X8"); dicRos.Add(tmp.roid, tmp); int j; for (j = i - 1; j >= 0 && tmp.ID < myGrp.children[j].ID; j--) { myGrp.children[j + 1] = myGrp.children[j]; } myGrp.children[j + 1] = tmp; } } else { int slen = StringLength(ab, offset + 12); myGrp.value = Encoding.Default.GetString(ab, offset + 12, slen); int slen2 = StringLength(ab, offset + 13 + slen); myGrp.appid = Encoding.Default.GetString(ab, offset + 13 + slen, slen2); } return myGrp; } private void ParseIntoDictionary() { FileStream fsIn = new FileStream(fstPath, FileMode.Open,FileAccess.Read, FileShare.Read); // Create an instance of StreamReader that can read // characters from the FileStream. BinaryReader r = new BinaryReader(fsIn); byte[] ab = r.ReadBytes((int)fsIn.Length); r.Close(); myHdr.hSize = BitConverter.ToInt32(ab, 0); myHdr.hYear = BitConverter.ToInt16(ab, 4); myHdr.hMonth = ab[6]; myHdr.hDay = ab[7]; myHdr.hcYear = BitConverter.ToInt16(ab, 8); myHdr.hcMonth = ab[10]; myHdr.hcDay = ab[11]; myHdr.hcHour = ab[12]; myHdr.hcMin = ab[13]; myHdr.hcSec = ab[14]; myHdr.hcHund = ab[15]; int hdrOffset = BitConverter.ToInt32(ab, 16); int howbig = BitConverter.ToInt32(ab, hdrOffset); int dbs = BitConverter.ToInt16(ab, hdrOffset + 4); myHdr.myDbs = new rodbi[dbs]; for (int i = 0; i < dbs; i++) { int offset = hdrOffset + 6 + (i * 30); myHdr.myDbs[i].dbiID = BitConverter.ToInt16(ab, offset + 0); TableID = myHdr.myDbs[i].dbiID; myHdr.myDbs[i].dbiType = BitConverter.ToInt16(ab, offset + 2); myHdr.myDbs[i].dbiAW = BitConverter.ToInt16(ab, offset + 4); rogrp tmp = LoadGroup(ab, BitConverter.ToInt32(ab, offset + 6)); myHdr.myDbs[i].ID = tmp.ID; myHdr.myDbs[i].children = tmp.children; int iPtr = BitConverter.ToInt32(ab, offset + 22) + hdrOffset + 6; myHdr.myDbs[i].dbiTitle = Encoding.Default.GetString(ab, iPtr, StringLength(ab, iPtr)); iPtr = BitConverter.ToInt32(ab, offset + 26) + hdrOffset + 6; myHdr.myDbs[i].dbiAP = Encoding.Default.GetString(ab, iPtr, StringLength(ab, iPtr)); } } public bool SaveToXml(string fname) { try { StreamWriter swxml = new StreamWriter(fname); XmlSerializer mySer = new XmlSerializer(typeof(roHdr)); mySer.Serialize(swxml, myHdr); swxml.Close(); } catch (Exception ex) { log.ErrorFormat("Error writing to file: {0}", ex.Message); return false; } return true; } public XmlDocument GetXmlFromFile(string fname) { FileStream xmlIn = new FileStream(fname, FileMode.Open, FileAccess.Read, FileShare.Read); XmlDocument xmlDoc = new XmlDocument(); xmlDoc.Load(xmlIn); xmlIn.Close(); return xmlDoc; } public string GetValueFromXml(XmlDocument xmlDoc, string ROID) { // use roid as xpath to get data. try { string xpath_roid = "//rochild[roid = \"" + ROID.Substring(0, 12) + "\"]/value"; XmlNode valnd = xmlDoc.SelectSingleNode(xpath_roid); if (valnd == null) return null; return valnd.InnerText; } catch (Exception ex) { log.ErrorFormat("Cannot find ro in XmlDocument "); log.ErrorFormat("roid = {0}", ROID); log.ErrorFormat("{0}\r\n\r\n{1}", ex.Message, ex.InnerException); } return null; } } }