/// <summary> /// Comparison of two bits arrays. /// </summary> /// <param name="a">An other bits array.</param> /// <returns>True, is arrays equals.</returns> public override bool Equals(object a) { if (a == null) { return(false); } if (a.GetType() != this.GetType()) { return(false); } BitArr b = (BitArr)a; if (b.size != size) { return(false); } if (size == 0) { return(true); } for (int i = 0; i < BS2WS(size); i++) { if (b.words[i] != words[i]) { return(false); } } return(true); }
/// <summary> /// Creates a new object that is a deep copy of the current instance. /// </summary> /// <returns>A new object that is a deep copy of this instance.</returns> public object Clone() { BitArr ret = new BitArr(); if (words != null) ret.words = (uint[])words.Clone(); else ret.words = null; ret.size = size; return ret; }
/// <summary> /// Creates a new object that is a deep copy of the current instance. /// </summary> /// <returns>A new object that is a deep copy of this instance.</returns> public object Clone() { BitArr ret = new BitArr(); if (words != null) { ret.words = (uint[])words.Clone(); } else { ret.words = null; } ret.size = size; return(ret); }
/// <summary> /// Bitwise Or. /// </summary> /// <param name="a">First bits array.</param> /// <param name="b">Second bits array.</param> /// <returns>a bitwise or b</returns> public static BitArr operator|(BitArr a, BitArr b) { if (a == null && b == null) { return(null); } else if (a == null) { return((BitArr)b.Clone()); } else if (b == null) { return((BitArr)a.Clone()); } int rla = a.RealLength; int rlb = b.RealLength; int rlc = Math.Max(rla, rlb); int wla = BS2WS(rla); int wlb = BS2WS(rlb); int wlc = BS2WS(rlc); BitArr c = new BitArr(rlc); for (int i = 0; i < wlc; i++) { if (i > wla) { c.words[i] = b.words[i]; } else if (i > wlb) { c.words[i] = a.words[i]; } else { c.words[i] = a.words[i] | b.words[i]; } } return(c); }
/// <summary> /// Performs memberwise copy from BitArr. /// </summary> /// <param name="ba">Source BitArr.</param> /// <remarks>I use it to avoid ****ing "Compiler Error CS1540" in derived /// class's cast methods.</remarks> protected void Assign(BitArr ba) { this.words = ba.words; this.size = ba.size; }
private bool ParseValuesUpdateBlock(GenericReader gr, StringBuilder sb, StreamWriter swe, StreamWriter data, ObjectTypes objectTypeId, UpdateTypes updatetype) { // may be we can reduce size of code there... sb.AppendLine("=== values_update_block_start ==="); byte blocks_count = gr.ReadByte(); // count of update blocks (4 bytes for each update block) sb.AppendLine("Bit mask blocks count: " + blocks_count); uint[] updatemask = new uint[blocks_count]; // create array of update blocks for (int j = 0; j < blocks_count; j++) { updatemask[j] = gr.ReadUInt32(); // populate array of update blocks with data } Mask = (BitArr)updatemask; // convert array of update blocks to bitmask array int reallength = Mask.RealLength; // bitmask size (bits) // item/container values update block if (objectTypeId == ObjectTypes.TYPEID_ITEM || objectTypeId == ObjectTypes.TYPEID_CONTAINER) { if (reallength > 160) // 5*32, ?? { long pos = gr.BaseStream.Position; swe.WriteLine("error position " + pos.ToString("X2")); swe.WriteLine("error while parsing ITEM values update block, count " + reallength); return(false); } for (uint index = 0; index < reallength; index++) { if (index > UpdateFields.ITEM_END) { break; } if (Mask[index]) { switch (UpdateFields.item_updatefields[index].type) { case 1: sb.AppendLine(UpdateFields.item_updatefields[index].name + " (" + index + "): " + gr.ReadSingle().ToString().Replace(",", ".")); break; default: sb.AppendLine(UpdateFields.item_updatefields[index].name + " (" + index + "): " + gr.ReadUInt32()); break; } } } } // unit values update block if (objectTypeId == ObjectTypes.TYPEID_UNIT) { if (reallength > 256) // 32*8 (for units bitmask = 8) { long pos = gr.BaseStream.Position; swe.WriteLine("error position " + pos.ToString("X2")); swe.WriteLine("error while parsing UNIT values update block, count " + reallength); return(false); } for (uint index = 0; index < reallength; index++) { if (index > UpdateFields.UNIT_END) { break; } if (Mask[index]) { switch (UpdateFields.unit_updatefields[index].type) { case 1: string val1 = gr.ReadSingle().ToString().Replace(",", "."); if (updatetype == UpdateTypes.UPDATETYPE_CREATE_OBJECT || updatetype == UpdateTypes.UPDATETYPE_CREATE_OBJECT2) { data.WriteLine(UpdateFields.unit_updatefields[index].name + " (" + index + "): " + val1); } sb.AppendLine(UpdateFields.unit_updatefields[index].name + " (" + index + "): " + val1); break; default: uint val2 = gr.ReadUInt32(); if (updatetype == UpdateTypes.UPDATETYPE_CREATE_OBJECT || updatetype == UpdateTypes.UPDATETYPE_CREATE_OBJECT2) { data.WriteLine(UpdateFields.unit_updatefields[index].name + " (" + index + "): " + val2); } sb.AppendLine(UpdateFields.unit_updatefields[index].name + " (" + index + "): " + val2); break; } } } } // player values update block if (objectTypeId == ObjectTypes.TYPEID_PLAYER) { if (reallength > 1440) // 32*45 (for player bitmask = 45) { long pos = gr.BaseStream.Position; swe.WriteLine("error position " + pos.ToString("X2")); swe.WriteLine("error while parsing PLAYER values update block, count " + reallength); return(false); } for (uint index = 0; index < reallength; index++) { if (index > UpdateFields.PLAYER_END) { break; } if (Mask[index]) { switch (UpdateFields.unit_updatefields[index].type) { case 1: string val1 = gr.ReadSingle().ToString().Replace(",", "."); sb.AppendLine(UpdateFields.unit_updatefields[index].name + " (" + index + "): " + val1); break; default: uint val2 = gr.ReadUInt32(); sb.AppendLine(UpdateFields.unit_updatefields[index].name + " (" + index + "): " + val2); break; } } } } // gameobject values update block if (objectTypeId == ObjectTypes.TYPEID_GAMEOBJECT) { if (reallength > 32) // 1*32 { long pos = gr.BaseStream.Position; swe.WriteLine("error position " + pos.ToString("X2")); swe.WriteLine("error while parsing GO values update block, count " + reallength); return(false); } for (uint index = 0; index < reallength; index++) { if (index > UpdateFields.GO_END) { break; } if (Mask[index]) { switch (UpdateFields.go_updatefields[index].type) { case 1: string val1 = gr.ReadSingle().ToString().Replace(",", "."); if (updatetype == UpdateTypes.UPDATETYPE_CREATE_OBJECT || updatetype == UpdateTypes.UPDATETYPE_CREATE_OBJECT2) { data.WriteLine(UpdateFields.go_updatefields[index].name + " (" + index + "): " + val1); } sb.AppendLine(UpdateFields.go_updatefields[index].name + " (" + index + "): " + val1); break; default: uint val2 = gr.ReadUInt32(); if (updatetype == UpdateTypes.UPDATETYPE_CREATE_OBJECT || updatetype == UpdateTypes.UPDATETYPE_CREATE_OBJECT2) { data.WriteLine(UpdateFields.go_updatefields[index].name + " (" + index + "): " + val2); } sb.AppendLine(UpdateFields.go_updatefields[index].name + " (" + index + "): " + val2); break; } } } } // dynamicobject values update block if (objectTypeId == ObjectTypes.TYPEID_DYNAMICOBJECT) { if (reallength > 32) // 1*32 { long pos = gr.BaseStream.Position; swe.WriteLine("error position " + pos.ToString("X2")); swe.WriteLine("error while parsing DO values update block, count " + reallength); return(false); } for (uint index = 0; index < reallength; index++) { if (index > UpdateFields.DO_END) { break; } if (Mask[index]) { switch (UpdateFields.do_updatefields[index].type) { case 1: sb.AppendLine(UpdateFields.do_updatefields[index].name + " (" + index + "): " + gr.ReadSingle().ToString().Replace(",", ".")); break; default: sb.AppendLine(UpdateFields.do_updatefields[index].name + " (" + index + "): " + gr.ReadUInt32()); break; } } } } // corpse values update block if (objectTypeId == ObjectTypes.TYPEID_CORPSE) { if (reallength > 64) // 2*32 { long pos = gr.BaseStream.Position; swe.WriteLine("error position " + pos.ToString("X2")); swe.WriteLine("error while parsing CORPSE values update block, count " + reallength); return(false); } for (uint index = 0; index < reallength; index++) { if (index > UpdateFields.CORPSE_END) { break; } if (Mask[index]) { switch (UpdateFields.corpse_updatefields[index].type) { case 1: sb.AppendLine(UpdateFields.corpse_updatefields[index].name + " (" + index + "): " + gr.ReadSingle().ToString().Replace(",", ".")); break; default: sb.AppendLine(UpdateFields.corpse_updatefields[index].name + " (" + index + "): " + gr.ReadUInt32()); break; } } } } //swe.WriteLine("ok..."); sb.AppendLine("=== values_update_block_end ==="); return(true); }
/// <summary> /// Serves as a hash function. /// </summary> /// <returns>A hash code for the current bits.</returns> /// <remarks>Hash code depends on array length too.</remarks> public override Int32 GetHashCode() { int ret = base.GetHashCode(); ret ^= size ^ ((~size)<<16); if (words != null) for (int i=0; i<words.Length; i++) ret ^= words[i].GetHashCode(); return ret; }
/// <summary> /// Bitwise Or. /// </summary> /// <param name="a">First bits array.</param> /// <param name="b">Second bits array.</param> /// <returns>a bitwise or b</returns> public static BitArr operator |(BitArr a, BitArr b) { if (a == null && b==null) return null; else if (a == null) return (BitArr)b.Clone(); else if (b == null) return (BitArr)a.Clone(); int rla = a.RealLength; int rlb = b.RealLength; int rlc = Math.Max(rla, rlb); int wla = BS2WS(rla); int wlb = BS2WS(rlb); int wlc = BS2WS(rlc); BitArr c = new BitArr(rlc); for (int i=0; i<wlc; i++) if (i > wla) c.words[i] = b.words[i]; else if (i > wlb) c.words[i] = a.words[i]; else c.words[i] = a.words[i] | b.words[i]; return c; }
private bool ParseValuesUpdateBlock(GenericReader gr, StringBuilder sb, StreamWriter swe, StreamWriter data, ObjectTypes objectTypeId, UpdateTypes updatetype) { // may be we can reduce size of code there... sb.AppendLine("=== values_update_block_start ==="); byte blocks_count = gr.ReadByte(); // count of update blocks (4 bytes for each update block) sb.AppendLine("Bit mask blocks count: " + blocks_count); uint[] updatemask = new uint[blocks_count]; // create array of update blocks for (int j = 0; j < blocks_count; j++) updatemask[j] = gr.ReadUInt32(); // populate array of update blocks with data Mask = (BitArr)updatemask; // convert array of update blocks to bitmask array int reallength = Mask.RealLength; // bitmask size (bits) // item/container values update block if (objectTypeId == ObjectTypes.TYPEID_ITEM || objectTypeId == ObjectTypes.TYPEID_CONTAINER) { if (reallength > 160) // 5*32, ?? { long pos = gr.BaseStream.Position; swe.WriteLine("error position " + pos.ToString("X2")); swe.WriteLine("error while parsing ITEM values update block, count " + reallength); return false; } for (uint index = 0; index < reallength; index++) { if (index > UpdateFields.ITEM_END) break; if (Mask[index]) { switch (UpdateFields.item_updatefields[index].type) { case 1: sb.AppendLine(UpdateFields.item_updatefields[index].name + " (" + index + "): " + gr.ReadSingle().ToString().Replace(",", ".")); break; default: sb.AppendLine(UpdateFields.item_updatefields[index].name + " (" + index + "): " + gr.ReadUInt32()); break; } } } } // unit values update block if (objectTypeId == ObjectTypes.TYPEID_UNIT) { if (reallength > 256) // 32*8 (for units bitmask = 8) { long pos = gr.BaseStream.Position; swe.WriteLine("error position " + pos.ToString("X2")); swe.WriteLine("error while parsing UNIT values update block, count " + reallength); return false; } for (uint index = 0; index < reallength; index++) { if (index > UpdateFields.UNIT_END) break; if (Mask[index]) { switch (UpdateFields.unit_updatefields[index].type) { case 1: string val1 = gr.ReadSingle().ToString().Replace(",", "."); if(updatetype == UpdateTypes.UPDATETYPE_CREATE_OBJECT || updatetype == UpdateTypes.UPDATETYPE_CREATE_OBJECT2) data.WriteLine(UpdateFields.unit_updatefields[index].name + " (" + index + "): " + val1); sb.AppendLine(UpdateFields.unit_updatefields[index].name + " (" + index + "): " + val1); break; default: uint val2 = gr.ReadUInt32(); if (updatetype == UpdateTypes.UPDATETYPE_CREATE_OBJECT || updatetype == UpdateTypes.UPDATETYPE_CREATE_OBJECT2) data.WriteLine(UpdateFields.unit_updatefields[index].name + " (" + index + "): " + val2); sb.AppendLine(UpdateFields.unit_updatefields[index].name + " (" + index + "): " + val2); break; } } } } // player values update block if (objectTypeId == ObjectTypes.TYPEID_PLAYER) { if (reallength > 1440) // 32*45 (for player bitmask = 45) { long pos = gr.BaseStream.Position; swe.WriteLine("error position " + pos.ToString("X2")); swe.WriteLine("error while parsing PLAYER values update block, count " + reallength); return false; } for (uint index = 0; index < reallength; index++) { if (index > UpdateFields.PLAYER_END) break; if (Mask[index]) { switch (UpdateFields.unit_updatefields[index].type) { case 1: string val1 = gr.ReadSingle().ToString().Replace(",", "."); sb.AppendLine(UpdateFields.unit_updatefields[index].name + " (" + index + "): " + val1); break; default: uint val2 = gr.ReadUInt32(); sb.AppendLine(UpdateFields.unit_updatefields[index].name + " (" + index + "): " + val2); break; } } } } // gameobject values update block if (objectTypeId == ObjectTypes.TYPEID_GAMEOBJECT) { if (reallength > 32) // 1*32 { long pos = gr.BaseStream.Position; swe.WriteLine("error position " + pos.ToString("X2")); swe.WriteLine("error while parsing GO values update block, count " + reallength); return false; } for (uint index = 0; index < reallength; index++) { if (index > UpdateFields.GO_END) break; if (Mask[index]) { switch (UpdateFields.go_updatefields[index].type) { case 1: string val1 = gr.ReadSingle().ToString().Replace(",", "."); if (updatetype == UpdateTypes.UPDATETYPE_CREATE_OBJECT || updatetype == UpdateTypes.UPDATETYPE_CREATE_OBJECT2) data.WriteLine(UpdateFields.go_updatefields[index].name + " (" + index + "): " + val1); sb.AppendLine(UpdateFields.go_updatefields[index].name + " (" + index + "): " + val1); break; default: uint val2 = gr.ReadUInt32(); if (updatetype == UpdateTypes.UPDATETYPE_CREATE_OBJECT || updatetype == UpdateTypes.UPDATETYPE_CREATE_OBJECT2) data.WriteLine(UpdateFields.go_updatefields[index].name + " (" + index + "): " + val2); sb.AppendLine(UpdateFields.go_updatefields[index].name + " (" + index + "): " + val2); break; } } } } // dynamicobject values update block if (objectTypeId == ObjectTypes.TYPEID_DYNAMICOBJECT) { if (reallength > 32) // 1*32 { long pos = gr.BaseStream.Position; swe.WriteLine("error position " + pos.ToString("X2")); swe.WriteLine("error while parsing DO values update block, count " + reallength); return false; } for (uint index = 0; index < reallength; index++) { if (index > UpdateFields.DO_END) break; if (Mask[index]) { switch (UpdateFields.do_updatefields[index].type) { case 1: sb.AppendLine(UpdateFields.do_updatefields[index].name + " (" + index + "): " + gr.ReadSingle().ToString().Replace(",", ".")); break; default: sb.AppendLine(UpdateFields.do_updatefields[index].name + " (" + index + "): " + gr.ReadUInt32()); break; } } } } // corpse values update block if (objectTypeId == ObjectTypes.TYPEID_CORPSE) { if (reallength > 64) // 2*32 { long pos = gr.BaseStream.Position; swe.WriteLine("error position " + pos.ToString("X2")); swe.WriteLine("error while parsing CORPSE values update block, count " + reallength); return false; } for (uint index = 0; index < reallength; index++) { if (index > UpdateFields.CORPSE_END) break; if (Mask[index]) { switch (UpdateFields.corpse_updatefields[index].type) { case 1: sb.AppendLine(UpdateFields.corpse_updatefields[index].name + " (" + index + "): " + gr.ReadSingle().ToString().Replace(",", ".")); break; default: sb.AppendLine(UpdateFields.corpse_updatefields[index].name + " (" + index + "): " + gr.ReadUInt32()); break; } } } } //swe.WriteLine("ok..."); sb.AppendLine("=== values_update_block_end ==="); return true; }