public static bool Compile(Record r2, out string msg) { msg=null; r=new Record(); string script=null; int scptype=0; foreach(SubRecord sr2 in r2.SubRecords) { if(sr2.Name=="SCTX") script=sr2.GetStrData(); if(sr2.Name=="SCHR") { byte[] tmp=sr2.GetReadonlyData(); scptype=TypeConverter.h2si(tmp[16], tmp[17], tmp[18], tmp[19]); } } if(script==null) { msg="Script had no SCTX record to compile"; return false; } locals.Clear(); localList.Clear(); edidRefs.Clear(); refcount=0; errors.Clear(); ts=new TokenStream(script, errors); if(errors.Count>0) return OutputErrors( out msg); Token[] smt=ts.PopNextStatement(); if(smt.Length!=2||!smt[0].IsKeyword(Keywords.ScriptName)||smt[1].token==null) return ReturnError("Expected 'ScriptName <edid>'", out msg); SubRecord sr=new SubRecord(); sr.Name="EDID"; sr.SetStrData(smt[1].utoken, true); r.AddRecord(sr); r.descriptiveName=" ("+smt[1].token+")"; schr=new SubRecord(); schr.Name="SCHR"; r.AddRecord(schr); scda=new SubRecord(); scda.Name="SCDA"; r.AddRecord(scda); sr=new SubRecord(); sr.Name="SCTX"; sr.SetStrData(script, false); r.AddRecord(sr); bw=new BinaryWriter(new MemoryStream()); Emit(0x001d); Emit(0x0000); try { HandleVariables(); } catch(Exception ex) { return ReturnError(ex.Message, out msg); } for(int i=0;i<localList.Count;i++) { if(localList[i].type==VarType.Ref) { sr=new SubRecord(); sr.Name="SCRV"; sr.SetData(TypeConverter.si2h(i+1)); r.AddRecord(sr); refcount++; localList[i].refid=refcount; } } while(ts.PeekNextStatement().Length>0) { try { HandleBlock(); } catch(Exception ex) { return ReturnError(ex.Message, out msg); } } if(errors.Count>0) { return OutputErrors(out msg); } byte[] header=new byte[20]; TypeConverter.si2h(refcount, header, 4); TypeConverter.i2h((uint)bw.BaseStream.Length, header, 8); TypeConverter.si2h(localList.Count, header, 12); TypeConverter.si2h(scptype, header, 16); schr.SetData(header); byte[] compileddata=((MemoryStream)bw.BaseStream).GetBuffer(); if(compileddata.Length!=bw.BaseStream.Length) Array.Resize<byte>(ref compileddata, (int)bw.BaseStream.Length); scda.SetData(compileddata); r2.SubRecords.Clear(); r2.SubRecords.AddRange(r.SubRecords); bw.Close(); return true; }
/// <summary> /// Gets the well-known MESG record's subrecord data containg the critical record info. /// </summary> /// <remarks> /// If the required record is not found, it is created. /// </remarks> /// <returns>The well-known MESG record's subrecord data containg the critical record info.</returns> protected SubRecord getCriticalRecordData() { GroupRecord grcGroup = null; Record recCriticalRecords = null; SubRecord srcCriticalData = null; foreach (var rec in Records) { grcGroup = rec as GroupRecord; if (grcGroup == null) { continue; } if (grcGroup.ContentsType == "MESG") { foreach (Record recRecord in grcGroup.Records) { foreach (var srcSubRecord in recRecord.SubRecords) { switch (srcSubRecord.Name) { case "EDID": if (srcSubRecord.GetStrData().Equals(CRITICAL_DATA_RECORD_EDID)) { recCriticalRecords = recRecord; } break; case "DESC": srcCriticalData = srcSubRecord; break; } } if (recCriticalRecords != null) { return srcCriticalData; } } } } //if there is no MESG group, create one if (grcGroup == null) { grcGroup = new GroupRecord("MESG"); AddRecord(grcGroup); } //if there is no fommCriticalRecords record, create one, we returned otherwise. recCriticalRecords = new Record(); recCriticalRecords.Name = "MESG"; var uintMastersCount = (UInt32) Masters.Count << 24; var uintFormId = uintMastersCount + 1; while (ContainsFormId(uintFormId)) { uintFormId++; } if ((uintFormId & 0xff000000) != uintMastersCount) { throw new PluginFullException("No available Form Id for new MESG record"); } recCriticalRecords.FormID = uintFormId; recCriticalRecords.Flags2 = 0x00044210; recCriticalRecords.Flags3 = 0x0002000f; var srcSub = new SubRecord(); srcSub.Name = "EDID"; srcSub.SetStrData(CRITICAL_DATA_RECORD_EDID, true); recCriticalRecords.SubRecords.Add(srcSub); srcCriticalData = new SubRecord(); srcCriticalData.Name = "DESC"; recCriticalRecords.SubRecords.Add(srcCriticalData); srcSub = new SubRecord(); srcSub.Name = "INAM"; srcSub.SetData(new byte[] { 0, 0, 0, 0 }); recCriticalRecords.SubRecords.Add(srcSub); srcSub = new SubRecord(); srcSub.Name = "DNAM"; srcSub.SetData(new byte[] { 0, 0, 0, 0 }); recCriticalRecords.SubRecords.Add(srcSub); srcSub = new SubRecord(); srcSub.Name = "TNAM"; srcSub.SetData(new byte[] { 0, 0, 0, 1 }); recCriticalRecords.SubRecords.Add(srcSub); grcGroup.AddRecord(recCriticalRecords); return srcCriticalData; }
private static void HandleVariables() { Token[] smt=ts.PeekNextStatement(); SubRecord slsd; SubRecord scvr; while(smt.Length>0&&smt[0].IsType()) { ts.PopNextStatement(); if(smt.Length!=2||smt[1].type!=TokenType.Unknown) { AddError("Expected <type> <variable name>"); smt=ts.PeekNextStatement(); continue; } slsd=new SubRecord(); slsd.Name="SLSD"; byte[] data=new byte[24]; TypeConverter.si2h(locals.Count+1, data, 0); if(smt[0].IsKeyword(Keywords.Int)) data[16]=1; slsd.SetData(data); r.AddRecord(slsd); scvr=new SubRecord(); scvr.Name="SCVR"; scvr.SetStrData(smt[1].utoken, true); r.AddRecord(scvr); LocalVar lv=new LocalVar(locals.Count+1, smt[0]); locals.Add(smt[1].token, lv); localList.Add(lv); ts.AddLocal(smt[1].token); smt=ts.PeekNextStatement(); } }