ClassRecord.cs 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648
  1. /*
  2. * Copyright (c) Contributors, http://opensimulator.org/
  3. * See CONTRIBUTORS.TXT for a full list of copyright holders.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions are met:
  7. * * Redistributions of source code must retain the above copyright
  8. * notice, this list of conditions and the following disclaimer.
  9. * * Redistributions in binary form must reproduce the above copyright
  10. * notice, this list of conditions and the following disclaimer in the
  11. * documentation and/or other materials provided with the distribution.
  12. * * Neither the name of the OpenSim Project nor the
  13. * names of its contributors may be used to endorse or promote products
  14. * derived from this software without specific prior written permission.
  15. *
  16. * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
  17. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  18. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  19. * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
  20. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  21. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  22. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  23. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  24. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  25. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  26. */
  27. using System;
  28. using System.Collections.Generic;
  29. using System.IO;
  30. using OpenSim.Region.ExtensionsScriptModule.JVMEngine.Types;
  31. using OpenSim.Region.ExtensionsScriptModule.JVMEngine.Types.PrimitiveTypes;
  32. namespace OpenSim.Region.ExtensionsScriptModule.JVMEngine.JVM
  33. {
  34. public class ClassRecord
  35. {
  36. private ushort m_majorVersion;
  37. private ushort m_minorVersion;
  38. private ushort m_constantPoolCount;
  39. private ushort m_accessFlags;
  40. private ushort m_thisClass;
  41. private ushort m_supperClass;
  42. private ushort m_interfaceCount;
  43. private ushort m_fieldCount;
  44. private ushort m_methodCount;
  45. //private ushort _attributeCount;
  46. //private string _name;
  47. public Dictionary<string, BaseType> StaticFields = new Dictionary<string, BaseType>();
  48. public PoolClass MClass;
  49. public List<PoolItem> m_constantsPool = new List<PoolItem>();
  50. private List<MethodInfo> m_methodsList = new List<MethodInfo>();
  51. private List<FieldInfo> m_fieldList = new List<FieldInfo>();
  52. public ClassRecord()
  53. {
  54. }
  55. public ClassInstance CreateNewInstance()
  56. {
  57. ClassInstance classInst = new ClassInstance();
  58. classInst.ClassRec = this;
  59. //TODO: set fields
  60. return classInst;
  61. }
  62. public void LoadClassFromFile(string fileName)
  63. {
  64. Console.WriteLine("loading script " + fileName);
  65. FileStream fs = File.OpenRead(fileName);
  66. LoadClassFromBytes(ReadFully(fs));
  67. fs.Close();
  68. }
  69. public void LoadClassFromBytes(byte[] data)
  70. {
  71. int i = 0;
  72. i += 4;
  73. m_minorVersion = (ushort) ((data[i++] << 8) + data[i++]);
  74. m_majorVersion = (ushort) ((data[i++] << 8) + data[i++]);
  75. m_constantPoolCount = (ushort) ((data[i++] << 8) + data[i++]);
  76. Console.WriteLine("there should be " + m_constantPoolCount + " items in the pool");
  77. for (int count = 0; count < (m_constantPoolCount - 1); count++)
  78. {
  79. //read in the constant pool
  80. byte pooltype = data[i++];
  81. Console.WriteLine("#" + count + ": new constant type = " + pooltype);
  82. //Console.WriteLine("start position is: " + i);
  83. switch (pooltype)
  84. {
  85. case 1: //Utf8
  86. ushort uLength = (ushort) ((data[i++] << 8) + data[i++]);
  87. // Console.WriteLine("new utf8 type, length is " + uLength);
  88. PoolUtf8 utf8 = new PoolUtf8();
  89. utf8.readValue(data, ref i, uLength);
  90. m_constantsPool.Add(utf8);
  91. break;
  92. case 3: //Int
  93. break;
  94. case 4: //Float
  95. break;
  96. case 7: //Class
  97. PoolClass pClass = new PoolClass(this);
  98. pClass.readValue(data, ref i);
  99. m_constantsPool.Add(pClass);
  100. break;
  101. case 9: //FieldRef
  102. PoolFieldRef pField = new PoolFieldRef(this);
  103. pField.readValue(data, ref i);
  104. m_constantsPool.Add(pField);
  105. break;
  106. case 10: //Method
  107. PoolMethodRef pMeth = new PoolMethodRef(this);
  108. pMeth.readValue(data, ref i);
  109. m_constantsPool.Add(pMeth);
  110. break;
  111. case 12: //NamedType
  112. PoolNamedType pNamed = new PoolNamedType(this);
  113. pNamed.readValue(data, ref i);
  114. m_constantsPool.Add(pNamed);
  115. break;
  116. }
  117. }
  118. m_accessFlags = (ushort) ((data[i++] << 8) + data[i++]);
  119. m_thisClass = (ushort) ((data[i++] << 8) + data[i++]);
  120. m_supperClass = (ushort) ((data[i++] << 8) + data[i++]);
  121. if (m_constantsPool[m_thisClass - 1] is PoolClass)
  122. {
  123. MClass = ((PoolClass) m_constantsPool[m_thisClass - 1]);
  124. }
  125. m_interfaceCount = (ushort) ((data[i++] << 8) + data[i++]);
  126. //should now read in the info for each interface
  127. m_fieldCount = (ushort) ((data[i++] << 8) + data[i++]);
  128. //should now read in the info for each field
  129. for (int count = 0; count < m_fieldCount; count++)
  130. {
  131. FieldInfo fieldInf = new FieldInfo(this);
  132. fieldInf.ReadData(data, ref i);
  133. m_fieldList.Add(fieldInf);
  134. }
  135. m_methodCount = (ushort) ((data[i++] << 8) + data[i++]);
  136. for (int count = 0; count < m_methodCount; count++)
  137. {
  138. MethodInfo methInf = new MethodInfo(this);
  139. methInf.ReadData(data, ref i);
  140. m_methodsList.Add(methInf);
  141. }
  142. }
  143. public void AddMethodsToMemory(MethodMemory memory)
  144. {
  145. for (int count = 0; count < m_methodCount; count++)
  146. {
  147. m_methodsList[count].AddMethodCode(memory);
  148. }
  149. }
  150. public bool StartMethod(Thread thread, string methodName)
  151. {
  152. for (int count = 0; count < m_methodCount; count++)
  153. {
  154. if (m_constantsPool[m_methodsList[count].NameIndex - 1] is PoolUtf8)
  155. {
  156. if (((PoolUtf8) m_constantsPool[m_methodsList[count].NameIndex - 1]).Value == methodName)
  157. {
  158. //Console.WriteLine("found method: " + ((PoolUtf8)this._constantsPool[this._methodsList[count].NameIndex - 1]).Value);
  159. thread.SetPC(m_methodsList[count].CodePointer);
  160. return true;
  161. }
  162. }
  163. }
  164. return false;
  165. }
  166. public void PrintToConsole()
  167. {
  168. Console.WriteLine("Class File:");
  169. Console.WriteLine("Major version: " + m_majorVersion);
  170. Console.WriteLine("Minor version: " + m_minorVersion);
  171. Console.WriteLine("Pool size: " + m_constantPoolCount);
  172. for (int i = 0; i < m_constantsPool.Count; i++)
  173. {
  174. m_constantsPool[i].Print();
  175. }
  176. Console.WriteLine("Access flags: " + m_accessFlags);
  177. Console.WriteLine("This class: " + m_thisClass);
  178. Console.WriteLine("Super class: " + m_supperClass);
  179. for (int count = 0; count < m_fieldCount; count++)
  180. {
  181. Console.WriteLine();
  182. m_fieldList[count].Print();
  183. }
  184. for (int count = 0; count < m_methodCount; count++)
  185. {
  186. Console.WriteLine();
  187. m_methodsList[count].Print();
  188. }
  189. Console.WriteLine("class name is " + MClass.Name.Value);
  190. }
  191. public static byte[] ReadFully(Stream stream)
  192. {
  193. byte[] buffer = new byte[1024];
  194. using (MemoryStream ms = new MemoryStream())
  195. {
  196. while (true)
  197. {
  198. int read = stream.Read(buffer, 0, buffer.Length);
  199. if (read <= 0)
  200. return ms.ToArray();
  201. ms.Write(buffer, 0, read);
  202. }
  203. }
  204. }
  205. #region nested classes
  206. public class PoolItem
  207. {
  208. public virtual void Print()
  209. {
  210. }
  211. }
  212. public class PoolUtf8 : PoolItem
  213. {
  214. public string Value = String.Empty;
  215. public void readValue(byte[] data, ref int pointer, int length)
  216. {
  217. for (int i = 0; i < length; i++)
  218. {
  219. int a = (int) data[pointer++];
  220. if ((a & 0x80) == 0)
  221. {
  222. Value = Value + (char) a;
  223. }
  224. else if ((a & 0x20) == 0)
  225. {
  226. int b = (int) data[pointer++];
  227. Value = Value + (char) (((a & 0x1f) << 6) + (b & 0x3f));
  228. }
  229. else
  230. {
  231. int b = (int) data[pointer++];
  232. int c = (int) data[pointer++];
  233. Value = Value + (char) (((a & 0xf) << 12) + ((b & 0x3f) << 6) + (c & 0x3f));
  234. }
  235. }
  236. }
  237. public override void Print()
  238. {
  239. Console.WriteLine("Utf8 type: " + Value);
  240. }
  241. }
  242. private class PoolInt : PoolItem
  243. {
  244. }
  245. public class PoolClass : PoolItem
  246. {
  247. //public string name = String.Empty;
  248. public ushort namePointer = 0;
  249. private ClassRecord parent;
  250. public PoolUtf8 Name;
  251. public PoolClass(ClassRecord paren)
  252. {
  253. parent = paren;
  254. }
  255. public void readValue(byte[] data, ref int pointer)
  256. {
  257. namePointer = (ushort) ((data[pointer++] << 8) + data[pointer++]);
  258. }
  259. public override void Print()
  260. {
  261. Name = ((PoolUtf8) parent.m_constantsPool[namePointer - 1]);
  262. Console.Write("Class type: " + namePointer);
  263. Console.WriteLine(" // " + ((PoolUtf8) parent.m_constantsPool[namePointer - 1]).Value);
  264. }
  265. }
  266. public class PoolFieldRef : PoolItem
  267. {
  268. public ushort classPointer = 0;
  269. public ushort nameTypePointer = 0;
  270. public PoolNamedType mNameType;
  271. public PoolClass mClass;
  272. private ClassRecord parent;
  273. public PoolFieldRef(ClassRecord paren)
  274. {
  275. parent = paren;
  276. }
  277. public void readValue(byte[] data, ref int pointer)
  278. {
  279. classPointer = (ushort) ((data[pointer++] << 8) + data[pointer++]);
  280. nameTypePointer = (ushort) ((data[pointer++] << 8) + data[pointer++]);
  281. }
  282. public override void Print()
  283. {
  284. mNameType = ((PoolNamedType) parent.m_constantsPool[nameTypePointer - 1]);
  285. mClass = ((PoolClass) parent.m_constantsPool[classPointer - 1]);
  286. Console.WriteLine("FieldRef type: " + classPointer + " , " + nameTypePointer);
  287. }
  288. }
  289. public class PoolMethodRef : PoolItem
  290. {
  291. public ushort classPointer = 0;
  292. public ushort nameTypePointer = 0;
  293. public PoolNamedType mNameType;
  294. public PoolClass mClass;
  295. private ClassRecord parent;
  296. public PoolMethodRef(ClassRecord paren)
  297. {
  298. parent = paren;
  299. }
  300. public void readValue(byte[] data, ref int pointer)
  301. {
  302. classPointer = (ushort) ((data[pointer++] << 8) + data[pointer++]);
  303. nameTypePointer = (ushort) ((data[pointer++] << 8) + data[pointer++]);
  304. }
  305. public override void Print()
  306. {
  307. mNameType = ((PoolNamedType) parent.m_constantsPool[nameTypePointer - 1]);
  308. mClass = ((PoolClass) parent.m_constantsPool[classPointer - 1]);
  309. Console.WriteLine("MethodRef type: " + classPointer + " , " + nameTypePointer);
  310. }
  311. }
  312. public class PoolNamedType : PoolItem
  313. {
  314. public ushort namePointer = 0;
  315. public ushort typePointer = 0;
  316. private ClassRecord parent;
  317. public PoolUtf8 Name;
  318. public PoolUtf8 Type;
  319. public PoolNamedType(ClassRecord paren)
  320. {
  321. parent = paren;
  322. }
  323. public void readValue(byte[] data, ref int pointer)
  324. {
  325. namePointer = (ushort) ((data[pointer++] << 8) + data[pointer++]);
  326. typePointer = (ushort) ((data[pointer++] << 8) + data[pointer++]);
  327. }
  328. public override void Print()
  329. {
  330. Name = ((PoolUtf8) parent.m_constantsPool[namePointer - 1]);
  331. Type = ((PoolUtf8) parent.m_constantsPool[typePointer - 1]);
  332. Console.Write("Named type: " + namePointer + " , " + typePointer);
  333. Console.WriteLine(" // " + ((PoolUtf8) parent.m_constantsPool[namePointer - 1]).Value);
  334. }
  335. }
  336. //***********************
  337. public class MethodInfo
  338. {
  339. public ushort AccessFlags = 0;
  340. public ushort NameIndex = 0;
  341. public string Name = String.Empty;
  342. public ushort DescriptorIndex = 0;
  343. public ushort AttributeCount = 0;
  344. public List<MethodAttribute> Attributes = new List<MethodAttribute>();
  345. private ClassRecord parent;
  346. public int CodePointer = 0;
  347. public MethodInfo(ClassRecord paren)
  348. {
  349. parent = paren;
  350. }
  351. public void AddMethodCode(MethodMemory memory)
  352. {
  353. Array.Copy(Attributes[0].Code, 0, memory.MethodBuffer, memory.NextMethodPC, Attributes[0].Code.Length);
  354. memory.Methodcount++;
  355. CodePointer = memory.NextMethodPC;
  356. memory.NextMethodPC += Attributes[0].Code.Length;
  357. }
  358. public void ReadData(byte[] data, ref int pointer)
  359. {
  360. AccessFlags = (ushort) ((data[pointer++] << 8) + data[pointer++]);
  361. NameIndex = (ushort) ((data[pointer++] << 8) + data[pointer++]);
  362. DescriptorIndex = (ushort) ((data[pointer++] << 8) + data[pointer++]);
  363. AttributeCount = (ushort) ((data[pointer++] << 8) + data[pointer++]);
  364. for (int i = 0; i < AttributeCount; i++)
  365. {
  366. MethodAttribute attri = new MethodAttribute(parent);
  367. attri.ReadData(data, ref pointer);
  368. Attributes.Add(attri);
  369. }
  370. }
  371. public void Print()
  372. {
  373. Console.WriteLine("Method Info Struct: ");
  374. Console.WriteLine("AccessFlags: " + AccessFlags);
  375. Console.WriteLine("NameIndex: " + NameIndex + " // " +
  376. ((PoolUtf8) parent.m_constantsPool[NameIndex - 1]).Value);
  377. Console.WriteLine("DescriptorIndex: " + DescriptorIndex + " // " +
  378. ((PoolUtf8) parent.m_constantsPool[DescriptorIndex - 1]).Value);
  379. Console.WriteLine("Attribute Count:" + AttributeCount);
  380. for (int i = 0; i < AttributeCount; i++)
  381. {
  382. Attributes[i].Print();
  383. }
  384. }
  385. public class MethodAttribute
  386. {
  387. public ushort NameIndex = 0;
  388. public string Name = String.Empty;
  389. public Int32 Length = 0;
  390. //for now only support code attribute
  391. public ushort MaxStack = 0;
  392. public ushort MaxLocals = 0;
  393. public Int32 CodeLength = 0;
  394. public byte[] Code;
  395. public ushort ExceptionTableLength = 0;
  396. public ushort SubAttributeCount = 0;
  397. public List<SubAttribute> SubAttributes = new List<SubAttribute>();
  398. private ClassRecord parent;
  399. public MethodAttribute(ClassRecord paren)
  400. {
  401. parent = paren;
  402. }
  403. public void ReadData(byte[] data, ref int pointer)
  404. {
  405. NameIndex = (ushort) ((data[pointer++] << 8) + data[pointer++]);
  406. Length =
  407. (Int32)
  408. ((data[pointer++] << 24) + (data[pointer++] << 16) + (data[pointer++] << 8) + data[pointer++]);
  409. MaxStack = (ushort) ((data[pointer++] << 8) + data[pointer++]);
  410. MaxLocals = (ushort) ((data[pointer++] << 8) + data[pointer++]);
  411. CodeLength =
  412. (Int32)
  413. ((data[pointer++] << 24) + (data[pointer++] << 16) + (data[pointer++] << 8) + data[pointer++]);
  414. Code = new byte[CodeLength];
  415. for (int i = 0; i < CodeLength; i++)
  416. {
  417. Code[i] = data[pointer++];
  418. }
  419. ExceptionTableLength = (ushort) ((data[pointer++] << 8) + data[pointer++]);
  420. SubAttributeCount = (ushort) ((data[pointer++] << 8) + data[pointer++]);
  421. for (int i = 0; i < SubAttributeCount; i++)
  422. {
  423. SubAttribute subAttri = new SubAttribute(parent);
  424. subAttri.ReadData(data, ref pointer);
  425. SubAttributes.Add(subAttri);
  426. }
  427. }
  428. public void Print()
  429. {
  430. Console.WriteLine("Method Attribute: ");
  431. Console.WriteLine("Name Index: " + NameIndex + " // " +
  432. ((PoolUtf8) parent.m_constantsPool[NameIndex - 1]).Value);
  433. Console.WriteLine("Length: " + Length);
  434. Console.WriteLine("MaxStack: " + MaxStack);
  435. Console.WriteLine("MaxLocals: " + MaxLocals);
  436. Console.WriteLine("CodeLength: " + CodeLength);
  437. for (int i = 0; i < Code.Length; i++)
  438. {
  439. Console.WriteLine("OpCode #" + i + " is: " + Code[i]);
  440. }
  441. Console.WriteLine("SubAttributes: " + SubAttributeCount);
  442. for (int i = 0; i < SubAttributeCount; i++)
  443. {
  444. SubAttributes[i].Print();
  445. }
  446. }
  447. public class SubAttribute
  448. {
  449. public ushort NameIndex = 0;
  450. public string Name = String.Empty;
  451. public Int32 Length = 0;
  452. public byte[] Data;
  453. private ClassRecord parent;
  454. public SubAttribute(ClassRecord paren)
  455. {
  456. parent = paren;
  457. }
  458. public void ReadData(byte[] data, ref int pointer)
  459. {
  460. NameIndex = (ushort) ((data[pointer++] << 8) + data[pointer++]);
  461. Length =
  462. (Int32)
  463. ((data[pointer++] << 24) + (data[pointer++] << 16) + (data[pointer++] << 8) +
  464. data[pointer++]);
  465. Data = new byte[Length];
  466. for (int i = 0; i < Length; i++)
  467. {
  468. Data[i] = data[pointer++];
  469. }
  470. }
  471. public void Print()
  472. {
  473. Console.WriteLine("SubAttribute: NameIndex: " + NameIndex + " // " +
  474. ((PoolUtf8) parent.m_constantsPool[NameIndex - 1]).Value);
  475. }
  476. }
  477. }
  478. }
  479. private class InterfaceInfo
  480. {
  481. public void ReadData(byte[] data, ref int i)
  482. {
  483. }
  484. }
  485. public class FieldInfo
  486. {
  487. public ushort AccessFlags = 0;
  488. public ushort NameIndex = 0;
  489. public string Name = String.Empty;
  490. public ushort DescriptorIndex = 0;
  491. public ushort AttributeCount = 0;
  492. public List<FieldAttribute> Attributes = new List<FieldAttribute>();
  493. private ClassRecord parent;
  494. public FieldInfo(ClassRecord paren)
  495. {
  496. parent = paren;
  497. }
  498. public void ReadData(byte[] data, ref int pointer)
  499. {
  500. AccessFlags = (ushort) ((data[pointer++] << 8) + data[pointer++]);
  501. NameIndex = (ushort) ((data[pointer++] << 8) + data[pointer++]);
  502. DescriptorIndex = (ushort) ((data[pointer++] << 8) + data[pointer++]);
  503. AttributeCount = (ushort) ((data[pointer++] << 8) + data[pointer++]);
  504. for (int i = 0; i < AttributeCount; i++)
  505. {
  506. FieldAttribute attri = new FieldAttribute(parent);
  507. attri.ReadData(data, ref pointer);
  508. Attributes.Add(attri);
  509. }
  510. }
  511. public void Print()
  512. {
  513. Console.WriteLine("Field Info Struct: ");
  514. Console.WriteLine("AccessFlags: " + AccessFlags);
  515. Console.WriteLine("NameIndex: " + NameIndex + " // " +
  516. ((PoolUtf8) parent.m_constantsPool[NameIndex - 1]).Value);
  517. Console.WriteLine("DescriptorIndex: " + DescriptorIndex + " // " +
  518. ((PoolUtf8) parent.m_constantsPool[DescriptorIndex - 1]).Value);
  519. Console.WriteLine("Attribute Count:" + AttributeCount);
  520. //if static, add to static field list
  521. // if (this.AccessFlags == 9) //public and static
  522. if ((AccessFlags & 0x08) != 0)
  523. {
  524. switch (((PoolUtf8) parent.m_constantsPool[DescriptorIndex - 1]).Value)
  525. {
  526. case "I":
  527. Int newin = new Int();
  528. parent.StaticFields.Add(((PoolUtf8) parent.m_constantsPool[NameIndex - 1]).Value, newin);
  529. break;
  530. case "F":
  531. Float newfl = new Float();
  532. parent.StaticFields.Add(((PoolUtf8) parent.m_constantsPool[NameIndex - 1]).Value, newfl);
  533. break;
  534. }
  535. }
  536. for (int i = 0; i < AttributeCount; i++)
  537. {
  538. Attributes[i].Print();
  539. }
  540. }
  541. public class FieldAttribute
  542. {
  543. public ushort NameIndex = 0;
  544. public string Name = String.Empty;
  545. public Int32 Length = 0;
  546. public byte[] Data;
  547. private ClassRecord parent;
  548. public FieldAttribute(ClassRecord paren)
  549. {
  550. parent = paren;
  551. }
  552. public void ReadData(byte[] data, ref int pointer)
  553. {
  554. NameIndex = (ushort) ((data[pointer++] << 8) + data[pointer++]);
  555. Length =
  556. (Int32)
  557. ((data[pointer++] << 24) + (data[pointer++] << 16) + (data[pointer++] << 8) + data[pointer++]);
  558. Data = new byte[Length];
  559. for (int i = 0; i < Length; i++)
  560. {
  561. Data[i] = data[pointer++];
  562. }
  563. }
  564. public void Print()
  565. {
  566. Console.WriteLine("FieldAttribute: NameIndex: " + NameIndex + " // " +
  567. ((PoolUtf8) parent.m_constantsPool[NameIndex - 1]).Value);
  568. }
  569. }
  570. }
  571. private class AttributeInfo
  572. {
  573. public void ReadData(byte[] data, ref int i)
  574. {
  575. }
  576. }
  577. #endregion
  578. }
  579. }