From d125ca1665a95bb15718abdad3bce148070bbede Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Wed, 8 Sep 2021 20:56:32 +0100 Subject: [PATCH 001/149] cosmetics --- OpenMetaverse/Primitives/TextureEntry.cs | 185 +++++++++++++---------- OpenMetaverseTypes/Quaternion.cs | 33 ++-- OpenMetaverseTypes/Vector3.cs | 83 +++++----- OpenMetaverseTypes/Vector3d.cs | 12 +- 4 files changed, 169 insertions(+), 144 deletions(-) diff --git a/OpenMetaverse/Primitives/TextureEntry.cs b/OpenMetaverse/Primitives/TextureEntry.cs index 56af9d0f..ef741981 100644 --- a/OpenMetaverse/Primitives/TextureEntry.cs +++ b/OpenMetaverse/Primitives/TextureEntry.cs @@ -1147,6 +1147,7 @@ public byte[] GetBytes(int maxfaces = MAX_FACES) ulong next = 0; ulong nulls = 0; + TextureEntryFace curFace; int last = FaceTextures.Length - 1; if(last > maxfaces - 1) last = maxfaces - 1; @@ -1158,7 +1159,8 @@ public byte[] GetBytes(int maxfaces = MAX_FACES) for (int i = last; i >= 0; --i) { cur = (1UL << i); - if (FaceTextures[i] == null) + curFace = FaceTextures[i]; + if (curFace == null) { nulls |= cur; continue; @@ -1173,10 +1175,10 @@ public byte[] GetBytes(int maxfaces = MAX_FACES) if ((done & cur) != 0) continue; - if ((FaceTextures[i].m_attributes & TextureAttributes.TextureID) == 0) + if ((curFace.m_attributes & TextureAttributes.TextureID) == 0) continue; - UUID id = FaceTextures[i].TextureID; + UUID id = curFace.TextureID; if (id == DefaultTexture.m_textureID) continue; @@ -1186,17 +1188,18 @@ public byte[] GetBytes(int maxfaces = MAX_FACES) if ((done & next) != 0) continue; - if (FaceTextures[j] == null) + curFace = FaceTextures[j]; + if (curFace == null) { nulls |= next; done |= next; continue; } - if ((FaceTextures[j].m_attributes & TextureAttributes.TextureID) == 0) + if ((curFace.m_attributes & TextureAttributes.TextureID) == 0) continue; - if (FaceTextures[j].m_textureID != id) + if (curFace.m_textureID != id) continue; done |= next; @@ -1221,10 +1224,11 @@ public byte[] GetBytes(int maxfaces = MAX_FACES) if ((done & cur) != 0) continue; - if ((FaceTextures[i].m_attributes & TextureAttributes.RGBA) == 0) + curFace = FaceTextures[i]; + if ((curFace.m_attributes & TextureAttributes.RGBA) == 0) continue; - Color4 c = FaceTextures[i].m_rgba; + Color4 c = curFace.m_rgba; if (c == DefaultTexture.m_rgba) continue; @@ -1234,10 +1238,11 @@ public byte[] GetBytes(int maxfaces = MAX_FACES) if ((done & next) != 0) continue; - if ((FaceTextures[j].m_attributes & TextureAttributes.RGBA) == 0) + curFace = FaceTextures[j]; + if ((curFace.m_attributes & TextureAttributes.RGBA) == 0) continue; - if (FaceTextures[j].m_rgba != c) + if (curFace.m_rgba != c) continue; done |= next; @@ -1259,10 +1264,11 @@ public byte[] GetBytes(int maxfaces = MAX_FACES) if ((done & cur) != 0) continue; - if ((FaceTextures[i].m_attributes & TextureAttributes.RepeatU) == 0) + curFace = FaceTextures[i]; + if ((curFace.m_attributes & TextureAttributes.RepeatU) == 0) continue; - float repeat = FaceTextures[i].m_repeatU; + float repeat = curFace.m_repeatU; if (repeat == deff) continue; @@ -1272,10 +1278,11 @@ public byte[] GetBytes(int maxfaces = MAX_FACES) if ((done & next) != 0) continue; - if ((FaceTextures[j].m_attributes & TextureAttributes.RepeatU) == 0) + curFace = FaceTextures[j]; + if ((curFace.m_attributes & TextureAttributes.RepeatU) == 0) continue; - if (FaceTextures[j].m_repeatU != repeat) + if (curFace.m_repeatU != repeat) continue; done |= next; @@ -1297,10 +1304,11 @@ public byte[] GetBytes(int maxfaces = MAX_FACES) if ((done & cur) != 0) continue; - if ((FaceTextures[i].m_attributes & TextureAttributes.RepeatV) == 0) + curFace = FaceTextures[i]; + if ((curFace.m_attributes & TextureAttributes.RepeatV) == 0) continue; - float repeat = FaceTextures[i].m_repeatV; + float repeat = curFace.m_repeatV; if (repeat == deff) continue; @@ -1310,10 +1318,11 @@ public byte[] GetBytes(int maxfaces = MAX_FACES) if ((done & next) != 0) continue; - if ((FaceTextures[j].m_attributes & TextureAttributes.RepeatV) == 0) + curFace = FaceTextures[j]; + if ((curFace.m_attributes & TextureAttributes.RepeatV) == 0) continue; - if (FaceTextures[j].m_repeatV != repeat) + if (curFace.m_repeatV != repeat) continue; done |= next; @@ -1336,10 +1345,11 @@ public byte[] GetBytes(int maxfaces = MAX_FACES) if ((done & cur) != 0) continue; - if ((FaceTextures[i].m_attributes & TextureAttributes.OffsetU) == 0) + curFace = FaceTextures[i]; + if ((curFace.m_attributes & TextureAttributes.OffsetU) == 0) continue; - short offset = FaceTextures[i].m_offsetU; + short offset = curFace.m_offsetU; if (offset == def) continue; @@ -1349,10 +1359,11 @@ public byte[] GetBytes(int maxfaces = MAX_FACES) if ((done & next) != 0) continue; - if ((FaceTextures[j].m_attributes & TextureAttributes.OffsetU) == 0) + curFace = FaceTextures[j]; + if ((curFace.m_attributes & TextureAttributes.OffsetU) == 0) continue; - if (FaceTextures[j].m_offsetU != offset) + if (curFace.m_offsetU != offset) continue; done |= next; @@ -1374,10 +1385,11 @@ public byte[] GetBytes(int maxfaces = MAX_FACES) if ((done & cur) != 0) continue; - if ((FaceTextures[i].m_attributes & TextureAttributes.OffsetV) == 0) + curFace = FaceTextures[i]; + if ((curFace.m_attributes & TextureAttributes.OffsetV) == 0) continue; - short offset = FaceTextures[i].m_offsetV; + short offset = curFace.m_offsetV; if (offset == def) continue; @@ -1387,10 +1399,11 @@ public byte[] GetBytes(int maxfaces = MAX_FACES) if ((done & next) != 0) continue; - if ((FaceTextures[j].m_attributes & TextureAttributes.OffsetV) == 0) + curFace = FaceTextures[j]; + if ((curFace.m_attributes & TextureAttributes.OffsetV) == 0) continue; - if (FaceTextures[j].m_offsetV != offset) + if (curFace.m_offsetV != offset) continue; done |= next; @@ -1412,10 +1425,11 @@ public byte[] GetBytes(int maxfaces = MAX_FACES) if ((done & cur) != 0) continue; - if ((FaceTextures[i].m_attributes & TextureAttributes.Rotation) == 0) + curFace = FaceTextures[i]; + if ((curFace.m_attributes & TextureAttributes.Rotation) == 0) continue; - short rotation = FaceTextures[i].m_rotation; + short rotation = curFace.m_rotation; if (rotation == def) continue; @@ -1425,10 +1439,11 @@ public byte[] GetBytes(int maxfaces = MAX_FACES) if ((done & next) != 0) continue; - if ((FaceTextures[j].m_attributes & TextureAttributes.Rotation) == 0) + curFace = FaceTextures[j]; + if ((curFace.m_attributes & TextureAttributes.Rotation) == 0) continue; - if (FaceTextures[j].m_rotation != rotation) + if (curFace.m_rotation != rotation) continue; done |= next; @@ -1449,10 +1464,11 @@ public byte[] GetBytes(int maxfaces = MAX_FACES) if ((done & cur) != 0) continue; - if ((FaceTextures[i].m_attributes & TextureAttributes.Material) == 0) + curFace = FaceTextures[i]; + if ((curFace.m_attributes & TextureAttributes.Material) == 0) continue; - byte material = FaceTextures[i].m_material; + byte material = curFace.m_material; if (material == DefaultTexture.m_material) continue; @@ -1462,10 +1478,11 @@ public byte[] GetBytes(int maxfaces = MAX_FACES) if ((done & next) != 0) continue; - if ((FaceTextures[j].m_attributes & TextureAttributes.Material) == 0) + curFace = FaceTextures[j]; + if ((curFace.m_attributes & TextureAttributes.Material) == 0) continue; - if (FaceTextures[j].m_material != material) + if (curFace.m_material != material) continue; done |= next; @@ -1486,10 +1503,11 @@ public byte[] GetBytes(int maxfaces = MAX_FACES) if ((done & cur) != 0) continue; - if ((FaceTextures[i].m_attributes & TextureAttributes.Media) == 0) + curFace = FaceTextures[i]; + if ((curFace.m_attributes & TextureAttributes.Media) == 0) continue; - byte media = FaceTextures[i].m_media; + byte media = curFace.m_media; if (media == DefaultTexture.m_media) continue; @@ -1499,10 +1517,11 @@ public byte[] GetBytes(int maxfaces = MAX_FACES) if ((done & next) != 0) continue; - if ((FaceTextures[j].m_attributes & TextureAttributes.Media) == 0) + curFace = FaceTextures[j]; + if ((curFace.m_attributes & TextureAttributes.Media) == 0) continue; - if (FaceTextures[j].m_media != media) + if (curFace.m_media != media) continue; done |= next; @@ -1524,10 +1543,11 @@ public byte[] GetBytes(int maxfaces = MAX_FACES) if ((done & cur) != 0) continue; - if ((FaceTextures[i].m_attributes & TextureAttributes.Glow) == 0) + curFace = FaceTextures[i]; + if ((curFace.m_attributes & TextureAttributes.Glow) == 0) continue; - byte glow = FaceTextures[i].m_glow; + byte glow = curFace.m_glow; if (glow == defg) continue; @@ -1537,10 +1557,11 @@ public byte[] GetBytes(int maxfaces = MAX_FACES) if ((done & next) != 0) continue; - if ((FaceTextures[j].m_attributes & TextureAttributes.Glow) == 0) + curFace = FaceTextures[j]; + if ((curFace.m_attributes & TextureAttributes.Glow) == 0) continue; - if (FaceTextures[j].m_glow != glow) + if (curFace.m_glow != glow) continue; done |= next; @@ -1561,11 +1582,12 @@ public byte[] GetBytes(int maxfaces = MAX_FACES) if ((done & cur) != 0) continue; - if ((FaceTextures[i].m_attributes & TextureAttributes.MaterialID) == 0) + curFace = FaceTextures[i]; + if ((curFace.m_attributes & TextureAttributes.MaterialID) == 0) continue; - UUID materialID = FaceTextures[i].m_materialID; - if (materialID == null || materialID == DefaultTexture.m_materialID) + UUID materialID = curFace.m_materialID; + if (materialID == DefaultTexture.m_materialID) continue; for (int j = i - 1; j >= 0; --j) @@ -1574,10 +1596,11 @@ public byte[] GetBytes(int maxfaces = MAX_FACES) if ((done & next) != 0) continue; - if ((FaceTextures[j].m_attributes & TextureAttributes.MaterialID) == 0) + curFace = FaceTextures[j]; + if ((curFace.m_attributes & TextureAttributes.MaterialID) == 0) continue; - if (FaceTextures[j].m_materialID != materialID) + if (curFace.m_materialID != materialID) continue; done |= next; @@ -1594,8 +1617,8 @@ public byte[] GetBytes(int maxfaces = MAX_FACES) } - private static List AllBakedIndexes = new List() { 44, 43, 42, 41, 40, 20, 19, 11, 10, 9, 8 }; - private static List LegacyBakedIndexes = new List() {20, 19, 11, 10, 9, 8 }; + private static int[] AllBakedIndexes = { 44, 43, 42, 41, 40, 20, 19, 11, 10, 9, 8 }; + private static int[] LegacyBakedIndexes = {20, 19, 11, 10, 9, 8 }; public byte[] GetBakesBytes(int maxfaces = MAX_FACES) { @@ -1605,12 +1628,9 @@ public byte[] GetBakesBytes(int maxfaces = MAX_FACES) if(maxfaces > FaceTextures.Length) maxfaces = FaceTextures.Length; - List bakedIndexes; - if(maxfaces > 21) - bakedIndexes = AllBakedIndexes; - else - bakedIndexes = LegacyBakedIndexes; + int[] bakedIndexes = (maxfaces > 21) ? AllBakedIndexes : LegacyBakedIndexes; + TextureEntryFace curFace; using (MemoryStream ms = new MemoryStream(4096)) { #region Texture @@ -1618,10 +1638,11 @@ public byte[] GetBakesBytes(int maxfaces = MAX_FACES) ms.Write(defText.GetBytes(), 0, 16); foreach (int i in bakedIndexes) { - if (FaceTextures[i] == null) + curFace = FaceTextures[i]; + if (curFace == null) continue; - UUID id = FaceTextures[i].TextureID; + UUID id = curFace.TextureID; if (id == defText) continue; @@ -1636,10 +1657,11 @@ public byte[] GetBakesBytes(int maxfaces = MAX_FACES) ms.Write(DefaultTexture.RGBA.GetBytes(true), 0, 4); foreach (int i in bakedIndexes) { - if (FaceTextures[i] == null) + curFace = FaceTextures[i]; + if (curFace == null) continue; - Color4 c = FaceTextures[i].RGBA; + Color4 c = curFace.RGBA; if (c == DefaultTexture.RGBA) continue; @@ -1654,10 +1676,11 @@ public byte[] GetBakesBytes(int maxfaces = MAX_FACES) Utils.FloatToBytes(ms, deff); foreach (int i in bakedIndexes) { - if (FaceTextures[i] == null) + curFace = FaceTextures[i]; + if (curFace == null) continue; - float repeat = FaceTextures[i].RepeatU; + float repeat = curFace.RepeatU; if (repeat == deff) continue; @@ -1672,10 +1695,11 @@ public byte[] GetBakesBytes(int maxfaces = MAX_FACES) Utils.FloatToBytes(ms, deff); foreach (int i in bakedIndexes) { - if (FaceTextures[i] == null) + curFace = FaceTextures[i]; + if (curFace == null) continue; - float repeat = FaceTextures[i].RepeatV; + float repeat = curFace.RepeatV; if (repeat == deff) continue; @@ -1691,10 +1715,11 @@ public byte[] GetBakesBytes(int maxfaces = MAX_FACES) Utils.Int16ToBytes(ms, def); foreach (int i in bakedIndexes) { - if (FaceTextures[i] == null) + curFace = FaceTextures[i]; + if (curFace == null) continue; - short offset = FaceTextures[i].m_offsetU; + short offset = curFace.m_offsetU; if (offset == def) continue; @@ -1709,10 +1734,11 @@ public byte[] GetBakesBytes(int maxfaces = MAX_FACES) Utils.Int16ToBytes(ms, def); foreach (int i in bakedIndexes) { - if (FaceTextures[i] == null) + curFace = FaceTextures[i]; + if (curFace == null) continue; - short offset = FaceTextures[i].m_offsetV; + short offset = curFace.m_offsetV; if (offset == def) continue; @@ -1727,10 +1753,11 @@ public byte[] GetBakesBytes(int maxfaces = MAX_FACES) Utils.Int16ToBytes(ms, def); foreach (int i in bakedIndexes) { - if (FaceTextures[i] == null) + curFace = FaceTextures[i]; + if (curFace == null) continue; - short rotation = FaceTextures[i].m_rotation; + short rotation = curFace.m_rotation; if (rotation == def) continue; @@ -1744,10 +1771,11 @@ public byte[] GetBakesBytes(int maxfaces = MAX_FACES) ms.WriteByte(DefaultTexture.m_material); foreach (int i in bakedIndexes) { - if (FaceTextures[i] == null) + curFace = FaceTextures[i]; + if (curFace == null) continue; - byte material = FaceTextures[i].m_material; + byte material = curFace.m_material; if (material == DefaultTexture.m_material) continue; @@ -1761,10 +1789,11 @@ public byte[] GetBakesBytes(int maxfaces = MAX_FACES) ms.WriteByte(DefaultTexture.m_media); foreach (int i in bakedIndexes) { - if (FaceTextures[i] == null) + curFace = FaceTextures[i]; + if (curFace == null) continue; - byte media = FaceTextures[i].m_media; + byte media = curFace.m_media; if (media == DefaultTexture.m_media) continue; @@ -1779,10 +1808,11 @@ public byte[] GetBakesBytes(int maxfaces = MAX_FACES) ms.WriteByte(defg); foreach (int i in bakedIndexes) { - if (FaceTextures[i] == null) + curFace = FaceTextures[i]; + if (curFace == null) continue; - byte glow = FaceTextures[i].m_glow; + byte glow = curFace.m_glow; if (glow == defg) continue; @@ -1796,11 +1826,12 @@ public byte[] GetBakesBytes(int maxfaces = MAX_FACES) ms.Write(DefaultTexture.m_materialID.GetBytes(), 0, 16); foreach (int i in bakedIndexes) { - if (FaceTextures[i] == null) + curFace = FaceTextures[i]; + if (curFace == null) continue; - UUID materialID = FaceTextures[i].m_materialID; - if (materialID == null || materialID == DefaultTexture.m_materialID) + UUID materialID = curFace.m_materialID; + if (materialID == DefaultTexture.m_materialID) continue; WriteFaceBitfieldBytes(ms, (1UL << i)); diff --git a/OpenMetaverseTypes/Quaternion.cs b/OpenMetaverseTypes/Quaternion.cs index 94e9bf92..4ed9808c 100644 --- a/OpenMetaverseTypes/Quaternion.cs +++ b/OpenMetaverseTypes/Quaternion.cs @@ -25,6 +25,7 @@ */ using System; +using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Globalization; @@ -103,7 +104,7 @@ public Quaternion(Quaternion q) #endregion Constructors #region Public Methods - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool ApproxEquals(Quaternion quat) { // assume normalized @@ -112,7 +113,7 @@ public bool ApproxEquals(Quaternion quat) Math.Abs(quat.Z - Z) < 1e-6f; } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool ApproxEquals(Quaternion quat, float tolerance) { // assume normalized @@ -121,13 +122,13 @@ public bool ApproxEquals(Quaternion quat, float tolerance) Math.Abs(quat.Z - Z) < tolerance; } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public float Length() { return (float)Math.Sqrt((X * X) + (Y * Y) + (Z * Z) + (W * W)); } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public float LengthSquared() { return (X * X) + (Y * Y) + (Z * Z) + (W * W); @@ -136,7 +137,7 @@ public float LengthSquared() /// /// Normalizes the quaternion /// - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Normalize() { float mag = LengthSquared(); @@ -157,7 +158,7 @@ public void Normalize() } } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Conjugate() { X = -X; @@ -165,7 +166,7 @@ public void Conjugate() Z = -Z; } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Invert() { float len = LengthSquared(); @@ -352,7 +353,7 @@ public void GetAxisAngle(out Vector3 axis, out float angle) #region Static Methods - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Quaternion Add(Quaternion quaternion1, Quaternion quaternion2) { return new Quaternion( @@ -365,7 +366,7 @@ public static Quaternion Add(Quaternion quaternion1, Quaternion quaternion2) /// /// Returns the conjugate (spatial inverse) of a quaternion /// - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Quaternion Conjugate(Quaternion quaternion) { return new Quaternion( -quaternion.X, -quaternion.Y, -quaternion.Z, quaternion.W); @@ -487,13 +488,13 @@ public static Quaternion CreateFromRotationMatrix(Matrix4 matrix) (matrix.M12 - matrix.M21) * num2); } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Quaternion Divide(Quaternion q1, Quaternion q2) { return Quaternion.Inverse(q1) * q2; } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static float Dot(Quaternion q1, Quaternion q2) { return (q1.X * q2.X) + (q1.Y * q2.Y) + (q1.Z * q2.Z) + (q1.W * q2.W); @@ -502,7 +503,7 @@ public static float Dot(Quaternion q1, Quaternion q2) /// /// inverse of a quaternion /// - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Quaternion Inverse(Quaternion quaternion) { float normsq = quaternion.LengthSquared(); @@ -570,7 +571,7 @@ public static Quaternion Slerp(Quaternion q1, Quaternion q2, float amount) ); } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Quaternion Subtract(Quaternion quaternion1, Quaternion quaternion2) { return new Quaternion( @@ -590,7 +591,7 @@ public static Quaternion Multiply(Quaternion a, Quaternion b) ); } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Quaternion Multiply(Quaternion quaternion, float scaleFactor) { return new Quaternion( @@ -600,7 +601,7 @@ public static Quaternion Multiply(Quaternion quaternion, float scaleFactor) quaternion.W * scaleFactor); } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Quaternion Negate(Quaternion quaternion) { return new Quaternion( @@ -610,7 +611,7 @@ public static Quaternion Negate(Quaternion quaternion) -quaternion.W); } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Quaternion Normalize(Quaternion q) { float mag = q.LengthSquared(); diff --git a/OpenMetaverseTypes/Vector3.cs b/OpenMetaverseTypes/Vector3.cs index 94680831..7325408e 100644 --- a/OpenMetaverseTypes/Vector3.cs +++ b/OpenMetaverseTypes/Vector3.cs @@ -25,6 +25,7 @@ */ using System; +using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Globalization; @@ -95,7 +96,7 @@ public Vector3(Vector3 vector) #endregion Constructors #region Public Methods - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Abs() { if (X < 0) @@ -106,7 +107,7 @@ public void Abs() Z = -Z; } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Min(Vector3 v) { if (v.X < X) X = v.X; @@ -114,7 +115,7 @@ public void Min(Vector3 v) if (v.Z < Z) Z = v.Z; } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Max(Vector3 v) { if (v.X > X) X = v.X; @@ -122,19 +123,19 @@ public void Max(Vector3 v) if (v.Z > Z) Z = v.Z; } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public float Length() { return (float)Math.Sqrt((X * X) + (Y * Y) + (Z * Z)); } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public float LengthSquared() { return (X * X) + (Y * Y) + (Z * Z); } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Normalize() { float factor = LengthSquared(); @@ -153,7 +154,7 @@ public void Normalize() } } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool ApproxEquals(Vector3 vec) { return Utils.ApproxEqual(X, vec.X) && @@ -170,7 +171,7 @@ public bool ApproxEquals(Vector3 vec) /// between the two vectors /// True if the magnitude of difference between the two vectors /// is less than the given tolerance, otherwise false - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool ApproxEquals(Vector3 vec, float tolerance) { return Utils.ApproxEqual(X, vec.X, tolerance) && @@ -181,7 +182,7 @@ public bool ApproxEquals(Vector3 vec, float tolerance) /// /// IComparable.CompareTo implementation /// - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public int CompareTo(Vector3 vector) { return LengthSquared().CompareTo(vector.LengthSquared()); @@ -190,7 +191,7 @@ public int CompareTo(Vector3 vector) /// /// Test if this vector is composed of all finite numbers /// - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool IsFinite() { return (Utils.IsFinite(X) && Utils.IsFinite(Y) && Utils.IsFinite(Z)); @@ -201,7 +202,7 @@ public bool IsFinite() /// /// Byte array containing a 12 byte vector /// Beginning position in the byte array - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void FromBytes(byte[] byteArray, int pos) { X = Utils.BytesToFloatSafepos(byteArray, pos); @@ -213,7 +214,7 @@ public void FromBytes(byte[] byteArray, int pos) /// Returns the raw bytes for this vector /// /// A 12 byte array containing X, Y, and Z - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public byte[] GetBytes() { byte[] dest = new byte[12]; @@ -229,7 +230,7 @@ public byte[] GetBytes() /// Destination byte array /// Position in the destination array to start /// writing. Must be at least 12 bytes before the end of the array - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ToBytes(byte[] dest, int pos) { Utils.FloatToBytesSafepos(X, dest, pos); @@ -240,13 +241,13 @@ public void ToBytes(byte[] dest, int pos) #endregion Public Methods #region Static Methods - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 Add(Vector3 value1, Vector3 value2) { return new Vector3(value1.X + value2.X, value1.Y + value2.Y, value1.Z + value2.Z); } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 Clamp(Vector3 value1, Vector3 min, Vector3 max) { return new Vector3( @@ -255,7 +256,7 @@ public static Vector3 Clamp(Vector3 value1, Vector3 min, Vector3 max) Utils.Clamp(value1.Z, min.Z, max.Z)); } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 Cross(Vector3 value1, Vector3 value2) { return new Vector3( @@ -269,7 +270,7 @@ public static float Distance(Vector3 value1, Vector3 value2) return (float)Math.Sqrt(DistanceSquared(value1, value2)); } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static float DistanceSquared(Vector3 value1, Vector3 value2) { float x = value1.X - value2.X; @@ -282,20 +283,20 @@ public static float DistanceSquared(Vector3 value1, Vector3 value2) return (x + z * z); } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 Divide(Vector3 value1, Vector3 value2) { return new Vector3(value1.X / value2.X, value1.Y / value2.Y, value1.Z / value2.Z); } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 Divide(Vector3 value1, float value2) { float factor = 1f / value2; return new Vector3(value1.X * factor, value1.Y * factor, value1.Z * factor); } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static float Dot(Vector3 value1, Vector3 value2) { return (value1.X * value2.X) + (value1.Y * value2.Y) + (value1.Z * value2.Z); @@ -309,13 +310,13 @@ public static Vector3 Lerp(Vector3 value1, Vector3 value2, float amount) Utils.Lerp(value1.Z, value2.Z, amount)); } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static float Mag(Vector3 value) { return value.Length(); } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 Max(Vector3 value1, Vector3 value2) { return new Vector3( @@ -324,7 +325,7 @@ public static Vector3 Max(Vector3 value1, Vector3 value2) Math.Max(value1.Z, value2.Z)); } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 Min(Vector3 value1, Vector3 value2) { return new Vector3( @@ -333,32 +334,32 @@ public static Vector3 Min(Vector3 value1, Vector3 value2) Math.Min(value1.Z, value2.Z)); } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 Multiply(Vector3 value1, Vector3 value2) { return new Vector3(value1.X * value2.X, value1.Y * value2.Y, value1.Z * value2.Z); } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 Multiply(Vector3 value1, float scaleFactor) { return new Vector3(value1.X * scaleFactor, value1.Y * scaleFactor, value1.Z * scaleFactor); } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 Negate(Vector3 value) { return new Vector3(-value.X, -value.Y, -value.Z); } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 Normalize(Vector3 value) { float factor = value.LengthSquared(); if (factor > 1e-6f) { factor = 1f / (float)Math.Sqrt(factor); - return new Vector3(value.X *= factor, value.Y *= factor, value.Z *= factor); + return new Vector3(value.X * factor, value.Y * factor, value.Z * factor); } return Vector3.Zero; } @@ -427,7 +428,7 @@ public static Quaternion RotationBetween(Vector3 a, Vector3 b) /// /// Interpolates between two vectors using a cubic equation /// - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 SmoothStep(Vector3 value1, Vector3 value2, float amount) { return new Vector3( @@ -436,7 +437,7 @@ public static Vector3 SmoothStep(Vector3 value1, Vector3 value2, float amount) Utils.SmoothStep(value1.Z, value2.Z, amount)); } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 Subtract(Vector3 value1, Vector3 value2) { return new Vector3(value1.X - value2.X, value1.Y - value2.Y, value1.Z - value2.Z); @@ -458,7 +459,7 @@ public static Vector3 TransformNormal(Vector3 position, Matrix4 matrix) (position.X * matrix.M13) + (position.Y * matrix.M23) + (position.Z * matrix.M33)); } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 Transform(Vector3 vec, Quaternion rot) { float x2 = rot.X + rot.X; @@ -499,7 +500,7 @@ public bool Equals(Vector3 other) return this == other; } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public override int GetHashCode() { int hash = X.GetHashCode(); @@ -546,37 +547,37 @@ public string ToRawString() return !(value1 == value2); } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 operator +(Vector3 value1, Vector3 value2) { return new Vector3(value1.X + value2.X, value1.Y + value2.Y, value1.Z + value2.Z); } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 operator -(Vector3 value) { return new Vector3(-value.X , -value.Y, -value.Z); } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 operator -(Vector3 value1, Vector3 value2) { return new Vector3(value1.X - value2.X, value1.Y - value2.Y, value1.Z - value2.Z); } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 operator *(Vector3 value1, Vector3 value2) { return new Vector3(value1.X * value2.X, value1.Y * value2.Y, value1.Z * value2.Z); } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 operator *(Vector3 value, float scaleFactor) { return new Vector3(value.X * scaleFactor, value.Y * scaleFactor, value.Z * scaleFactor); } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 operator *(Vector3 vec, Quaternion rot) { float x2 = rot.X + rot.X; @@ -604,19 +605,19 @@ public string ToRawString() } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 operator *(Vector3 vector, Matrix4 matrix) { return Transform(vector, matrix); } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 operator /(Vector3 value1, Vector3 value2) { return new Vector3(value1.X / value2.X, value1.Y / value2.Y, value1.Z / value2.Z); } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 operator /(Vector3 value, float divider) { float factor = 1f / divider; diff --git a/OpenMetaverseTypes/Vector3d.cs b/OpenMetaverseTypes/Vector3d.cs index d5209d5c..f8a588bd 100644 --- a/OpenMetaverseTypes/Vector3d.cs +++ b/OpenMetaverseTypes/Vector3d.cs @@ -290,17 +290,9 @@ public static Vector3d Normalize(Vector3d value) if (factor > Double.Epsilon) { factor = 1d / factor; - value.X *= factor; - value.Y *= factor; - value.Z *= factor; + return new Vector3d(value.X * factor, value.Y * factor, value.Z * factor); } - else - { - value.X = 0d; - value.Y = 0d; - value.Z = 0d; - } - return value; + return Vector3.Zero; } /// From 9b3348e799b5e139d806bb8d245a59015d059bd3 Mon Sep 17 00:00:00 2001 From: Sara Payne Date: Thu, 9 Sep 2021 16:26:39 +0100 Subject: [PATCH 002/149] Added .idea to gitignore (jetbrains settings files) --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 9a7f6e27..44a34837 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,5 @@ compile.bat [Bb]in/ PublishProfiles/ + +.idea/.idea.OpenMetaverse/.idea/ From e8186412304b5415adc146cb1dcd81301d22cb80 Mon Sep 17 00:00:00 2001 From: Sara Payne Date: Thu, 9 Sep 2021 16:44:11 +0100 Subject: [PATCH 003/149] Added replacement for Thread.Abort from LibreMetaverse Thread.Abort is obsolete in .net5 --- OpenMetaverse/Voice/VoiceControl.cs | 30 +++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/OpenMetaverse/Voice/VoiceControl.cs b/OpenMetaverse/Voice/VoiceControl.cs index a77bba10..8fbd0c0d 100644 --- a/OpenMetaverse/Voice/VoiceControl.cs +++ b/OpenMetaverse/Voice/VoiceControl.cs @@ -75,6 +75,7 @@ public enum ConnectionState // Position update thread private Thread posThread; + private CancellationTokenSource posTokenSource; //added based on LibreOpenMetaverse private ManualResetEvent posRestart; public GridClient Client; private VoicePosition position; @@ -128,8 +129,21 @@ public VoiceGateway(GridClient c) public void Start() { // Start the background thread - if (posThread != null && posThread.IsAlive) + + /* Removed as thread.abort is obsolte + * + * if (posThread != null && posThread.IsAlive) posThread.Abort(); + */ + + // Start the background thread (from libre OpenMetaverse) + if (posThread != null && posThread.IsAlive) + { + posRestart.Set(); + posTokenSource.Cancel(); + } + + posTokenSource = new CancellationTokenSource();//Added from LibreOpenMetaverse posThread = new Thread(new ThreadStart(PositionThreadBody)); posThread.Name = "VoicePositionUpdate"; posThread.IsBackground = true; @@ -250,8 +264,18 @@ public void Stop() { PosUpdating(false); - if (posThread.IsAlive) + /* Removed as thread.abort is obsolete + if (posThread.IsAlive) posThread.Abort(); + */ + + //Added From Libre OpenMetaverse + if (posThread.IsAlive) + { + posRestart.Set(); + posTokenSource.Cancel(); + } + posThread = null; } @@ -986,9 +1010,11 @@ internal void PosUpdating(bool go) private void PositionThreadBody() { + var token = posTokenSource.Token; //added from LibreOpenMetaverse while (true) { posRestart.WaitOne(); + token.ThrowIfCancellationRequested(); //added from LibreOpenMetaverse Thread.Sleep(1500); UpdatePosition(Client.Self); } From 7109e91f66017ff9a15f4031e7ce7c43c1d453f2 Mon Sep 17 00:00:00 2001 From: Sara Payne Date: Thu, 9 Sep 2021 16:51:03 +0100 Subject: [PATCH 004/149] Added Targeting for NetStandard 2.0 and 2.1 in OpenMetaverse, OpenMetaverse.StructuredData, OpenMetaverse.Types --- .../OpenMetaverse.StructuredData.csproj | 2 +- OpenMetaverse.Types/OpenMetaverse.Types.csproj | 2 +- OpenMetaverse/OpenMetaverse.csproj | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/OpenMetaverse.StructuredData/OpenMetaverse.StructuredData.csproj b/OpenMetaverse.StructuredData/OpenMetaverse.StructuredData.csproj index b2e908fa..2e540210 100644 --- a/OpenMetaverse.StructuredData/OpenMetaverse.StructuredData.csproj +++ b/OpenMetaverse.StructuredData/OpenMetaverse.StructuredData.csproj @@ -1,7 +1,7 @@  Local - net48 + net48;netstandard2.0;netstandard2.1 1591,1574,0419,0618 true true diff --git a/OpenMetaverse.Types/OpenMetaverse.Types.csproj b/OpenMetaverse.Types/OpenMetaverse.Types.csproj index 33162fff..9b44dbff 100644 --- a/OpenMetaverse.Types/OpenMetaverse.Types.csproj +++ b/OpenMetaverse.Types/OpenMetaverse.Types.csproj @@ -1,7 +1,7 @@  Local - net48 + net48;netstandard2.0;netstandard2.1 OpenMetaverse 1591,1574,0419,0618 True diff --git a/OpenMetaverse/OpenMetaverse.csproj b/OpenMetaverse/OpenMetaverse.csproj index c461f644..9c589a3f 100644 --- a/OpenMetaverse/OpenMetaverse.csproj +++ b/OpenMetaverse/OpenMetaverse.csproj @@ -1,7 +1,7 @@  Local - net48 + net48;netstandard2.0;netstandard2.1 OpenMetaverse 1591,1574,0419,0618 True From cca8a88ee7f656ffd497ea0d70071d7eda7f4048 Mon Sep 17 00:00:00 2001 From: Sara Payne Date: Thu, 9 Sep 2021 16:56:57 +0100 Subject: [PATCH 005/149] Added replacement for Thread.Abort from LibreMetaverse --- OpenMetaverse/AppearanceManager.cs | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/OpenMetaverse/AppearanceManager.cs b/OpenMetaverse/AppearanceManager.cs index f2c2fb18..ff613d09 100644 --- a/OpenMetaverse/AppearanceManager.cs +++ b/OpenMetaverse/AppearanceManager.cs @@ -403,6 +403,10 @@ public bool ManagerBusy /// private Thread AppearanceThread; /// + /// Main appearance cancellation token source + /// + private CancellationTokenSource CancellationTokenSource; //Added from LibreOpenMetaverse + /// /// Is server baking complete. It needs doing only once /// private bool ServerBakingDone = false; @@ -471,11 +475,14 @@ public void RequestSetAppearance(bool forceRebake) RebakeScheduleTimer.Dispose(); RebakeScheduleTimer = null; } + + CancellationTokenSource = new CancellationTokenSource(); //added from LibreOpenMetaverse // This is the first time setting appearance, run through the entire sequence AppearanceThread = new Thread( delegate () { + var cancellationToken = CancellationTokenSource.Token; //added from LibreOpenMetaverse bool success = true; try { @@ -2367,13 +2374,23 @@ private void Network_OnDisconnected(object sender, DisconnectedEventArgs e) RebakeScheduleTimer.Dispose(); RebakeScheduleTimer = null; } + + // Added from LibreOpenMetaverse + if (CancellationTokenSource != null) + { + CancellationTokenSource.Cancel(); + CancellationTokenSource.Dispose(); + CancellationTokenSource = null; + } if (AppearanceThread != null) { - if (AppearanceThread.IsAlive) + /* removed as thread.abort is obsolte + if (AppearanceThread.IsAlive) { AppearanceThread.Abort(); } + */ AppearanceThread = null; AppearanceThreadRunning = 0; } From 8c5e39a05fd45d56df0e089a5c5bb50286c4652e Mon Sep 17 00:00:00 2001 From: Sara Payne Date: Thu, 9 Sep 2021 16:58:58 +0100 Subject: [PATCH 006/149] Added replacement for Thread.Abort from LibreMeaverse --- OpenMetaverse/TexturePipeline.cs | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/OpenMetaverse/TexturePipeline.cs b/OpenMetaverse/TexturePipeline.cs index a5a9135b..8217db0d 100644 --- a/OpenMetaverse/TexturePipeline.cs +++ b/OpenMetaverse/TexturePipeline.cs @@ -95,6 +95,8 @@ private class TaskInfo public TextureRequestState State; /// The Unique Request ID, This is also the Asset ID of the texture being requested public UUID RequestID; + /// The cancellation token for the request. + public CancellationTokenSource TokenSource; //added from LibreOpenMetaverse /// The slot this request is occupying in the threadpoolSlots array public int RequestSlot; /// The ImageType of the request. @@ -131,6 +133,8 @@ private class TaskInfo private readonly int[] threadpoolSlots; /// The primary thread which manages the requests. private Thread downloadMaster; + /// The cancellation token for the TexturePipeline and all child tasks. + private CancellationTokenSource downloadTokenSource; //added from LibreOpenMetaverse /// true if the TexturePipeline is currently running bool _Running; /// A synchronization object used by the primary thread @@ -150,6 +154,8 @@ public TexturePipeline(GridClient client) _Client = client; maxTextureRequests = client.Settings.MAX_CONCURRENT_TEXTURE_DOWNLOADS; + + downloadTokenSource = new CancellationTokenSource();//Added from LibreOpenMetaverse resetEvents = new AutoResetEvent[maxTextureRequests]; threadpoolSlots = new int[maxTextureRequests]; @@ -219,10 +225,17 @@ public void Shutdown() if (null != RefreshDownloadsTimer) RefreshDownloadsTimer.Dispose(); RefreshDownloadsTimer = null; - if (downloadMaster != null && downloadMaster.IsAlive) + /* + if (downloadMaster != null && downloadMaster.IsAlive) { downloadMaster.Abort(); } + */ + + //Added from LibreOpenMetaverse + if (!downloadTokenSource.IsCancellationRequested) + downloadTokenSource.Cancel(); + downloadMaster = null; _Client.Network.UnregisterCallback(PacketType.ImageNotInDatabase, ImageNotInDatabaseHandler); @@ -314,6 +327,7 @@ public void RequestTexture(UUID textureID, ImageType imageType, float priority, } else { + //TokenSource added from LibreMetaverse lock (_Transfers) { TaskInfo request; @@ -328,6 +342,7 @@ public void RequestTexture(UUID textureID, ImageType imageType, float priority, request.State = TextureRequestState.Pending; request.RequestID = textureID; request.ReportProgress = progressive; + request.TokenSource = CancellationTokenSource.CreateLinkedTokenSource(downloadTokenSource.Token); request.RequestSlot = -1; request.Type = imageType; From 9d6388efcb16f00a2b8fade78aba732c9b3d2398 Mon Sep 17 00:00:00 2001 From: Sara Payne Date: Thu, 9 Sep 2021 17:03:16 +0100 Subject: [PATCH 007/149] removed targeting of netstandard 2.1 for now due to conflicts. --- .../OpenMetaverse.StructuredData.csproj | 2 +- OpenMetaverse.Types/OpenMetaverse.Types.csproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/OpenMetaverse.StructuredData/OpenMetaverse.StructuredData.csproj b/OpenMetaverse.StructuredData/OpenMetaverse.StructuredData.csproj index 2e540210..a811910d 100644 --- a/OpenMetaverse.StructuredData/OpenMetaverse.StructuredData.csproj +++ b/OpenMetaverse.StructuredData/OpenMetaverse.StructuredData.csproj @@ -1,7 +1,7 @@  Local - net48;netstandard2.0;netstandard2.1 + net48;netstandard2.0 1591,1574,0419,0618 true true diff --git a/OpenMetaverse.Types/OpenMetaverse.Types.csproj b/OpenMetaverse.Types/OpenMetaverse.Types.csproj index 9b44dbff..f93afd11 100644 --- a/OpenMetaverse.Types/OpenMetaverse.Types.csproj +++ b/OpenMetaverse.Types/OpenMetaverse.Types.csproj @@ -1,7 +1,7 @@  Local - net48;netstandard2.0;netstandard2.1 + net48;netstandard2.0 OpenMetaverse 1591,1574,0419,0618 True From 9523fcbed3b83943fb671aeb1a24398dac8c0568 Mon Sep 17 00:00:00 2001 From: Sara Payne Date: Thu, 9 Sep 2021 17:16:28 +0100 Subject: [PATCH 008/149] Added zero formatter package used in LibreMetaverse to replace binary formatter --- OpenMetaverse/OpenMetaverse.csproj | 1 + 1 file changed, 1 insertion(+) diff --git a/OpenMetaverse/OpenMetaverse.csproj b/OpenMetaverse/OpenMetaverse.csproj index 9c589a3f..5bc2d2f9 100644 --- a/OpenMetaverse/OpenMetaverse.csproj +++ b/OpenMetaverse/OpenMetaverse.csproj @@ -10,6 +10,7 @@ + From 297e782171d89a6edbaf0d151e00bb4bf33e107a Mon Sep 17 00:00:00 2001 From: Sara Payne Date: Thu, 9 Sep 2021 17:19:28 +0100 Subject: [PATCH 009/149] Added changes from LibreMetaverse to replace Binary Formatter --- OpenMetaverse/Inventory.cs | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/OpenMetaverse/Inventory.cs b/OpenMetaverse/Inventory.cs index 6bc6e01e..f4ed8dd5 100644 --- a/OpenMetaverse/Inventory.cs +++ b/OpenMetaverse/Inventory.cs @@ -363,7 +363,10 @@ public void SaveToDisk(string filename) Logger.Log("Caching " + Items.Count.ToString() + " inventory items to " + filename, Helpers.LogLevel.Info); foreach (KeyValuePair kvp in Items) { - bformatter.Serialize(stream, kvp.Value); + /* Removed as binary formatter is obsolete + bformatter.Serialize(stream, kvp.Value); + */ + ZeroFormatter.ZeroFormatterSerializer.Serialize(stream, kvp.Value); //added from LibreMetaverse } } } @@ -391,11 +394,15 @@ public int RestoreFromDisk(string filename) using (Stream stream = File.Open(filename, FileMode.Open)) { - BinaryFormatter bformatter = new BinaryFormatter(); + //BinaryFormatter bformatter = new BinaryFormatter(); //removed as part of binary formatter replacements while (stream.Position < stream.Length) { - OpenMetaverse.InventoryNode node = (InventoryNode)bformatter.Deserialize(stream); + /* Removed as binaryformatter is obsolte + OpenMetaverse.InventoryNode node = (InventoryNode)bformatter.Deserialize(stream); + */ + + var node = ZeroFormatter.ZeroFormatterSerializer.Deserialize(stream); //added from LibreOpenMetaverse nodes.Add(node); item_count++; } From 9eb6e242bfbce91711e89990e194d644c3a84335 Mon Sep 17 00:00:00 2001 From: mdicvkson Date: Thu, 9 Sep 2021 13:18:14 -0400 Subject: [PATCH 010/149] Make things build to a ./build directory. LF is default line ending. --- .gitattributes | 14 +++----------- .gitignore | 2 +- Directory.Build.props | 2 +- 3 files changed, 5 insertions(+), 13 deletions(-) diff --git a/.gitattributes b/.gitattributes index d0f0d3df..ded6cb71 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,17 +1,9 @@ # These files are text eol=lf and should be normalized (convert crlf => lf) -*.cs text eol=lf diff=csharp -*.xaml text eol=lf -*.csproj text eol=lf -*.sln text eol=lf -*.tt text eol=lf -*.ps1 text eol=lf -*.cmd text eol=lf -*.msbuild text eol=lf -*.md text eol=lf - +* text=auto eol=lf +*.{cmd,[cC][mM][dD]} text eol=crlf +*.{bat,[bB][aA][tT]} text eol=crlf # Images should be treated as binary # (binary is a macro for -text eol=lf -diff) *.png binary *.jepg binary - *.sdf binary diff --git a/.gitignore b/.gitignore index 9a7f6e27..e5d425f5 100644 --- a/.gitignore +++ b/.gitignore @@ -3,9 +3,9 @@ compile.bat *.userprefs *.suo *.cache - .vs/ [Oo]bj/ [Bb]in/ +[Bb]uild/ PublishProfiles/ diff --git a/Directory.Build.props b/Directory.Build.props index 1c8a703b..7d42142b 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -5,7 +5,7 @@ 1.1.6 $(SolutionDir)\obj\$(Configuration)\$(MSBuildProjectName)\ $(SolutionDir)\obj\$(Configuration)\$(MSBuildProjectName)\ - $(SolutionDir)\bin\$(Configuration)\$(AssemblyName)\ + $(SolutionDir)\build\$(Configuration)\$(AssemblyName)\ $(OutputPath) From 31112d74aa43dd52a049caab94ada3c5e999c277 Mon Sep 17 00:00:00 2001 From: Sara Payne Date: Thu, 9 Sep 2021 18:51:06 +0100 Subject: [PATCH 011/149] Replaced Binary Formatter with Zero Formatter in message tests since binary formatter is obsolete in .net5 --- OpenMetaverse.Tests/MessageTests.cs | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/OpenMetaverse.Tests/MessageTests.cs b/OpenMetaverse.Tests/MessageTests.cs index 87cda425..77cb9ba4 100644 --- a/OpenMetaverse.Tests/MessageTests.cs +++ b/OpenMetaverse.Tests/MessageTests.cs @@ -1169,7 +1169,7 @@ public void ReflectionPerformanceRemoteParcelResponse() TimeSpan duration = DateTime.UtcNow - messageTestTime; Console.WriteLine("RemoteParcelRequestReply: OMV Message System Serialization/Deserialization Passes: {0} Total time: {1}", TEST_ITER, duration); - BinaryFormatter formatter = new BinaryFormatter(); + //BinaryFormatter formatter = new BinaryFormatter(); DateTime xmlTestTime = DateTime.UtcNow; for (int x = 0; x < TEST_ITER; x++) { @@ -1178,10 +1178,13 @@ public void ReflectionPerformanceRemoteParcelResponse() MemoryStream stream = new MemoryStream(); - formatter.Serialize(stream, s); + ZeroFormatter.ZeroFormatterSerializer.Serialize(stream, s); + //formatter.Serialize(stream, s); stream.Seek(0, SeekOrigin.Begin); - RemoteParcelRequestReply t = (RemoteParcelRequestReply)formatter.Deserialize(stream); + //RemoteParcelRequestReply t = (RemoteParcelRequestReply)formatter.Deserialize(stream); + RemoteParcelRequestReply t = + ZeroFormatter.ZeroFormatterSerializer.Deserialize(stream); Assert.AreEqual(s.ParcelID, t.ParcelID); } @@ -1279,10 +1282,12 @@ public void ReflectionPerformanceDirLandReply() MemoryStream stream = new MemoryStream(); - formatter.Serialize(stream, s); + //formatter.Serialize(stream, s); + ZeroFormatter.ZeroFormatterSerializer.Serialize(stream, s); stream.Seek(0, SeekOrigin.Begin); - DirLandReplyMessage t = (DirLandReplyMessage)formatter.Deserialize(stream); + //DirLandReplyMessage t = (DirLandReplyMessage)formatter.Deserialize(stream); + DirLandReplyMessage t = ZeroFormatter.ZeroFormatterSerializer.Deserialize(stream); Assert.AreEqual(s.AgentID, t.AgentID); Assert.AreEqual(s.QueryID, t.QueryID); @@ -1555,11 +1560,13 @@ public void ReflectionPerformanceParcelProperties() MemoryStream stream = new MemoryStream(); - formatter.Serialize(stream, s); + //formatter.Serialize(stream, s); + ZeroFormatter.ZeroFormatterSerializer.Serialize(stream, s); stream.Seek(0, SeekOrigin.Begin); - ParcelPropertiesMessage t = (ParcelPropertiesMessage)formatter.Deserialize(stream); + //ParcelPropertiesMessage t = (ParcelPropertiesMessage)formatter.Deserialize(stream); + ParcelPropertiesMessage t = ZeroFormatter.ZeroFormatterSerializer.Deserialize(stream); Assert.AreEqual(s.AABBMax, t.AABBMax); Assert.AreEqual(s.AABBMin, t.AABBMin); From 14dc39ad48440d28e33c2bfee94dd791880f37be Mon Sep 17 00:00:00 2001 From: Mike Dickson Date: Fri, 10 Sep 2021 12:08:01 -0400 Subject: [PATCH 012/149] Create dotnet.yml --- .github/workflows/dotnet.yml | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 .github/workflows/dotnet.yml diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml new file mode 100644 index 00000000..e4301fef --- /dev/null +++ b/.github/workflows/dotnet.yml @@ -0,0 +1,25 @@ +name: .NET + +on: + push: + branches: [ develop ] + pull_request: + branches: [ develop ] + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + - name: Setup .NET + uses: actions/setup-dotnet@v1 + with: + dotnet-version: 5.0.x + - name: Restore dependencies + run: dotnet restore + - name: Build + run: dotnet build --no-restore + - name: Test + run: dotnet test --no-build --verbosity normal From a77691738b39c03de8a053c5ef491ecae8757fcc Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Fri, 10 Sep 2021 22:18:21 +0100 Subject: [PATCH 013/149] cosmetics --- OpenMetaverse/Assets/AssetTypes/AssetPrim.cs | 10 +- OpenMetaverse/CoordinateFrame.cs | 2 +- OpenMetaverseTypes/Matrix4.cs | 20 +-- OpenMetaverseTypes/Quaternion.cs | 156 +++++++++++++++---- OpenMetaverseTypes/Utils.cs | 35 ++++- OpenMetaverseTypes/Vector2.cs | 4 +- OpenMetaverseTypes/Vector3.cs | 40 +++-- 7 files changed, 192 insertions(+), 75 deletions(-) diff --git a/OpenMetaverse/Assets/AssetTypes/AssetPrim.cs b/OpenMetaverse/Assets/AssetTypes/AssetPrim.cs index a875c325..b17c2ea8 100644 --- a/OpenMetaverse/Assets/AssetTypes/AssetPrim.cs +++ b/OpenMetaverse/Assets/AssetTypes/AssetPrim.cs @@ -416,15 +416,13 @@ static UUID ReadUUID(XmlTextReader reader, string name) static Vector3 ReadVector(XmlTextReader reader, string name) { - Vector3 vec; - reader.ReadStartElement(name); - vec.X = reader.ReadElementContentAsFloat("X", String.Empty); - vec.Y = reader.ReadElementContentAsFloat("Y", String.Empty); - vec.Z = reader.ReadElementContentAsFloat("Z", String.Empty); + float x = reader.ReadElementContentAsFloat("X", String.Empty); + float y = reader.ReadElementContentAsFloat("Y", String.Empty); + float z = reader.ReadElementContentAsFloat("Z", String.Empty); reader.ReadEndElement(); - return vec; + return new Vector3(x,y,z); } static Quaternion ReadQuaternion(XmlTextReader reader, string name) diff --git a/OpenMetaverse/CoordinateFrame.cs b/OpenMetaverse/CoordinateFrame.cs index a03ee77e..c3948a9a 100644 --- a/OpenMetaverse/CoordinateFrame.cs +++ b/OpenMetaverse/CoordinateFrame.cs @@ -255,7 +255,7 @@ public void LookAt(Vector3 origin, Vector3 target) public void LookAt(Vector3 origin, Vector3 target, Vector3 upDirection) { this.origin = origin; - Vector3 at = new Vector3(target - origin); + Vector3 at = target - origin; at.Normalize(); LookDirection(at, upDirection); diff --git a/OpenMetaverseTypes/Matrix4.cs b/OpenMetaverseTypes/Matrix4.cs index bd7f7dec..a7f3f145 100644 --- a/OpenMetaverseTypes/Matrix4.cs +++ b/OpenMetaverseTypes/Matrix4.cs @@ -280,27 +280,27 @@ public Quaternion GetQuaternion() public bool Decompose(out Vector3 scale, out Quaternion rotation, out Vector3 translation) { - translation.X = this.M41; - translation.Y = this.M42; - translation.Z = this.M43; + translation = new Vector3(M41, M42,M43); float xs = (Math.Sign(M11 * M12 * M13 * M14) < 0) ? -1 : 1; float ys = (Math.Sign(M21 * M22 * M23 * M24) < 0) ? -1 : 1; float zs = (Math.Sign(M31 * M32 * M33 * M34) < 0) ? -1 : 1; - scale.X = xs * (float)Math.Sqrt(this.M11 * this.M11 + this.M12 * this.M12 + this.M13 * this.M13); - scale.Y = ys * (float)Math.Sqrt(this.M21 * this.M21 + this.M22 * this.M22 + this.M23 * this.M23); - scale.Z = zs * (float)Math.Sqrt(this.M31 * this.M31 + this.M32 * this.M32 + this.M33 * this.M33); + xs *= (float)Math.Sqrt(M11 * M11 + M12 * M12 + M13 * M13); + ys *= (float)Math.Sqrt(M21 * M21 + M22 * M22 + M23 * M23); + zs *= (float)Math.Sqrt(M31 * M31 + M32 * M32 + M33 * M33); - if (scale.X == 0.0 || scale.Y == 0.0 || scale.Z == 0.0) + scale = new Vector3(xs, ys, zs); + + if (xs == 0.0 || ys == 0.0 || zs == 0.0) { rotation = Quaternion.Identity; return false; } - Matrix4 m1 = new Matrix4(this.M11 / scale.X, M12 / scale.X, M13 / scale.X, 0, - this.M21 / scale.Y, M22 / scale.Y, M23 / scale.Y, 0, - this.M31 / scale.Z, M32 / scale.Z, M33 / scale.Z, 0, + Matrix4 m1 = new Matrix4(M11 / xs, M12 / xs, M13 / xs, 0, + M21 / ys, M22 / ys, M23 / ys, 0, + M31 / zs, M32 / zs, M33 / zs, 0, 0, 0, 0, 1); rotation = Quaternion.CreateFromRotationMatrix(m1); diff --git a/OpenMetaverseTypes/Quaternion.cs b/OpenMetaverseTypes/Quaternion.cs index 4ed9808c..a2272ff6 100644 --- a/OpenMetaverseTypes/Quaternion.cs +++ b/OpenMetaverseTypes/Quaternion.cs @@ -46,6 +46,7 @@ public struct Quaternion : IEquatable #region Constructors + [MethodImpl(MethodImplOptions.AggressiveInlining)] public Quaternion(float x, float y, float z, float w) { X = x; @@ -54,6 +55,7 @@ public Quaternion(float x, float y, float z, float w) W = w; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public Quaternion(Vector3 vectorPart, float scalarPart) { X = vectorPart.X; @@ -68,6 +70,7 @@ public Quaternion(Vector3 vectorPart, float scalarPart) /// X value from -1.0 to 1.0 /// Y value from -1.0 to 1.0 /// Z value from -1.0 to 1.0 + [MethodImpl(MethodImplOptions.AggressiveInlining)] public Quaternion(float x, float y, float z) { X = x; @@ -86,6 +89,7 @@ public Quaternion(float x, float y, float z) /// Whether the source data is normalized or /// not. If this is true 12 bytes will be read, otherwise 16 bytes will /// be read. + [MethodImpl(MethodImplOptions.AggressiveInlining)] public Quaternion(byte[] byteArray, int pos, bool normalized) { X = Y = Z = 0; @@ -93,6 +97,7 @@ public Quaternion(byte[] byteArray, int pos, bool normalized) FromBytes(byteArray, pos, normalized); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public Quaternion(Quaternion q) { X = q.X; @@ -172,12 +177,11 @@ public void Invert() float len = LengthSquared(); if (len > 1e-6f) { - len = 1.0f / len; - - X = -X * len; - Y = -Y * len; - Z = -Z * len; - W = W * len; + len = -1.0f / len; + X = X * len; + Y = Y * len; + Z = Z * len; + W = -W * len; } else { @@ -376,6 +380,7 @@ public static Quaternion Conjugate(Quaternion quaternion) /// Build a quaternion from an axis and an angle of rotation around /// that axis /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Quaternion CreateFromAxisAngle(float axisX, float axisY, float axisZ, float angle) { Vector3 axis = new Vector3(axisX, axisY, axisZ); @@ -388,6 +393,7 @@ public static Quaternion CreateFromAxisAngle(float axisX, float axisY, float axi /// /// Axis of rotation /// Angle of rotation + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Quaternion CreateFromAxisAngle(Vector3 axis, float angle) { axis = Vector3.Normalize(axis); @@ -399,6 +405,36 @@ public static Quaternion CreateFromAxisAngle(Vector3 axis, float angle) return new Quaternion(axis.X * s, axis.Y * s, axis.Z * s, c); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Quaternion CreateRotationX(float angle) + { + angle *= 0.5f; + float c = (float)Math.Cos(angle); + float s = (float)Math.Sin(angle); + + return new Quaternion(s, 0, 0, c); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Quaternion CreateRotationY(float angle) + { + angle *= 0.5f; + float c = (float)Math.Cos(angle); + float s = (float)Math.Sin(angle); + + return new Quaternion(0, s, 0, c); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Quaternion CreateRotationZ(float angle) + { + angle *= 0.5f; + float c = (float)Math.Cos(angle); + float s = (float)Math.Sin(angle); + + return new Quaternion(0, 0, s, c); + } + /// /// Creates a quaternion from a vector containing roll, pitch, and yaw /// in radians @@ -406,6 +442,7 @@ public static Quaternion CreateFromAxisAngle(Vector3 axis, float angle) /// Vector representation of the euler angles in /// radians /// Quaternion representation of the euler angles + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Quaternion CreateFromEulers(Vector3 eulers) { return CreateFromEulers(eulers.X, eulers.Y, eulers.Z); @@ -444,48 +481,92 @@ public static Quaternion CreateFromEulers(float roll, float pitch, float yaw) ); } + public static Quaternion CreateFromRotationMatrix(Matrix3x3 matrix) + { + float num = matrix.M11 + matrix.M22 + matrix.M33; + float n2; + if (num >= 0f) + { + num = (float)Math.Sqrt((num + 1f)); + n2 = 0.5f / num; + return new Quaternion( + (matrix.M23 - matrix.M32) * n2, + (matrix.M31 - matrix.M13) * n2, + (matrix.M12 - matrix.M21) * n2, + num * 0.5f); + } + if ((matrix.M11 >= matrix.M22) && (matrix.M11 >= matrix.M33)) + { + num = (float)Math.Sqrt((((1f + matrix.M11) - matrix.M22) - matrix.M33)); + n2 = 0.5f / num; + return new Quaternion( + 0.5f * num, + (matrix.M12 + matrix.M21) * n2, + (matrix.M13 + matrix.M31) * n2, + (matrix.M23 - matrix.M32) * n2); + } + if (matrix.M22 > matrix.M33) + { + num = (float)Math.Sqrt((((1f + matrix.M22) - matrix.M11) - matrix.M33)); + n2 = 0.5f / num; + return new Quaternion( + (matrix.M21 + matrix.M12) * n2, + 0.5f * num, + (matrix.M32 + matrix.M23) * n2, + (matrix.M31 - matrix.M13) * n2); + } + + num = (float)Math.Sqrt((((1f + matrix.M33) - matrix.M11) - matrix.M22)); + n2 = 0.5f / num; + return new Quaternion( + (matrix.M31 + matrix.M13) * n2, + (matrix.M32 + matrix.M23) * n2, + 0.5f * num, + (matrix.M12 - matrix.M21) * n2); + } + public static Quaternion CreateFromRotationMatrix(Matrix4 matrix) { - float num8 = (matrix.M11 + matrix.M22) + matrix.M33; - if (num8 > 0f) + float num = matrix.M11 + matrix.M22 + matrix.M33; + float n2; + if (num >= 0f) { - float num = (float)Math.Sqrt((double)(num8 + 1f)); - float w = num * 0.5f; - num = 0.5f / num; + num = (float)Math.Sqrt((num + 1f)); + n2 = 0.5f / num; return new Quaternion( - (matrix.M23 - matrix.M32) * num, - (matrix.M31 - matrix.M13) * num, - (matrix.M12 - matrix.M21) * num, - w); + (matrix.M23 - matrix.M32) * n2, + (matrix.M31 - matrix.M13) * n2, + (matrix.M12 - matrix.M21) * n2, + num * 0.5f); } if ((matrix.M11 >= matrix.M22) && (matrix.M11 >= matrix.M33)) { - float num7 = (float)Math.Sqrt((double)(((1f + matrix.M11) - matrix.M22) - matrix.M33)); - float num4 = 0.5f / num7; + num = (float)Math.Sqrt((((1f + matrix.M11) - matrix.M22) - matrix.M33)); + n2 = 0.5f / num; return new Quaternion( - 0.5f * num7, - (matrix.M12 + matrix.M21) * num4, - (matrix.M13 + matrix.M31) * num4, - (matrix.M23 - matrix.M32) * num4); + 0.5f * num, + (matrix.M12 + matrix.M21) * n2, + (matrix.M13 + matrix.M31) * n2, + (matrix.M23 - matrix.M32) * n2); } if (matrix.M22 > matrix.M33) { - float num6 = (float)Math.Sqrt((double)(((1f + matrix.M22) - matrix.M11) - matrix.M33)); - float num3 = 0.5f / num6; + num = (float)Math.Sqrt((((1f + matrix.M22) - matrix.M11) - matrix.M33)); + n2 = 0.5f / num; return new Quaternion( - (matrix.M21 + matrix.M12) * num3, - 0.5f * num6, - (matrix.M32 + matrix.M23) * num3, - (matrix.M31 - matrix.M13) * num3); + (matrix.M21 + matrix.M12) * n2, + 0.5f * num, + (matrix.M32 + matrix.M23) * n2, + (matrix.M31 - matrix.M13) * n2); } - float num5 = (float)Math.Sqrt((double)(((1f + matrix.M33) - matrix.M11) - matrix.M22)); - float num2 = 0.5f / num5; + num = (float)Math.Sqrt((((1f + matrix.M33) - matrix.M11) - matrix.M22)); + n2 = 0.5f / num; return new Quaternion( - (matrix.M31 + matrix.M13) * num2, - (matrix.M32 + matrix.M23) * num2, - 0.5f * num5, - (matrix.M12 - matrix.M21) * num2); + (matrix.M31 + matrix.M13) * n2, + (matrix.M32 + matrix.M23) * n2, + 0.5f * num, + (matrix.M12 - matrix.M21) * n2); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -581,6 +662,7 @@ public static Quaternion Subtract(Quaternion quaternion1, Quaternion quaternion2 quaternion1.W - quaternion2.W); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Quaternion Multiply(Quaternion a, Quaternion b) { return new Quaternion( @@ -710,31 +792,37 @@ public string ToRawString() #region Operators + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool operator ==(Quaternion quaternion1, Quaternion quaternion2) { return quaternion1.Equals(quaternion2); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool operator !=(Quaternion quaternion1, Quaternion quaternion2) { return !quaternion1.Equals(quaternion2); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Quaternion operator +(Quaternion quaternion1, Quaternion quaternion2) { return Add(quaternion1, quaternion2); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Quaternion operator -(Quaternion quaternion) { return Negate(quaternion); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Quaternion operator -(Quaternion quaternion1, Quaternion quaternion2) { return Subtract(quaternion1, quaternion2); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Quaternion operator *(Quaternion a, Quaternion b) { return new Quaternion( @@ -745,6 +833,7 @@ public string ToRawString() ); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Quaternion operator *(Quaternion quaternion, float scaleFactor) { return new Quaternion( @@ -754,6 +843,7 @@ public string ToRawString() quaternion.W * scaleFactor); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Quaternion operator /(Quaternion quaternion1, Quaternion quaternion2) { return Divide(quaternion1, quaternion2); diff --git a/OpenMetaverseTypes/Utils.cs b/OpenMetaverseTypes/Utils.cs index 08de633d..8ebb141e 100644 --- a/OpenMetaverseTypes/Utils.cs +++ b/OpenMetaverseTypes/Utils.cs @@ -27,6 +27,7 @@ */ using System; +using System.Runtime.CompilerServices; using System.Text; namespace OpenMetaverse @@ -110,13 +111,16 @@ public enum Runtime /// Minimum allowable value /// Maximum allowable value /// A value inclusively between lower and upper + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static float Clamp(float value, float min, float max) { // First we check to see if we're greater than the max - value = (value > max) ? max : value; + if (value > max) + return max; // Then we check to see if we're less than the min. - value = (value < min) ? min : value; + if (value < min) + return min; // There's no check to see if min > max. return value; @@ -129,13 +133,16 @@ public static float Clamp(float value, float min, float max) /// Minimum allowable value /// Maximum allowable value /// A value inclusively between lower and upper + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static double Clamp(double value, double min, double max) { // First we check to see if we're greater than the max - value = (value > max) ? max : value; + if (value > max) + return max; // Then we check to see if we're less than the min. - value = (value < min) ? min : value; + if (value < min) + return min; // There's no check to see if min > max. return value; @@ -148,13 +155,16 @@ public static double Clamp(double value, double min, double max) /// Minimum allowable value /// Maximum allowable value /// A value inclusively between lower and upper + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int Clamp(int value, int min, int max) { // First we check to see if we're greater than the max - value = (value > max) ? max : value; + if (value > max) + return max; // Then we check to see if we're less than the min. - value = (value < min) ? min : value; + if (value < min) + return min; // There's no check to see if min > max. return value; @@ -165,6 +175,7 @@ public static int Clamp(int value, int min, int max) /// /// Floating point number to round /// Integer + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int Round(float val) { return (int)Math.Floor(val + 0.5f); @@ -173,6 +184,7 @@ public static int Round(float val) /// /// Test if a single precision float is a finite number /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool IsFinite(float value) { return !(Single.IsNaN(value) || Single.IsInfinity(value)); @@ -181,6 +193,7 @@ public static bool IsFinite(float value) /// /// Test if a double precision float is a finite number /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool IsFinite(double value) { return !(Double.IsNaN(value) || Double.IsInfinity(value)); @@ -192,6 +205,7 @@ public static bool IsFinite(double value) /// First value /// Second value /// The distance between the two values + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static float Distance(float value1, float value2) { return Math.Abs(value1 - value2); @@ -263,6 +277,7 @@ public static double SmoothStep(double value1, double value2, double amount) return Utils.Hermite(value1, 0f, value2, 0f, result); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static float ToDegrees(float radians) { // This method uses double precission internally, @@ -271,6 +286,8 @@ public static float ToDegrees(float radians) return (float)(radians * 57.295779513082320876798154814105); } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static float ToRadians(float degrees) { // This method uses double precission internally, @@ -284,6 +301,7 @@ public static float ToRadians(float degrees) /// /// Byte array to compute the hash for /// MD5 hash of the input data + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static byte[] MD5(byte[] data) { lock (MD5Builder) @@ -295,6 +313,7 @@ public static byte[] MD5(byte[] data) /// /// Byte array to compute the hash for /// SHA1 hash of the input data + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static byte[] SHA1(byte[] data) { lock (SHA1Builder) @@ -306,6 +325,7 @@ public static byte[] SHA1(byte[] data) /// /// The string to hash /// The SHA1 hash as a string + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string SHA1String(string value) { StringBuilder digest = new StringBuilder(40); @@ -323,6 +343,7 @@ public static string SHA1String(string value) /// /// Byte array to compute the hash for /// SHA256 hash of the input data + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static byte[] SHA256(byte[] data) { lock (SHA256Builder) @@ -334,6 +355,7 @@ public static byte[] SHA256(byte[] data) /// /// The string to hash /// The SHA256 hash as a string + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string SHA256String(string value) { StringBuilder digest = new StringBuilder(64); @@ -351,6 +373,7 @@ public static string SHA256String(string value) /// /// The password to hash /// An MD5 hash in string format, with $1$ prepended + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string MD5(string password) { StringBuilder digest = new StringBuilder(32); diff --git a/OpenMetaverseTypes/Vector2.cs b/OpenMetaverseTypes/Vector2.cs index bdc07095..fb437317 100644 --- a/OpenMetaverseTypes/Vector2.cs +++ b/OpenMetaverseTypes/Vector2.cs @@ -295,7 +295,7 @@ public static Vector2 Normalize(Vector2 value) factor = 1f / (float)Math.Sqrt(factor); return new Vector2(value.X * factor, value.Y * factor); } - return Vector2.Zero; + return new Vector2(); } /// @@ -321,7 +321,7 @@ public static bool TryParse(string val, out Vector2 result) } catch (Exception) { - result = Vector2.Zero; + result = new Vector2(); return false; } } diff --git a/OpenMetaverseTypes/Vector3.cs b/OpenMetaverseTypes/Vector3.cs index 7325408e..ce7b478c 100644 --- a/OpenMetaverseTypes/Vector3.cs +++ b/OpenMetaverseTypes/Vector3.cs @@ -47,6 +47,7 @@ public struct Vector3 : IComparable, IEquatable #region Constructors + [MethodImpl(MethodImplOptions.AggressiveInlining)] public Vector3(float x, float y, float z) { X = x; @@ -54,6 +55,7 @@ public Vector3(float x, float y, float z) Z = z; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public Vector3(float value) { X = value; @@ -61,6 +63,7 @@ public Vector3(float value) Z = value; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public Vector3(Vector2 value, float z) { X = value.X; @@ -68,6 +71,7 @@ public Vector3(Vector2 value, float z) Z = z; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public Vector3(Vector3d vector) { X = (float)vector.X; @@ -75,23 +79,26 @@ public Vector3(Vector3d vector) Z = (float)vector.Z; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vector3(Vector3 vector) + { + X = vector.X; + Y = vector.Y; + Z = vector.Z; + } + /// /// Constructor, builds a vector from a byte array /// /// Byte array containing three four-byte floats /// Beginning position in the byte array + [MethodImpl(MethodImplOptions.AggressiveInlining)] public Vector3(byte[] byteArray, int pos) { X = Y = Z = 0f; FromBytes(byteArray, pos); } - public Vector3(Vector3 vector) - { - X = vector.X; - Y = vector.Y; - Z = vector.Z; - } #endregion Constructors @@ -126,19 +133,19 @@ public void Max(Vector3 v) [MethodImpl(MethodImplOptions.AggressiveInlining)] public float Length() { - return (float)Math.Sqrt((X * X) + (Y * Y) + (Z * Z)); + return (float)Math.Sqrt(X * X + Y * Y + Z * Z); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public float LengthSquared() { - return (X * X) + (Y * Y) + (Z * Z); + return (X * X + Y * Y + Z * Z); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Normalize() { - float factor = LengthSquared(); + float factor = X * X + Y * Y + Z * Z; if (factor > 1e-6f) { factor = 1f / (float)Math.Sqrt(factor); @@ -274,13 +281,10 @@ public static float Distance(Vector3 value1, Vector3 value2) public static float DistanceSquared(Vector3 value1, Vector3 value2) { float x = value1.X - value2.X; - x *= x; float y = value1.Y - value2.Y; - y *= y; float z = value1.Z - value2.Z; - x += y; - return (x + z * z); + return x * x + y * y + z * z; } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -359,9 +363,9 @@ public static Vector3 Normalize(Vector3 value) if (factor > 1e-6f) { factor = 1f / (float)Math.Sqrt(factor); - return new Vector3(value.X * factor, value.Y * factor, value.Z * factor); + return value * factor; } - return Vector3.Zero; + return new Vector3(); } /// @@ -505,7 +509,7 @@ public override int GetHashCode() { int hash = X.GetHashCode(); hash = Utils.CombineHash(hash, Y.GetHashCode()); - hash = Utils.CombineHash(hash, Y.GetHashCode()); + hash = Utils.CombineHash(hash, Z.GetHashCode()); return hash; } @@ -627,6 +631,7 @@ public string ToRawString() /// /// Cross product between two vectors /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 operator %(Vector3 value1, Vector3 value2) { return Cross(value1, value2); @@ -637,6 +642,7 @@ public string ToRawString() /// /// /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static explicit operator Vector3(Vector3d value) { return new Vector3(value); @@ -647,7 +653,7 @@ public static explicit operator Vector3(Vector3d value) /// A vector with a value of 0,0,0 public readonly static Vector3 Zero = new Vector3(); /// A vector with a value of 1,1,1 - public readonly static Vector3 One = new Vector3(1f, 1f, 1f); + public readonly static Vector3 One = new Vector3(1f); /// A unit vector facing forward (X axis), value 1,0,0 public readonly static Vector3 UnitX = new Vector3(1f, 0f, 0f); /// A unit vector facing left (Y axis), value 0,1,0 From 8bf53bedce20889fd58a91b8f2502f2d275d1b65 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Fri, 10 Sep 2021 22:20:25 +0100 Subject: [PATCH 014/149] and a simple 3x3 matrix without simd polution --- OpenMetaverseTypes/Matrix3x3.cs | 886 ++++++++++++++++++++++++++++++++ 1 file changed, 886 insertions(+) create mode 100644 OpenMetaverseTypes/Matrix3x3.cs diff --git a/OpenMetaverseTypes/Matrix3x3.cs b/OpenMetaverseTypes/Matrix3x3.cs new file mode 100644 index 00000000..4ffff538 --- /dev/null +++ b/OpenMetaverseTypes/Matrix3x3.cs @@ -0,0 +1,886 @@ +/* + * Copyright (c) 2006-2016, openmetaverse.co + * All rights reserved. + * + * - Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * - Neither the name of the openmetaverse.co nor the names + * of its contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Runtime.InteropServices; + +namespace OpenMetaverse +{ + [Serializable] + [StructLayout(LayoutKind.Sequential)] + public struct Matrix3x3 : IEquatable< Matrix3x3> + { + public float M11, M12, M13; + public float M21, M22, M23; + public float M31, M32, M33; + + #region Properties + + public Vector3 AtAxis + { + get + { + return new Vector3(M11, M21, M31); + } + set + { + M11 = value.X; + M21 = value.Y; + M31 = value.Z; + } + } + + public Vector3 LeftAxis + { + get + { + return new Vector3(M12, M22, M32); + } + set + { + M12 = value.X; + M22 = value.Y; + M32 = value.Z; + } + } + + public Vector3 UpAxis + { + get + { + return new Vector3(M13, M23, M33); + } + set + { + M13 = value.X; + M23 = value.Y; + M33 = value.Z; + } + } + + #endregion Properties + + #region Constructors + + public Matrix3x3( + float m11, float m12, float m13, + float m21, float m22, float m23, + float m31, float m32, float m33) + { + M11 = m11; + M12 = m12; + M13 = m13; + + M21 = m21; + M22 = m22; + M23 = m23; + + M31 = m31; + M32 = m32; + M33 = m33; + } + + public Matrix3x3(float roll, float pitch, float yaw) + { + this = CreateFromEulers(roll, pitch, yaw); + } + + public Matrix3x3( Matrix3x3 m) + { + M11 = m.M11; + M12 = m.M12; + M13 = m.M13; + + M21 = m.M21; + M22 = m.M22; + M23 = m.M23; + + M31 = m.M31; + M32 = m.M32; + M33 = m.M33; + } + + #endregion Constructors + + #region Public Methods + + public float Determinant() + { + return Determinant3x3(); + } + + public float Determinant3x3() + { + float diag1 = M11 * M22 * M33; + float diag2 = M12 * M23 * M31; + float diag3 = M13 * M21 * M32; + float diag4 = M31 * M22 * M13; + float diag5 = M32 * M23 * M11; + float diag6 = M33 * M21 * M12; + + return diag1 + diag2 + diag3 - (diag4 + diag5 + diag6); + } + + public float Trace() + { + return M11 + M22 + M33; + } + + /// + /// Convert this matrix to euler rotations + /// + /// X euler angle + /// Y euler angle + /// Z euler angle + public void GetEulerAngles(out float roll, out float pitch, out float yaw) + { + double angleX, angleY, angleZ; + double cx, cy, cz; // cosines + double sx, sz; // sines + + angleY = Math.Asin(Utils.Clamp(M13, -1f, 1f)); + cy = Math.Cos(angleY); + + if (Math.Abs(cy) > 0.005f) + { + // No gimbal lock + cx = M33 / cy; + sx = (-M23) / cy; + + angleX = (float)Math.Atan2(sx, cx); + + cz = M11 / cy; + sz = (-M12) / cy; + + angleZ = (float)Math.Atan2(sz, cz); + } + else + { + // Gimbal lock + angleX = 0; + + cz = M22; + sz = M21; + + angleZ = Math.Atan2(sz, cz); + } + + // Return only positive angles in [0,360] + if (angleX < 0) angleX += 360d; + if (angleY < 0) angleY += 360d; + if (angleZ < 0) angleZ += 360d; + + roll = (float)angleX; + pitch = (float)angleY; + yaw = (float)angleZ; + } + + /// + /// Convert this matrix to a quaternion rotation + /// + /// A quaternion representation of this rotation matrix + public Quaternion GetQuaternion() + { + Quaternion quat = new Quaternion(); + float trace = Trace() + 1f; + + if (trace > Single.Epsilon) + { + float s = 0.5f / (float)Math.Sqrt(trace); + + quat.X = (M32 - M23) * s; + quat.Y = (M13 - M31) * s; + quat.Z = (M21 - M12) * s; + quat.W = 0.25f / s; + } + else + { + if (M11 > M22 && M11 > M33) + { + float s = 2.0f * (float)Math.Sqrt(1.0f + M11 - M22 - M33); + + quat.X = 0.25f * s; + quat.Y = (M12 + M21) / s; + quat.Z = (M13 + M31) / s; + quat.W = (M23 - M32) / s; + } + else if (M22 > M33) + { + float s = 2.0f * (float)Math.Sqrt(1.0f + M22 - M11 - M33); + + quat.X = (M12 + M21) / s; + quat.Y = 0.25f * s; + quat.Z = (M23 + M32) / s; + quat.W = (M13 - M31) / s; + } + else + { + float s = 2.0f * (float)Math.Sqrt(1.0f + M33 - M11 - M22); + + quat.X = (M13 + M31) / s; + quat.Y = (M23 + M32) / s; + quat.Z = 0.25f * s; + quat.W = (M12 - M21) / s; + } + } + + return quat; + } + + public bool Decompose(out Vector3 scale, out Quaternion rotation) + { + float sx = (float)Math.Sqrt(M11 * M11 + M12 * M12 + M13 * M13); + float sy = (float)Math.Sqrt(M21 * M21 + M22 * M22 + M23 * M23); + float sz = (float)Math.Sqrt(M31 * M31 + M32 * M32 + M33 * M33); + + scale = new Vector3(sx, sy, sz); + if (sx == 0.0 || sy == 0.0 || sz == 0.0) + { + rotation = Quaternion.Identity; + return false; + } + + Matrix3x3 m1 = new Matrix3x3( + M11 / sx, M12 / sx, M13 / sx, + M21 / sy, M22 / sy, M23 / sy, + M31 / sz, M32 / sz, M33 / sz); + + rotation = Quaternion.CreateFromRotationMatrix(m1); + return true; + } + + #endregion Public Methods + + #region Static Methods + + public static Matrix3x3 Add( Matrix3x3 matrix1, Matrix3x3 matrix2) + { + return new Matrix3x3( + matrix1.M11 + matrix2.M11, + matrix1.M12 + matrix2.M12, + matrix1.M13 + matrix2.M13, + + matrix1.M21 + matrix2.M21, + matrix1.M22 + matrix2.M22, + matrix1.M23 + matrix2.M23, + + matrix1.M31 + matrix2.M31, + matrix1.M32 + matrix2.M32, + matrix1.M33 + matrix2.M33 + ); + } + + public static Matrix3x3 CreateFromAxisAngle(Vector3 axis, float angle) + { + + float x = axis.X; + float y = axis.Y; + float z = axis.Z; + float sin = (float)Math.Sin(angle); + float cos = (float)Math.Cos(angle); + float xx = x * x; + float yy = y * y; + float zz = z * z; + float xy = x * y; + float xz = x * z; + float yz = y * z; + + return new Matrix3x3( + xx + (cos * (1f - xx)), + xy - (cos * xy) + (sin * z), + xz - (cos * xz) - (sin * y), + + xy - (cos * xy) - (sin * z), + yy + (cos * (1f - yy)), + yz - (cos * yz) + (sin * x), + + xz - (cos * xz) + (sin * y), + yz - (cos * yz) - (sin * x), + zz + (cos * (1f - zz)) + ); + } + + /// + /// Construct a matrix from euler rotation values in radians + /// + /// X euler angle in radians + /// Y euler angle in radians + /// Z euler angle in radians + public static Matrix3x3 CreateFromEulers(float roll, float pitch, float yaw) + { + float a = (float)Math.Cos(roll); + float b = (float)Math.Sin(roll); + float c = (float)Math.Cos(pitch); + float d = (float)Math.Sin(pitch); + float e = (float)Math.Cos(yaw); + float f = (float)Math.Sin(yaw); + + float ad = a * d; + float bd = b * d; + return new Matrix3x3( + c * e, + -c * f, + d, + + bd * e + a * f, + -bd * f + a * e, + -b * c, + + -ad * e + b * f, + ad * f + b * e, + a * c + ); + } + + public static Matrix3x3 CreateFromQuaternion(Quaternion rot) + { + float x2 = rot.X + rot.X; + float y2 = rot.Y + rot.Y; + float z2 = rot.Z + rot.Z; + + float wx2 = rot.W * x2; + float wy2 = rot.W * y2; + float wz2 = rot.W * z2; + float xx2 = rot.X * x2; + float xy2 = rot.X * y2; + float xz2 = rot.X * z2; + float yy2 = rot.Y * y2; + float yz2 = rot.Y * z2; + float zz2 = rot.Z * z2; + + return new Matrix3x3( + 1.0f - yy2 - zz2, + xy2 - wz2, + xz2 + wy2, + + xy2 + wz2, + 1.0f - xx2 - zz2, + yz2 - wx2, + + xz2 - wy2, + yz2 + wx2, + 1.0f - xx2 - yy2 + ); + } + + public static Matrix3x3 CreateRotationX(float radians) + { + float cos = (float)Math.Cos(radians); + float sin = (float)Math.Sin(radians); + + return new Matrix3x3( + 1f, 0f, 0f, + 0f, cos, sin, + 0f, -sin, cos + ); + } + + public static Matrix3x3 CreateRotationY(float radians) + { + float cos = (float)Math.Cos(radians); + float sin = (float)Math.Sin(radians); + + return new Matrix3x3( + cos, 0f, -sin, + 0f, 1f, 0f, + sin, 0f, cos + ); + } + + public static Matrix3x3 CreateRotationZ(float radians) + { + float cos = (float)Math.Cos(radians); + float sin = (float)Math.Sin(radians); + + return new Matrix3x3( + cos, sin, 0f, + -sin, cos, 0f, + 0f, 0f, 1f + ); + } + + public static Matrix3x3 CreateScale(Vector3 scale) + { + return new Matrix3x3( + scale.X, 0f, 0f, + 0f, scale.Y, 0f, + 0f, 0f, scale.Z + ); + } + + public static Matrix3x3 Divide( Matrix3x3 matrix1, Matrix3x3 matrix2) + { + return new Matrix3x3( + matrix1.M11 / matrix2.M11, + matrix1.M12 / matrix2.M12, + matrix1.M13 / matrix2.M13, + + matrix1.M21 / matrix2.M21, + matrix1.M22 / matrix2.M22, + matrix1.M23 / matrix2.M23, + + matrix1.M31 / matrix2.M31, + matrix1.M32 / matrix2.M32, + matrix1.M33 / matrix2.M33 + ); + } + + public static Matrix3x3 Divide( Matrix3x3 matrix1, float divider) + { + float oodivider = 1f / divider; + return new Matrix3x3( + matrix1.M11 * oodivider, + matrix1.M12 * oodivider, + matrix1.M13 * oodivider, + + matrix1.M21 * oodivider, + matrix1.M22 * oodivider, + matrix1.M23 * oodivider, + + matrix1.M31 * oodivider, + matrix1.M32 * oodivider, + matrix1.M33 * oodivider + ); + } + + public static Matrix3x3 Lerp( Matrix3x3 matrix1, Matrix3x3 matrix2, float amount) + { + return new Matrix3x3( + matrix1.M11 + ((matrix2.M11 - matrix1.M11) * amount), + matrix1.M12 + ((matrix2.M12 - matrix1.M12) * amount), + matrix1.M13 + ((matrix2.M13 - matrix1.M13) * amount), + + matrix1.M21 + ((matrix2.M21 - matrix1.M21) * amount), + matrix1.M22 + ((matrix2.M22 - matrix1.M22) * amount), + matrix1.M23 + ((matrix2.M23 - matrix1.M23) * amount), + + matrix1.M31 + ((matrix2.M31 - matrix1.M31) * amount), + matrix1.M32 + ((matrix2.M32 - matrix1.M32) * amount), + matrix1.M33 + ((matrix2.M33 - matrix1.M33) * amount) + ); + } + + public static Matrix3x3 Multiply( Matrix3x3 matrix1, Matrix3x3 matrix2) + { + return new Matrix3x3( + matrix1.M11 * matrix2.M11 + matrix1.M12 * matrix2.M21 + matrix1.M13 * matrix2.M31, + matrix1.M11 * matrix2.M12 + matrix1.M12 * matrix2.M22 + matrix1.M13 * matrix2.M32, + matrix1.M11 * matrix2.M13 + matrix1.M12 * matrix2.M23 + matrix1.M13 * matrix2.M33, + + matrix1.M21 * matrix2.M11 + matrix1.M22 * matrix2.M21 + matrix1.M23 * matrix2.M31, + matrix1.M21 * matrix2.M12 + matrix1.M22 * matrix2.M22 + matrix1.M23 * matrix2.M32, + matrix1.M21 * matrix2.M13 + matrix1.M22 * matrix2.M23 + matrix1.M23 * matrix2.M33, + + matrix1.M31 * matrix2.M11 + matrix1.M32 * matrix2.M21 + matrix1.M33 * matrix2.M31, + matrix1.M31 * matrix2.M12 + matrix1.M32 * matrix2.M22 + matrix1.M33 * matrix2.M32, + matrix1.M31 * matrix2.M13 + matrix1.M32 * matrix2.M23 + matrix1.M33 * matrix2.M33 + ); + } + + public static Matrix3x3 Multiply( Matrix3x3 matrix1, float scaleFactor) + { + Matrix3x3 matrix; + matrix.M11 = matrix1.M11 * scaleFactor; + matrix.M12 = matrix1.M12 * scaleFactor; + matrix.M13 = matrix1.M13 * scaleFactor; + + matrix.M21 = matrix1.M21 * scaleFactor; + matrix.M22 = matrix1.M22 * scaleFactor; + matrix.M23 = matrix1.M23 * scaleFactor; + + matrix.M31 = matrix1.M31 * scaleFactor; + matrix.M32 = matrix1.M32 * scaleFactor; + matrix.M33 = matrix1.M33 * scaleFactor; + + return matrix; + } + + public static Matrix3x3 Negate( Matrix3x3 matrix) + { + return new Matrix3x3( + -matrix.M11, -matrix.M12, -matrix.M13, + -matrix.M21, -matrix.M22, -matrix.M23, + -matrix.M31, -matrix.M32, -matrix.M33 + ); + } + + public static Matrix3x3 Subtract( Matrix3x3 matrix1, Matrix3x3 matrix2) + { + return new Matrix3x3( + matrix1.M11 - matrix2.M11, + matrix1.M12 - matrix2.M12, + matrix1.M13 - matrix2.M13, + + matrix1.M21 - matrix2.M21, + matrix1.M22 - matrix2.M22, + matrix1.M23 - matrix2.M23, + + matrix1.M31 - matrix2.M31, + matrix1.M32 - matrix2.M32, + matrix1.M33 - matrix2.M33 + ); + } + + public static Matrix3x3 Transform( Matrix3x3 value, Quaternion rotation) + { + float x2 = rotation.X + rotation.X; + float y2 = rotation.Y + rotation.Y; + float z2 = rotation.Z + rotation.Z; + + float a = (1f - rotation.Y * y2) - rotation.Z * z2; + float b = rotation.X * y2 - rotation.W * z2; + float c = rotation.X * z2 + rotation.W * y2; + float d = rotation.X * y2 + rotation.W * z2; + float e = (1f - rotation.X * x2) - rotation.Z * z2; + float f = rotation.Y * z2 - rotation.W * x2; + float g = rotation.X * z2 - rotation.W * y2; + float h = rotation.Y * z2 + rotation.W * x2; + float i = (1f - rotation.X * x2) - rotation.Y * y2; + + return new Matrix3x3( + value.M11 * a + value.M12 * b + value.M13 * c, + value.M11 * d + value.M12 * e + value.M13 * f, + value.M11 * g + value.M12 * h + value.M13 * i, + + value.M21 * a + value.M22 * b + value.M23 * c, + value.M21 * d + value.M22 * e + value.M23 * f, + value.M21 * g + value.M22 * h + value.M23 * i, + + value.M31 * a + value.M32 * b + value.M33 * c, + value.M31 * d + value.M32 * e + value.M33 * f, + value.M31 * g + value.M32 * h + value.M33 * i + ); + } + + public static Matrix3x3 Transpose( Matrix3x3 matrix) + { + return new Matrix3x3( + matrix.M11, + matrix.M21, + matrix.M31, + matrix.M12, + matrix.M22, + matrix.M32, + matrix.M13, + matrix.M23, + matrix.M33 + ); + } + + public static Matrix3x3 Inverse3x3(Matrix3x3 matrix) + { + if (matrix.Determinant3x3() == 0f) + throw new ArgumentException("Singular matrix inverse not possible"); + + return (Adjoint3x3(matrix) / matrix.Determinant3x3()); + } + + public static Matrix3x3 Adjoint3x3( Matrix3x3 matrix) + { + Matrix3x3 adjointMatrix = new Matrix3x3(); + for (int i = 0; i < 4; i++) + { + for (int j = 0; j < 4; j++) + adjointMatrix[i,j] = (float)(Math.Pow(-1, i + j) * (Minor(matrix, i, j).Determinant3x3())); + } + + adjointMatrix = Transpose(adjointMatrix); + return adjointMatrix; + } + + public static Matrix3x3 Inverse( Matrix3x3 matrix) + { + if (matrix.Determinant() == 0f) + throw new ArgumentException("Singular matrix inverse not possible"); + + return (Adjoint(matrix) / matrix.Determinant()); + } + + public static Matrix3x3 Adjoint( Matrix3x3 matrix) + { + Matrix3x3 adjointMatrix = new Matrix3x3(); + for (int i = 0; i < 3; i++) + { + for (int j = 0; j < 3; j++) + adjointMatrix[i,j] = (float)(Math.Pow(-1, i + j) * ((Minor(matrix, i, j)).Determinant3x3())); + } + + adjointMatrix = Transpose(adjointMatrix); + return adjointMatrix; + } + + public static Matrix3x3 Minor(Matrix3x3 matrix, int row, int col) + { + Matrix3x3 minor = new Matrix3x3(); + int m = 0, n = 0; + + for (int i = 0; i < 3; i++) + { + if (i == row) + continue; + n = 0; + for (int j = 0; j < 3; j++) + { + if (j == col) + continue; + minor[m,n] = matrix[i,j]; + n++; + } + m++; + } + + return minor; + } + + #endregion Static Methods + + #region Overrides + + public override bool Equals(object obj) + { + return (obj is Matrix3x3) ? this.Equals(( Matrix3x3)obj) : false; + } + + public bool Equals( Matrix3x3 other) + { + return M11 == other.M11 && M12 == other.M12 && M13 == other.M13 && + M21 == other.M21 && M22 == other.M22 && M23 == other.M23 && + M31 == other.M31 && M32 == other.M32 && M33 == other.M33; + } + + public override int GetHashCode() + { + return + M11.GetHashCode() ^ M12.GetHashCode() ^ M13.GetHashCode() ^ + M21.GetHashCode() ^ M22.GetHashCode() ^ M23.GetHashCode() ^ + M31.GetHashCode() ^ M32.GetHashCode() ^ M33.GetHashCode(); + } + + /// + /// Get a formatted string representation of the vector + /// + /// A string representation of the vector + public override string ToString() + { + return string.Format(Utils.EnUsCulture, + "|{0}, {1}, {2}|\n|{3}, {4}, {5}|\n|{6}, {7} {8}|\n", + M11, M12, M13, M21, M22, M23, M31, M32, M33); + } + + #endregion Overrides + + #region Operators + + public static bool operator ==( Matrix3x3 left, Matrix3x3 right) + { + return left.Equals(right); + } + + public static bool operator !=( Matrix3x3 left, Matrix3x3 right) + { + return !left.Equals(right); + } + + public static Matrix3x3 operator +( Matrix3x3 left, Matrix3x3 right) + { + return Add(left, right); + } + + public static Matrix3x3 operator -( Matrix3x3 matrix) + { + return Negate(matrix); + } + + public static Matrix3x3 operator -( Matrix3x3 left, Matrix3x3 right) + { + return Subtract(left, right); + } + + public static Matrix3x3 operator *( Matrix3x3 left, Matrix3x3 right) + { + return Multiply(left, right); + } + + public static Matrix3x3 operator *( Matrix3x3 left, float scalar) + { + return Multiply(left, scalar); + } + + public static Matrix3x3 operator /( Matrix3x3 left, Matrix3x3 right) + { + return Divide(left, right); + } + + public static Matrix3x3 operator /( Matrix3x3 matrix, float divider) + { + return Divide(matrix, divider); + } + + public Vector3 this[int row] + { + get + { + switch (row) + { + case 0: + return new Vector3(M11, M12, M13); + case 1: + return new Vector3(M21, M22, M23); + case 2: + return new Vector3(M31, M32, M33); + default: + throw new IndexOutOfRangeException("Matrix3x3 row index must be from 0-2"); + } + } + set + { + switch (row) + { + case 0: + M11 = value.X; + M12 = value.Y; + M13 = value.Z; + break; + case 1: + M21 = value.X; + M22 = value.Y; + M23 = value.Z; + break; + case 2: + M31 = value.X; + M32 = value.Y; + M33 = value.Z; + break; + default: + throw new IndexOutOfRangeException("Matrix3x3 row index must be from 0-2"); + } + } + } + + public float this[int row, int column] + { + get + { + switch (row) + { + case 0: + switch (column) + { + case 0: + return M11; + case 1: + return M12; + case 2: + return M13; + default: + throw new IndexOutOfRangeException(" Matrix3x3 row and column values must be from 0-2"); + } + case 1: + switch (column) + { + case 0: + return M21; + case 1: + return M22; + case 2: + return M23; + default: + throw new IndexOutOfRangeException(" Matrix3x3 row and column values must be from 0-2"); + } + case 2: + switch (column) + { + case 0: + return M31; + case 1: + return M32; + case 2: + return M33; + default: + throw new IndexOutOfRangeException(" Matrix3x3 row and column values must be from 0-2"); + } + default: + throw new IndexOutOfRangeException(" Matrix3x3 row and column values must be from 0-2"); + } + } + set + { + switch (row) + { + case 0: + switch (column) + { + case 0: + M11 = value; return; + case 1: + M12 = value; return; + case 2: + M13 = value; return; + default: + throw new IndexOutOfRangeException(" Matrix3x3 row and column values must be from 0-2"); + } + case 1: + switch (column) + { + case 0: + M21 = value; return; + case 1: + M22 = value; return; + case 2: + M23 = value; return; + default: + throw new IndexOutOfRangeException(" Matrix3x3 row and column values must be from 0-2"); + } + case 2: + switch (column) + { + case 0: + M31 = value; return; + case 1: + M32 = value; return; + case 2: + M33 = value; return; + default: + throw new IndexOutOfRangeException(" Matrix3x3 row and column values must be from 0-2"); + } + default: + throw new IndexOutOfRangeException(" Matrix3x3 row and column values must be from 0-2"); + } + } + } + + #endregion Operators + + /// A 3x3 matrix containing all zeroes + public static readonly Matrix3x3 Zero = new Matrix3x3(); + + /// A 3x3 identity matrix + public static readonly Matrix3x3 Identity = new Matrix3x3( + 1f, 0f, 0f, + 0f, 1f, 0f, + 0f, 0f, 1f); + } +} From 7557c033a3b18c3e2b8849b73db0f4a238f75d8a Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Fri, 1 Oct 2021 17:33:16 +0100 Subject: [PATCH 015/149] fix osUTF8GetBytesCount.. --- OpenMetaverseTypes/UtilsConversions.cs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/OpenMetaverseTypes/UtilsConversions.cs b/OpenMetaverseTypes/UtilsConversions.cs index a52ffce9..3e02c150 100644 --- a/OpenMetaverseTypes/UtilsConversions.cs +++ b/OpenMetaverseTypes/UtilsConversions.cs @@ -1687,11 +1687,15 @@ public static int osUTF8GetBytesCount(string str, out int maxsource) if (c >= 0xD800 && c < 0xE000) { + if (c >= 0xDC00) + continue; + if (i == str.Length) + break; + c = str[i++]; if (c < 0xDC00 || c > 0xDFFF) continue; lastc = c; nbytes += 4; - ++i; continue; } lastc = c; @@ -1739,12 +1743,16 @@ public static int osUTF8GetBytesCount(string str, int maxnbytes, out int maxsour if (c >= 0xD800 && c < 0xE000) { + if (c >= 0xDC00) + continue; + if (i == str.Length) + break; + c = str[i++]; if (c < 0xDC00 || c > 0xDFFF) continue; if (nbytes > max4) break; nbytes += 4; - ++i; continue; } if (nbytes > max3) From f9960cb0e04bb443b2abfd407d7146f2e242d481 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Fri, 26 Nov 2021 19:04:08 +0000 Subject: [PATCH 016/149] save a few ns --- OpenMetaverseTypes/UtilsConversions.cs | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/OpenMetaverseTypes/UtilsConversions.cs b/OpenMetaverseTypes/UtilsConversions.cs index 3e02c150..a66cecc5 100644 --- a/OpenMetaverseTypes/UtilsConversions.cs +++ b/OpenMetaverseTypes/UtilsConversions.cs @@ -595,17 +595,26 @@ public unsafe static long BytesToInt64Safepos(byte[] bytes, int pos) /// An unsigned short, will be zero if a ushort can't be read /// at the given position [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static ushort BytesToUInt16(byte[] bytes, int pos) + public static unsafe ushort BytesToUInt16(byte[] bytes, int pos) { //if (bytes.Length < pos + 2) return 0; - return (ushort)(bytes[pos] + (bytes[pos + 1] << 8)); + if (CanDirectCopyLE) + { + fixed (byte* p = &bytes[pos]) + return *(ushort*)p; + } + else + return (ushort)(bytes[pos] + (bytes[pos + 1] << 8)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static unsafe ushort BytesToUInt16(byte* bytes) { //if (bytes.Length < pos + 2) return 0; - return (ushort)(*bytes + (bytes[1] << 8)); + if (CanDirectCopyLE) + return *(ushort*)bytes; + else + return (ushort)(*bytes + (bytes[1] << 8)); } /// @@ -615,10 +624,16 @@ public static unsafe ushort BytesToUInt16(byte* bytes) /// An unsigned short, will be zero if a ushort can't be /// read [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static ushort BytesToUInt16(byte[] bytes) + public static unsafe ushort BytesToUInt16(byte[] bytes) { //if (bytes.Length < 2) return 0; - return (ushort)(bytes[0] + (bytes[1] << 8)); + if (CanDirectCopyLE) + { + fixed (byte* p = bytes) + return *(ushort*)p; + } + else + return (ushort)(bytes[0] + (bytes[1] << 8)); } /// From 546df888183318ac83201a5ab17cfbfbc2965f3c Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Sun, 28 Nov 2021 17:26:02 +0000 Subject: [PATCH 017/149] cosmetics --- OpenMetaverseTypes/UtilsConversions.cs | 138 ++++++++++++++----------- 1 file changed, 78 insertions(+), 60 deletions(-) diff --git a/OpenMetaverseTypes/UtilsConversions.cs b/OpenMetaverseTypes/UtilsConversions.cs index a66cecc5..17de66d7 100644 --- a/OpenMetaverseTypes/UtilsConversions.cs +++ b/OpenMetaverseTypes/UtilsConversions.cs @@ -109,55 +109,55 @@ static bool CheckDirectCopyBE() "object", // 6 "notecard", // 7 "category", // 8 - String.Empty, // 9 + string.Empty, // 9 "lsltext", // 10 "lslbyte", // 11 "txtr_tga", // 12 "bodypart", // 13 - String.Empty, // 14 - String.Empty, // 15 - String.Empty, // 16 + string.Empty, // 14 + string.Empty, // 15 + string.Empty, // 16 "snd_wav", // 17 "img_tga", // 18 "jpeg", // 19 "animatn", // 20 "gesture", // 21 "simstate", // 22 - String.Empty, // 23 + string.Empty, // 23 "link", // 24 "link_f", // 25 - String.Empty, // 26 - String.Empty, // 27 - String.Empty, // 28 - String.Empty, // 29 - String.Empty, // 30 - String.Empty, // 31 - String.Empty, // 32 - String.Empty, // 33 - String.Empty, // 34 - String.Empty, // 35 - String.Empty, // 36 - String.Empty, // 37 - String.Empty, // 38 - String.Empty, // 39 - String.Empty, // 40 - String.Empty, // 41 - String.Empty, // 42 - String.Empty, // 43 - String.Empty, // 44 - String.Empty, // 45 - String.Empty, // 46 - String.Empty, // 47 - String.Empty, // 48 + string.Empty, // 26 + string.Empty, // 27 + string.Empty, // 28 + string.Empty, // 29 + string.Empty, // 30 + string.Empty, // 31 + string.Empty, // 32 + string.Empty, // 33 + string.Empty, // 34 + string.Empty, // 35 + string.Empty, // 36 + string.Empty, // 37 + string.Empty, // 38 + string.Empty, // 39 + string.Empty, // 40 + string.Empty, // 41 + string.Empty, // 42 + string.Empty, // 43 + string.Empty, // 44 + string.Empty, // 45 + string.Empty, // 46 + string.Empty, // 47 + string.Empty, // 48 "mesh", // 49 - String.Empty, // 50 - String.Empty, // 51 - String.Empty, // 52 - String.Empty, // 53 - String.Empty, // 54 - String.Empty, // 55 + string.Empty, // 50 + string.Empty, // 51 + string.Empty, // 52 + string.Empty, // 53 + string.Empty, // 54 + string.Empty, // 55 "settings", // 56 - String.Empty, // 57 + string.Empty, // 57 }; private static readonly string[] _FolderTypeNames = new string[] @@ -166,27 +166,27 @@ static bool CheckDirectCopyBE() "sound", // 1 "callcard", // 2 "landmark", // 3 - String.Empty, // 4 + string.Empty, // 4 "clothing", // 5 "object", // 6 "notecard", // 7 "root_inv", // 8 - String.Empty, // 9 + string.Empty, // 9 "lsltext", // 10 - String.Empty, // 11 - String.Empty, // 12 + string.Empty, // 11 + string.Empty, // 12 "bodypart", // 13 "trash", // 14 "snapshot", // 15 "lstndfnd", // 16 - String.Empty, // 17 - String.Empty, // 18 - String.Empty, // 19 + string.Empty, // 17 + string.Empty, // 18 + string.Empty, // 19 "animatn", // 20 "gesture", // 21 - String.Empty, // 22 + string.Empty, // 22 "favorite", // 23 - String.Empty, // 24 + string.Empty, // 24 "settings", // 25 "ensemble", // 26 "ensemble", // 27 @@ -225,29 +225,29 @@ static bool CheckDirectCopyBE() "sound", // 1 "callcard", // 2 "landmark", // 3 - String.Empty, // 4 - String.Empty, // 5 + string.Empty, // 4 + string.Empty, // 5 "object", // 6 "notecard", // 7 "category", // 8 "root", // 9 "script", // 10 - String.Empty, // 11 - String.Empty, // 12 - String.Empty, // 13 - String.Empty, // 14 + string.Empty, // 11 + string.Empty, // 12 + string.Empty, // 13 + string.Empty, // 14 "snapshot", // 15 - String.Empty, // 16 + string.Empty, // 16 "attach", // 17 "wearable", // 18 "animation", // 19 "gesture", // 20 - String.Empty, // 21 + string.Empty, // 21 "mesh", // 22 - String.Empty, // 23 - String.Empty, // 24 + string.Empty, // 23 + string.Empty, // 24 "settings", // 25 - String.Empty, // 26 + string.Empty, // 26 }; private static readonly string[] _SaleTypeNames = new string[] @@ -338,6 +338,7 @@ public static bool ApproxEqual(float a, float b, float tolerance, float reltoler return dif <= a * reltolerance; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool ApproxEqual(float a, float b) { float dif = Math.Abs(a - b); @@ -365,10 +366,16 @@ public static int CombineHash(int a, int b) /// A signed short integer, will be zero if a short can't be /// read at the given position [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static short BytesToInt16(byte[] bytes) + public static unsafe short BytesToInt16(byte[] bytes) { //if (bytes.Length < 2 ) return 0; - return (short)(bytes[0] | (bytes[1] << 8)); + if (CanDirectCopyLE) + { + fixed (byte* p = bytes) + return *(short*)p; + } + else + return (short)(bytes[0] | (bytes[1] << 8)); } /// @@ -380,17 +387,28 @@ public static short BytesToInt16(byte[] bytes) /// A signed short integer, will be zero if a short can't be /// read at the given position [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static short BytesToInt16(byte[] bytes, int pos) + public static unsafe short BytesToInt16(byte[] bytes, int pos) { //if (bytes.Length < pos + 2) return 0; - return (short)(bytes[pos] | (bytes[pos + 1] << 8)); + if (CanDirectCopyLE) + { + fixed (byte* p = &bytes[pos]) + return *(short*)p; + } + else + return (short)(bytes[pos] | (bytes[pos + 1] << 8)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static unsafe short BytesToInt16(byte* bytes) { //if (bytes.Length < pos + 2) return 0; - return (short)(*bytes | (bytes[1] << 8)); + if (CanDirectCopyLE) + { + return *(short*)bytes; + } + else + return (short)(*bytes | (bytes[1] << 8)); } /// From e717580a68b47b19b6a20204865b832716314c29 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Wed, 22 Dec 2021 18:33:50 +0000 Subject: [PATCH 018/149] a few xml issues --- OpenMetaverse.StructuredData/LLSD/XmlLLSD.cs | 173 +----------------- OpenMetaverse.Utilities/VoiceManager.cs | 1 + OpenMetaverse/Assets/Archiving/OarFile.cs | 1 + .../Assets/Archiving/RegionSettings.cs | 1 + OpenMetaverse/Assets/AssetTypes/AssetPrim.cs | 1 + Programs/GridProxy/GridProxy.cs | 2 +- 6 files changed, 10 insertions(+), 169 deletions(-) diff --git a/OpenMetaverse.StructuredData/LLSD/XmlLLSD.cs b/OpenMetaverse.StructuredData/LLSD/XmlLLSD.cs index 259bdeda..8f7853e8 100644 --- a/OpenMetaverse.StructuredData/LLSD/XmlLLSD.cs +++ b/OpenMetaverse.StructuredData/LLSD/XmlLLSD.cs @@ -1,5 +1,6 @@ /* * Copyright (c) 2006-2016, openmetaverse.co + * Copyright (c) OpenSimulator Contributors, http://opensimulator.org/ * All rights reserved. * * - Redistribution and use in source and binary forms, with or without @@ -40,11 +41,6 @@ namespace OpenMetaverse.StructuredData /// public static partial class OSDParser { - private static XmlSchema XmlSchema; - private static XmlTextReader XmlTextReader; - private static string LastXmlErrors = String.Empty; - private static object XmlValidationLock = new object(); - /// /// /// @@ -82,6 +78,8 @@ public static OSD DeserializeLLSDXml(string xmlData) /// public static OSD DeserializeLLSDXml(XmlTextReader xmlData) { + xmlData.DtdProcessing = DtdProcessing.Ignore; + try { xmlData.Read(); @@ -581,54 +579,7 @@ public static unsafe void base64Encode(byte[] data, StringBuilder sb) } - /// - /// - /// - /// - /// - /// - public static bool TryValidateLLSDXml(XmlTextReader xmlData, out string error) - { - lock (XmlValidationLock) - { - LastXmlErrors = String.Empty; - XmlTextReader = xmlData; - - CreateLLSDXmlSchema(); - - XmlReaderSettings readerSettings = new XmlReaderSettings(); - readerSettings.ValidationType = ValidationType.Schema; - readerSettings.Schemas.Add(XmlSchema); - readerSettings.ValidationEventHandler += new ValidationEventHandler(LLSDXmlSchemaValidationHandler); - - using(XmlReader reader = XmlReader.Create(xmlData, readerSettings)) - { - - try - { - while (reader.Read()) { } - } - catch (XmlException) - { - error = LastXmlErrors; - return false; - } - - if (LastXmlErrors == String.Empty) - { - error = null; - return true; - } - else - { - error = LastXmlErrors; - return false; - } - } - } - } - - /// + /// /// /// /// @@ -912,120 +863,6 @@ private static void SkipWhitespace(XmlTextReader reader) reader.Read(); } } - - private static void CreateLLSDXmlSchema() - { - if (XmlSchema == null) - { - #region XSD - string schemaText = @" - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -"; - #endregion XSD - - XmlSchema = new XmlSchema(); - using (MemoryStream stream = new MemoryStream(Encoding.ASCII.GetBytes(schemaText))) - XmlSchema = XmlSchema.Read(stream, new ValidationEventHandler(LLSDXmlSchemaValidationHandler)); - } - } - - private static void LLSDXmlSchemaValidationHandler(object sender, ValidationEventArgs args) - { - string error = String.Format("Line: {0} - Position: {1} - {2}", XmlTextReader.LineNumber, XmlTextReader.LinePosition, - args.Message); - - if (LastXmlErrors == String.Empty) - LastXmlErrors = error; - else - LastXmlErrors += Environment.NewLine + error; - } } } + diff --git a/OpenMetaverse.Utilities/VoiceManager.cs b/OpenMetaverse.Utilities/VoiceManager.cs index 226fda6e..ac5681ce 100644 --- a/OpenMetaverse.Utilities/VoiceManager.cs +++ b/OpenMetaverse.Utilities/VoiceManager.cs @@ -584,6 +584,7 @@ private void _DaemonPipe_OnDisconnected(SocketException se) private void _DaemonPipe_OnReceiveLine(string line) { XmlTextReader reader = new XmlTextReader(new StringReader(line)); + reader.DtdProcessing = DtdProcessing.Ignore; while (reader.Read()) { diff --git a/OpenMetaverse/Assets/Archiving/OarFile.cs b/OpenMetaverse/Assets/Archiving/OarFile.cs index 0cbaa790..856604f3 100644 --- a/OpenMetaverse/Assets/Archiving/OarFile.cs +++ b/OpenMetaverse/Assets/Archiving/OarFile.cs @@ -268,6 +268,7 @@ public static void LoadObjects(byte[] objectData, SceneObjectLoadedCallback obje using (XmlTextReader reader = new XmlTextReader(new MemoryStream(objectData))) { + reader.DtdProcessing = DtdProcessing.Ignore; reader.WhitespaceHandling = WhitespaceHandling.None; doc.Load(reader); } diff --git a/OpenMetaverse/Assets/Archiving/RegionSettings.cs b/OpenMetaverse/Assets/Archiving/RegionSettings.cs index 24a976b9..cbf848da 100644 --- a/OpenMetaverse/Assets/Archiving/RegionSettings.cs +++ b/OpenMetaverse/Assets/Archiving/RegionSettings.cs @@ -46,6 +46,7 @@ public static RegionSettings FromStream(Stream stream) using (XmlTextReader xtr = new XmlTextReader(stream)) { + xtr.DtdProcessing = DtdProcessing.Ignore; xtr.ReadStartElement("RegionSettings"); xtr.ReadStartElement("General"); diff --git a/OpenMetaverse/Assets/AssetTypes/AssetPrim.cs b/OpenMetaverse/Assets/AssetTypes/AssetPrim.cs index b17c2ea8..98bc2596 100644 --- a/OpenMetaverse/Assets/AssetTypes/AssetPrim.cs +++ b/OpenMetaverse/Assets/AssetTypes/AssetPrim.cs @@ -124,6 +124,7 @@ public bool DecodeXml(string xmlData) { using (XmlTextReader reader = new XmlTextReader(new StringReader(xmlData))) { + reader.DtdProcessing = DtdProcessing.Ignore; reader.Read(); reader.ReadStartElement("SceneObjectGroup"); Parent = LoadPrim(reader); diff --git a/Programs/GridProxy/GridProxy.cs b/Programs/GridProxy/GridProxy.cs index cae9b5c5..1c4efb54 100644 --- a/Programs/GridProxy/GridProxy.cs +++ b/Programs/GridProxy/GridProxy.cs @@ -585,7 +585,7 @@ private void ProxyHTTP(Socket client) if (uri == "/") { headers["method"] = meth; - if (contentType == "application/xml+llsd" || contentType == "application/xml") + if (contentType == "application/llsd+xml" || contentType == "application/xml+llsd" || contentType == "application/xml") { ProxyLoginSD(netStream, content); } From 52eb7ed0d4324056f1666b31a0327260e3188f63 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Tue, 4 Jan 2022 16:09:37 +0000 Subject: [PATCH 019/149] add some speedups for FetchInventoryDescendents to llsdencode --- .../LLSD/LLSDxmlEncode.cs | 87 +++++++++++++++++++ OpenMetaverseTypes/OSUTF8Constants.cs | 23 +++++ 2 files changed, 110 insertions(+) diff --git a/OpenMetaverse.StructuredData/LLSD/LLSDxmlEncode.cs b/OpenMetaverse.StructuredData/LLSD/LLSDxmlEncode.cs index 26db742f..63c26715 100644 --- a/OpenMetaverse.StructuredData/LLSD/LLSDxmlEncode.cs +++ b/OpenMetaverse.StructuredData/LLSD/LLSDxmlEncode.cs @@ -856,6 +856,93 @@ public static void AddElem_folder_id(UUID e, osUTF8 sb) } } + public static void AddElem_asset_id(UUID e, osUTF8 sb) + { + if (e == UUID.Zero) + sb.Append(osUTF8Const.XMLelement_asset_id_Empty); + else + { + sb.Append(osUTF8Const.XMLelement_asset_id_Start); + sb.AppendUUID(e); + sb.Append(osUTF8Const.XMLuuidEnd); + } + } + + public static void AddElem_item_id(UUID e, osUTF8 sb) + { + if (e == UUID.Zero) + sb.Append(osUTF8Const.XMLelement_item_id_Empty); + else + { + sb.Append(osUTF8Const.XMLelement_item_id_Start); + sb.AppendUUID(e); + sb.Append(osUTF8Const.XMLuuidEnd); + } + } + + public static void AddElem_category_id(UUID e, osUTF8 sb) + { + if (e == UUID.Zero) + sb.Append(osUTF8Const.XMLelement_category_id_Empty); + else + { + sb.Append(osUTF8Const.XMLelement_category_id_Start); + sb.AppendUUID(e); + sb.Append(osUTF8Const.XMLuuidEnd); + } + } + + public static void AddElem_creator_id(UUID e, osUTF8 sb) + { + if (e == UUID.Zero) + sb.Append(osUTF8Const.XMLelement_creator_id_Empty); + else + { + sb.Append(osUTF8Const.XMLelement_creator_id_Start); + sb.AppendUUID(e); + sb.Append(osUTF8Const.XMLuuidEnd); + } + } + + public static void AddElem_group_id(UUID e, osUTF8 sb) + { + if (e == UUID.Zero) + sb.Append(osUTF8Const.XMLelement_group_id_Empty); + else + { + sb.Append(osUTF8Const.XMLelement_group_id_Start); + sb.AppendUUID(e); + sb.Append(osUTF8Const.XMLuuidEnd); + } + } + + public static void AddElem_version(int v, osUTF8 sb) + { + if (v == 0) + sb.Append(osUTF8Const.XMLelement_version_Empty); + else + { + sb.Append(osUTF8Const.XMLelement_version_Start); + sb.AppendInt(v); + sb.Append(osUTF8Const.XMLintegerEnd); + } + } + + public static void AddElem_sale_info(int price, byte type, osUTF8 sb) + { + if(price == 0 && type == 0) + sb.Append(osUTF8Const.XMLelement_sale_info_Empty); + else + { + sb.Append(osUTF8Const.XMLelement_sale_info_Start); + sb.AppendInt(price); + sb.Append(osUTF8Const.XMLelement_sale_info_Mid); + sb.AppendInt(type); + sb.Append(osUTF8Const.XMLelement_sale_info_End); + } + } + + public static byte[] ulongToByteArray(ulong uLongValue) { return new byte[8] diff --git a/OpenMetaverseTypes/OSUTF8Constants.cs b/OpenMetaverseTypes/OSUTF8Constants.cs index 36cc94e5..7b4a0f57 100644 --- a/OpenMetaverseTypes/OSUTF8Constants.cs +++ b/OpenMetaverseTypes/OSUTF8Constants.cs @@ -101,12 +101,35 @@ public static class osUTF8Const public static readonly byte[] XMLelement_owner_id_Empty = osUTF8.GetASCIIBytes("owner_id"); public static readonly byte[] XMLelement_owner_id_Start = osUTF8.GetASCIIBytes("owner_id"); + public static readonly byte[] XMLelement_creator_id_Empty = osUTF8.GetASCIIBytes("creator_id"); + public static readonly byte[] XMLelement_creator_id_Start = osUTF8.GetASCIIBytes("creator_id"); + + public static readonly byte[] XMLelement_group_id_Empty = osUTF8.GetASCIIBytes("group_id"); + public static readonly byte[] XMLelement_group_id_Start = osUTF8.GetASCIIBytes("cgroup_id"); + public static readonly byte[] XMLelement_parent_id_Empty = osUTF8.GetASCIIBytes("parent_id"); public static readonly byte[] XMLelement_parent_id_Start = osUTF8.GetASCIIBytes("parent_id"); public static readonly byte[] XMLelement_folder_id_Empty = osUTF8.GetASCIIBytes("folder_id"); public static readonly byte[] XMLelement_folder_id_Start = osUTF8.GetASCIIBytes("folder_id"); + public static readonly byte[] XMLelement_asset_id_Empty = osUTF8.GetASCIIBytes("asset_id"); + public static readonly byte[] XMLelement_asset_id_Start = osUTF8.GetASCIIBytes("asset_id"); + + public static readonly byte[] XMLelement_item_id_Empty = osUTF8.GetASCIIBytes("item_id"); + public static readonly byte[] XMLelement_item_id_Start = osUTF8.GetASCIIBytes("item_id"); + + public static readonly byte[] XMLelement_category_id_Empty = osUTF8.GetASCIIBytes("category_id"); + public static readonly byte[] XMLelement_category_id_Start = osUTF8.GetASCIIBytes("category_id"); + + public static readonly byte[] XMLelement_version_Empty = osUTF8.GetASCIIBytes("version"); + public static readonly byte[] XMLelement_version_Start = osUTF8.GetASCIIBytes("version"); + + public static readonly byte[] XMLelement_sale_info_Empty = osUTF8.GetASCIIBytes("sale_infosale_pricesale_type"); + public static readonly byte[] XMLelement_sale_info_Start = osUTF8.GetASCIIBytes("sale_infosale_price"); + public static readonly byte[] XMLelement_sale_info_Mid = osUTF8.GetASCIIBytes("sale_type"); + public static readonly byte[] XMLelement_sale_info_End = osUTF8.GetASCIIBytes(""); + public static readonly byte[] base64Bytes = {(byte)'A',(byte)'B',(byte)'C',(byte)'D',(byte)'E',(byte)'F',(byte)'G',(byte)'H',(byte)'I',(byte)'J',(byte)'K',(byte)'L',(byte)'M',(byte)'N',(byte)'O', (byte)'P',(byte)'Q',(byte)'R',(byte)'S',(byte)'T',(byte)'U',(byte)'V',(byte)'W',(byte)'X',(byte)'Y',(byte)'Z',(byte)'a',(byte)'b',(byte)'c',(byte)'d', (byte)'e',(byte)'f',(byte)'g',(byte)'h',(byte)'i',(byte)'j',(byte)'k',(byte)'l',(byte)'m',(byte)'n',(byte)'o',(byte)'p',(byte)'q',(byte)'r',(byte)'s', From 15f99768642a60cb9ee299f7fcf6f02c6576bddb Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Sat, 8 Jan 2022 19:12:36 +0000 Subject: [PATCH 020/149] change UUID --- OpenMetaverse.StructuredData/JSON/OSDJson.cs | 2 +- .../LLSD/LLSDxmlEncode.cs | 22 +- .../StructuredData.cs | 4 +- OpenMetaverseTypes/OSUTF8.cs | 4 +- OpenMetaverseTypes/UUID.cs | 394 +++++++++++++----- OpenMetaverseTypes/UtilsConversions.cs | 305 +++++++++++--- 6 files changed, 551 insertions(+), 180 deletions(-) diff --git a/OpenMetaverse.StructuredData/JSON/OSDJson.cs b/OpenMetaverse.StructuredData/JSON/OSDJson.cs index 7f69274e..ceae0938 100644 --- a/OpenMetaverse.StructuredData/JSON/OSDJson.cs +++ b/OpenMetaverse.StructuredData/JSON/OSDJson.cs @@ -170,7 +170,7 @@ private static JsonData SerializeJsonNoDefaults(OSD osd) return new JsonData(str); case OSDType.UUID: UUID uuid = osd.AsUUID(); - if (uuid == UUID.Zero) + if (uuid.IsZero()) return null; return new JsonData(uuid.ToString()); diff --git a/OpenMetaverse.StructuredData/LLSD/LLSDxmlEncode.cs b/OpenMetaverse.StructuredData/LLSD/LLSDxmlEncode.cs index 63c26715..122c7480 100644 --- a/OpenMetaverse.StructuredData/LLSD/LLSDxmlEncode.cs +++ b/OpenMetaverse.StructuredData/LLSD/LLSDxmlEncode.cs @@ -315,7 +315,7 @@ public static void AddElem(double e, osUTF8 sb) public static void AddElem(UUID e, osUTF8 sb) { - if(e == UUID.Zero) + if(e.IsZero()) sb.Append(osUTF8Const.XMLuuidEmpty); else { @@ -678,7 +678,7 @@ public static void AddElem(string name, UUID e, osUTF8 sb) sb.AppendASCII(name); sb.Append(osUTF8Const.XMLkeyEnd); - if (e == UUID.Zero) + if (e.IsZero()) sb.Append(osUTF8Const.XMLuuidEmpty); else { @@ -810,7 +810,7 @@ public static void AddElem_name(string s, osUTF8 sb) public static void AddElem_agent_id(UUID e, osUTF8 sb) { - if (e == UUID.Zero) + if (e.IsZero()) sb.Append(osUTF8Const.XMLelement_agent_id_Empty); else { @@ -822,7 +822,7 @@ public static void AddElem_agent_id(UUID e, osUTF8 sb) public static void AddElem_owner_id(UUID e, osUTF8 sb) { - if (e == UUID.Zero) + if (e.IsZero()) sb.Append(osUTF8Const.XMLelement_owner_id_Empty); else { @@ -834,7 +834,7 @@ public static void AddElem_owner_id(UUID e, osUTF8 sb) public static void AddElem_parent_id(UUID e, osUTF8 sb) { - if (e == UUID.Zero) + if (e.IsZero()) sb.Append(osUTF8Const.XMLelement_parent_id_Empty); else { @@ -846,7 +846,7 @@ public static void AddElem_parent_id(UUID e, osUTF8 sb) public static void AddElem_folder_id(UUID e, osUTF8 sb) { - if (e == UUID.Zero) + if (e.IsZero()) sb.Append(osUTF8Const.XMLelement_folder_id_Empty); else { @@ -858,7 +858,7 @@ public static void AddElem_folder_id(UUID e, osUTF8 sb) public static void AddElem_asset_id(UUID e, osUTF8 sb) { - if (e == UUID.Zero) + if (e.IsZero()) sb.Append(osUTF8Const.XMLelement_asset_id_Empty); else { @@ -870,7 +870,7 @@ public static void AddElem_asset_id(UUID e, osUTF8 sb) public static void AddElem_item_id(UUID e, osUTF8 sb) { - if (e == UUID.Zero) + if (e.IsZero()) sb.Append(osUTF8Const.XMLelement_item_id_Empty); else { @@ -882,7 +882,7 @@ public static void AddElem_item_id(UUID e, osUTF8 sb) public static void AddElem_category_id(UUID e, osUTF8 sb) { - if (e == UUID.Zero) + if (e.IsZero()) sb.Append(osUTF8Const.XMLelement_category_id_Empty); else { @@ -894,7 +894,7 @@ public static void AddElem_category_id(UUID e, osUTF8 sb) public static void AddElem_creator_id(UUID e, osUTF8 sb) { - if (e == UUID.Zero) + if (e.IsZero()) sb.Append(osUTF8Const.XMLelement_creator_id_Empty); else { @@ -906,7 +906,7 @@ public static void AddElem_creator_id(UUID e, osUTF8 sb) public static void AddElem_group_id(UUID e, osUTF8 sb) { - if (e == UUID.Zero) + if (e.IsZero()) sb.Append(osUTF8Const.XMLelement_group_id_Empty); else { diff --git a/OpenMetaverse.StructuredData/StructuredData.cs b/OpenMetaverse.StructuredData/StructuredData.cs index 96e0af36..49cc136a 100644 --- a/OpenMetaverse.StructuredData/StructuredData.cs +++ b/OpenMetaverse.StructuredData/StructuredData.cs @@ -109,7 +109,7 @@ public virtual bool AsBoolean() return false; return true; case OSDType.UUID: - return (((OSDUUID)this).value == UUID.Zero) ? false : true; + return (((OSDUUID)this).value.IsZero()) ? false : true; case OSDType.Map: return ((OSDMap)this).dicvalue.Count > 0; case OSDType.Array: @@ -1453,7 +1453,7 @@ public OSDUUID(UUID value) } public override OSD Copy() { return new OSDUUID(value); } - public override bool AsBoolean() { return (value == UUID.Zero) ? false : true; } + public override bool AsBoolean() { return (value.IsZero()) ? false : true; } public override string AsString() { return value.ToString(); } public override UUID AsUUID() { return value; } public override byte[] AsBinary() { return value.GetBytes(); } diff --git a/OpenMetaverseTypes/OSUTF8.cs b/OpenMetaverseTypes/OSUTF8.cs index 1cc7ecf0..7bfac0e4 100644 --- a/OpenMetaverseTypes/OSUTF8.cs +++ b/OpenMetaverseTypes/OSUTF8.cs @@ -499,6 +499,7 @@ public unsafe void AppendInt(long v) m_len += Utils.LongToByteString(v, d + m_len); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe void AppendInt(ulong v) { CheckCapacity(32); @@ -506,11 +507,12 @@ public unsafe void AppendInt(ulong v) m_len += Utils.ULongToByteString(v, d + m_len); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe void AppendUUID(UUID u) { CheckCapacity(36); fixed (byte* d = m_data) - Utils.UUIDToByteDashString(u, d + m_len); + Utils.UUIDToByteDashString(ref u, d + m_len); m_len += 36; } diff --git a/OpenMetaverseTypes/UUID.cs b/OpenMetaverseTypes/UUID.cs index 91f513eb..c5113b52 100644 --- a/OpenMetaverseTypes/UUID.cs +++ b/OpenMetaverseTypes/UUID.cs @@ -25,18 +25,54 @@ */ using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; namespace OpenMetaverse { /// - /// A 128-bit Universally Unique Identifier, used throughout the Second - /// Life networking protocol + /// A 128-bit Universally Unique Identifier + /// Only diference from Guid is on to and from bytes, where it uses network byte order unlike Guid /// + + [StructLayout(LayoutKind.Explicit)] [Serializable] - public struct UUID : IComparable, IEquatable + public struct UUID : IComparable,IComparable, IEquatable { - /// The System.Guid object this struct wraps around - public Guid Guid; + // still a big piece of *** because how stupid .net structs are. + // .net5 unsafe may remove the need for this union + [FieldOffset(0)] public int a; + [FieldOffset(4)] public short b; + [FieldOffset(6)] public short c; + + [FieldOffset(8)] public byte d; + [FieldOffset(9)] public byte e; + [FieldOffset(10)] public byte f; + [FieldOffset(11)] public byte g; + [FieldOffset(12)] public byte h; + [FieldOffset(13)] public byte i; + [FieldOffset(14)] public byte j; + [FieldOffset(15)] public byte k; + + [FieldOffset(0)] public byte bytea0; + [FieldOffset(1)] public byte bytea1; + [FieldOffset(2)] public byte bytea2; + [FieldOffset(3)] public byte bytea3; + + [FieldOffset(4)] public byte byteb0; + [FieldOffset(5)] public byte byteb1; + + [FieldOffset(6)] public byte bytec0; + [FieldOffset(7)] public byte bytec1; + + [FieldOffset(4)] public int intb; + [FieldOffset(8)] public int intc; + [FieldOffset(12)] public int intd; + + [FieldOffset(0)] public ulong ulonga; + [FieldOffset(8)] public ulong ulongb; + + [FieldOffset(0)] public Guid Guid; #region Constructors @@ -46,12 +82,22 @@ public struct UUID : IComparable, IEquatable /// A string representation of a UUID, case /// insensitive and can either be hyphenated or non-hyphenated /// UUID("11f8aa9c-b071-4242-836b-13b7abe0d489") - public UUID(string val) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe UUID(string val) { - if (String.IsNullOrEmpty(val)) - Guid = new Guid(); - else - Guid = new Guid(val); + if (!string.IsNullOrEmpty(val)) + { + try + { + if (Guid.TryParse(val, out Guid gg)) + { + this = *(UUID *) ≫ + return; + } + } + catch { } + } + this = new UUID(); } /// @@ -59,9 +105,17 @@ public UUID(string val) /// /// A Guid object that contains the unique identifier /// to be represented by this UUID - public UUID(Guid val) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe UUID(Guid val) { - Guid = val; + this = *(UUID*)&val; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe UUID(ulong _la, ulong _lb) : this() + { + ulonga = _la; + ulongb = _lb; } /// @@ -69,10 +123,26 @@ public UUID(Guid val) /// /// Byte array containing a 16 byte UUID /// Beginning offset in the array - public UUID(byte[] source, int pos) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe UUID(byte[] source, int pos) : this() { - Guid = UUID.Zero.Guid; - FromBytes(source, pos); + if (BitConverter.IsLittleEndian) + { + bytea3 = source[pos + 0]; + bytea2 = source[pos + 1]; + bytea1 = source[pos + 2]; + bytea0 = source[pos + 3]; + + byteb1 = source[pos + 4]; + byteb0 = source[pos + 5]; + + bytec1 = source[pos + 6]; + bytec0 = source[pos + 7]; + } + else + ulonga = Utils.BytesToUInt64(source, pos); + + ulongb = Utils.BytesToUInt64(source, pos + 8); } /// @@ -80,13 +150,22 @@ public UUID(byte[] source, int pos) /// convert to a UUID /// /// 64-bit unsigned integer to convert to a UUID - public UUID(ulong val) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public UUID(ulong val) : this() { - byte[] end = BitConverter.GetBytes(val); - if (!BitConverter.IsLittleEndian) - Array.Reverse(end); - - Guid = new Guid(0, 0, 0, end); + if(BitConverter.IsLittleEndian) + ulongb = val; + else + { + d = (byte)val; + e = (byte)(val >> 8); + f = (byte)(val >> 16); + g = (byte)(val >> 24); + h = (byte)(val >> 32); + i = (byte)(val >> 40); + j = (byte)(val >> 48); + k = (byte)(val >> 56); + } } /// @@ -95,7 +174,7 @@ public UUID(ulong val) /// UUID to copy public UUID(UUID val) { - Guid = val.Guid; + this = val; } #endregion Constructors @@ -105,9 +184,65 @@ public UUID(UUID val) /// /// IComparable.CompareTo implementation /// + public int CompareTo(object val) + { + if(val == null) + return 1; + + UUID id = (UUID)val; + + if (id.a != a) + return (uint)id.a > (uint)a ? -1 : 1; + if (id.b != b) + return (uint)id.b > (uint)b ? -1 : 1; + if (id.c != c) + return (uint)id.c > (uint)c ? -1 : 1; + + if (id.d != d) + return id.d > d ? -1 : 1; + if (id.e != e) + return id.e > e ? -1 : 1; + if (id.f != f) + return id.f > f ? -1 : 1; + if (id.g != g) + return id.g > g ? -1 : 1; + if (id.h != h) + return id.h > h ? -1 : 1; + if (id.i != i) + return id.i > i ? -1 : 1; + if (id.j != j) + return id.j > j ? -1 : 1; + if (id.k != k) + return id.k > k ? -1 : 1; + return 0; + } + public int CompareTo(UUID id) { - return Guid.CompareTo(id.Guid); + if (id.a != a) + return (uint)id.a > (uint)a ? -1 : 1; + if (id.b != b) + return (uint)id.b > (uint)b ? -1 : 1; + if (id.c != c) + return (uint)id.c > (uint)c ? -1 : 1; + + if (id.d != d) + return id.d > d ? -1 : 1; + if (id.e != e) + return id.e > e ? -1 : 1; + if (id.f != f) + return id.f > f ? -1 : 1; + if (id.g != g) + return id.g > g ? -1 : 1; + if (id.h != h) + return id.h > h ? -1 : 1; + if (id.i != i) + return id.i > i ? -1 : 1; + if (id.j != j) + return id.j > j ? -1 : 1; + if (id.k != k) + return id.k > k ? -1 : 1; + return 0; } /// @@ -115,25 +250,54 @@ public int CompareTo(UUID id) /// /// Byte array containing the UUID to assign this UUID to /// Starting position of the UUID in the byte array - public void FromBytes(byte[] source, int pos) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe void FromBytes(byte[] source, int pos) { - int a = (source[pos + 0] << 24) | (source[pos + 1] << 16) | (source[pos + 2] << 8) | source[pos + 3]; - short b = (short)((source[pos + 4] << 8) | source[pos + 5]); - short c = (short)((source[pos + 6] << 8) | source[pos + 7]); + if (BitConverter.IsLittleEndian) + { + bytea3 = source[pos + 0]; + bytea2 = source[pos + 1]; + bytea1 = source[pos + 2]; + bytea0 = source[pos + 3]; + + byteb1 = source[pos + 4]; + byteb0 = source[pos + 5]; - Guid = new Guid(a, b, c, source[pos + 8], source[pos + 9], source[pos + 10], source[pos + 11], - source[pos + 12], source[pos + 13], source[pos + 14], source[pos + 15]); + bytec1 = source[pos + 6]; + bytec0 = source[pos + 7]; + } + else + ulonga = Utils.BytesToUInt64(source, pos); + + ulongb = Utils.BytesToUInt64(source, pos + 8); } /// /// Returns a copy of the raw bytes for this UUID /// /// A 16 byte array containing this UUID + [MethodImpl(MethodImplOptions.AggressiveInlining)] public byte[] GetBytes() { - byte[] output = new byte[16]; - ToBytes(output, 0); - return output; + byte[] dest = new byte[16]; + if (BitConverter.IsLittleEndian) + { + dest[0] = bytea3; + dest[1] = bytea2; + dest[2] = bytea1; + dest[3] = bytea0; + + dest[4] = byteb1; + dest[5] = byteb0; + + dest[6] = bytec1; + dest[7] = bytec0; + } + else + Utils.UInt64ToBytesSafepos(ulonga, dest, 0); + + Utils.UInt64ToBytesSafepos(ulongb, dest, 8); + return dest; } /// @@ -142,35 +306,44 @@ public byte[] GetBytes() /// Destination byte array /// Position in the destination array to start /// writing. Must be at least 16 bytes before the end of the array + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ToBytes(byte[] dest, int pos) { - byte[] bytes = Guid.ToByteArray(); - dest[pos + 0] = bytes[3]; - dest[pos + 1] = bytes[2]; - dest[pos + 2] = bytes[1]; - dest[pos + 3] = bytes[0]; - dest[pos + 4] = bytes[5]; - dest[pos + 5] = bytes[4]; - dest[pos + 6] = bytes[7]; - dest[pos + 7] = bytes[6]; - Buffer.BlockCopy(bytes, 8, dest, pos + 8, 8); + if (BitConverter.IsLittleEndian) + { + dest[pos + 0] = bytea3; + dest[pos + 1] = bytea2; + dest[pos + 2] = bytea1; + dest[pos + 3] = bytea0; + dest[pos + 4] = byteb1; + dest[pos + 5] = byteb0; + dest[pos + 6] = bytec1; + dest[pos + 7] = bytec0; + } + else + Utils.UInt64ToBytesSafepos(ulonga, dest, pos); + + Utils.UInt64ToBytesSafepos(ulongb, dest, pos + 8); } /// /// Calculate an LLCRC (cyclic redundancy check) for this UUID /// /// The CRC checksum for this UUID + [MethodImpl(MethodImplOptions.AggressiveInlining)] public uint CRC() { - uint retval = 0; - byte[] bytes = GetBytes(); - - retval += (uint)((bytes[3] << 24) + (bytes[2] << 16) + (bytes[1] << 8) + bytes[0]); - retval += (uint)((bytes[7] << 24) + (bytes[6] << 16) + (bytes[5] << 8) + bytes[4]); - retval += (uint)((bytes[11] << 24) + (bytes[10] << 16) + (bytes[9] << 8) + bytes[8]); - retval += (uint)((bytes[15] << 24) + (bytes[14] << 16) + (bytes[13] << 8) + bytes[12]); + return (uint)a + (uint)intb + (uint)intc + (uint)intd; + } - return retval; + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool IsZero() + { + if (ulonga != 0) + return false; + if (ulongb != 0) + return false; + return true; } /// @@ -179,17 +352,17 @@ public uint CRC() /// An integer created from the last eight bytes of this UUID public ulong GetULong() { - byte[] bytes = Guid.ToByteArray(); - - return (ulong) - ((ulong)bytes[8] + - ((ulong)bytes[9] << 8) + - ((ulong)bytes[10] << 16) + - ((ulong)bytes[12] << 24) + - ((ulong)bytes[13] << 32) + - ((ulong)bytes[13] << 40) + - ((ulong)bytes[14] << 48) + - ((ulong)bytes[15] << 56)); + if(BitConverter.IsLittleEndian) + return ulongb; + else + return d + + ((ulong)e << 8) + + ((ulong)f << 16) + + ((ulong)g << 24) + + ((ulong)h << 32) + + ((ulong)i << 40) + + ((ulong)j << 48) + + ((ulong)k << 56); } #endregion Public Methods @@ -204,7 +377,8 @@ public ulong GetULong() /// UUID.Parse("11f8aa9c-b071-4242-836b-13b7abe0d489") public static UUID Parse(string val) { - return new UUID(val); + Guid gg = Guid.Parse(val); + return new UUID(gg); } /// @@ -218,24 +392,19 @@ public static UUID Parse(string val) /// UUID.TryParse("11f8aa9c-b071-4242-836b-13b7abe0d489", result) public static bool TryParse(string val, out UUID result) { - if (String.IsNullOrEmpty(val)) + if (!string.IsNullOrEmpty(val)) { - result = UUID.Zero; - return false; - } - - Guid gg; - try - { - if(Guid.TryParse(val, out gg)) + try { - result = new UUID(gg); - return true; + if (Guid.TryParse(val, out Guid gg)) + { + result = new UUID(gg); + return true; + } } + catch { } } - catch { } - - result = UUID.Zero; + result = new UUID(); return false; } @@ -260,9 +429,11 @@ public static UUID Combine(UUID first, UUID second) /// /// /// - public static UUID Random() + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static UUID Random() { - return new UUID(Guid.NewGuid()); + Guid g = Guid.NewGuid(); + return *(UUID*)&g; } #endregion Static Methods @@ -273,9 +444,10 @@ public static UUID Random() /// Return a hash code for this UUID, used by .NET for hash tables /// /// An integer composed of all the UUID bytes XORed together + [MethodImpl(MethodImplOptions.AggressiveInlining)] public override int GetHashCode() { - return Guid.GetHashCode(); + return a ^ intb ^ intc ^ intd; } /// @@ -283,12 +455,18 @@ public override int GetHashCode() /// /// An object to compare to this UUID /// True if the object is a UUID and both UUIDs are equal + [MethodImpl(MethodImplOptions.AggressiveInlining)] public override bool Equals(object o) { - if (!(o is UUID)) return false; + if (!(o is UUID)) + return false; UUID uuid = (UUID)o; - return Guid == uuid.Guid; + if (ulonga != uuid.ulonga) + return false; + if (ulongb != uuid.ulongb) + return false; + return true; } /// @@ -296,9 +474,24 @@ public override bool Equals(object o) /// /// UUID to compare to /// True if the UUIDs are equal, otherwise false + [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool Equals(UUID uuid) { - return Guid == uuid.Guid; + if (ulonga != uuid.ulonga) + return false; + if (ulongb != uuid.ulongb) + return false; + return true; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool NotEqual(UUID uuid) + { + if (ulonga != uuid.ulonga) + return true; + if (ulongb != uuid.ulongb) + return true; + return false; } /// @@ -307,12 +500,11 @@ public bool Equals(UUID uuid) /// A string representation of this UUID, lowercase and /// with hyphens /// 11f8aa9c-b071-4242-836b-13b7abe0d489 + + [MethodImpl(MethodImplOptions.AggressiveInlining)] public override string ToString() { - if (Guid == Guid.Empty) - return ZeroString; - else - return Guid.ToString(); + return Utils.UUIDToDashString(ref this); } #endregion Overrides @@ -325,9 +517,14 @@ public override string ToString() /// First UUID for comparison /// Second UUID for comparison /// True if the UUIDs are byte for byte equal, otherwise false + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool operator ==(UUID lhs, UUID rhs) { - return lhs.Guid == rhs.Guid; + if (lhs.ulonga != rhs.ulonga) + return false; + if (lhs.ulongb != rhs.ulongb) + return false; + return true; } /// @@ -336,9 +533,14 @@ public override string ToString() /// First UUID for comparison /// Second UUID for comparison /// True if the UUIDs are not equal, otherwise true + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool operator !=(UUID lhs, UUID rhs) { - return !(lhs == rhs); + if (lhs.ulonga != rhs.ulonga) + return true; + if (lhs.ulongb != rhs.ulongb) + return true; + return false; } /// @@ -349,16 +551,10 @@ public override string ToString() /// A UUID that is a XOR combination of the two input UUIDs public static UUID operator ^(UUID lhs, UUID rhs) { - byte[] lhsbytes = lhs.GetBytes(); - byte[] rhsbytes = rhs.GetBytes(); - byte[] output = new byte[16]; - - for (int i = 0; i < 16; i++) - { - output[i] = (byte)(lhsbytes[i] ^ rhsbytes[i]); - } - - return new UUID(output, 0); + UUID ret = new UUID(); + ret.ulonga = lhs.ulonga ^ rhs.ulonga; + ret.ulongb = lhs.ulongb ^ rhs.ulongb; + return ret; } /// @@ -378,6 +574,6 @@ public static explicit operator UUID(string val) public static readonly UUID Zero = new UUID(); /// A cache of UUID.Zero as a string to optimize a common path - private static readonly string ZeroString = Guid.Empty.ToString(); + public static readonly string ZeroString = "00000000-0000-0000-0000-000000000000"; } } diff --git a/OpenMetaverseTypes/UtilsConversions.cs b/OpenMetaverseTypes/UtilsConversions.cs index 17de66d7..e4f9bf2f 100644 --- a/OpenMetaverseTypes/UtilsConversions.cs +++ b/OpenMetaverseTypes/UtilsConversions.cs @@ -2803,71 +2803,109 @@ public static byte HighNibbleToHexByteChar(byte b) return (byte)(b > 9 ? b + 0x57 : b + ASCIIzero); } - public static unsafe void UUIDToByteDashString(UUID u, byte* dst) - { - byte[] bytes = u.Guid.ToByteArray(); - //a - byte b = bytes[3]; - *dst++ = HighNibbleToHexByteChar(b); - *dst++ = LowNibbleToHexByteChar(b); - b = bytes[2]; - *dst++ = HighNibbleToHexByteChar(b); - *dst++ = LowNibbleToHexByteChar(b); - b = bytes[1]; - *dst++ = HighNibbleToHexByteChar(b); - *dst++ = LowNibbleToHexByteChar(b); - b = bytes[0]; - *dst++ = HighNibbleToHexByteChar(b); - *dst++ = LowNibbleToHexByteChar(b); - - *dst++ = ASCIIminus; - //b - b = bytes[5]; - *dst++ = HighNibbleToHexByteChar(b); - *dst++ = LowNibbleToHexByteChar(b); - b = bytes[4]; - *dst++ = HighNibbleToHexByteChar(b); - *dst++ = LowNibbleToHexByteChar(b); - - *dst++ = ASCIIminus; - - //c - b = bytes[7]; - *dst++ = HighNibbleToHexByteChar(b); - *dst++ = LowNibbleToHexByteChar(b); - b = bytes[6]; - *dst++ = HighNibbleToHexByteChar(b); - *dst++ = LowNibbleToHexByteChar(b); - - *dst++ = ASCIIminus; - - b = bytes[8]; //d - *dst++ = HighNibbleToHexByteChar(b); - *dst++ = LowNibbleToHexByteChar(b); - b = bytes[9]; //e - *dst++ = HighNibbleToHexByteChar(b); - *dst++ = LowNibbleToHexByteChar(b); - - *dst++ = ASCIIminus; - - b = bytes[10]; //f - *dst++ = HighNibbleToHexByteChar(b); - *dst++ = LowNibbleToHexByteChar(b); - b = bytes[11]; //g - *dst++ = HighNibbleToHexByteChar(b); - *dst++ = LowNibbleToHexByteChar(b); - b = bytes[12]; //h - *dst++ = HighNibbleToHexByteChar(b); - *dst++ = LowNibbleToHexByteChar(b); - b = bytes[13]; //i - *dst++ = HighNibbleToHexByteChar(b); - *dst++ = LowNibbleToHexByteChar(b); - b = bytes[14]; //j - *dst++ = HighNibbleToHexByteChar(b); - *dst++ = LowNibbleToHexByteChar(b); - b = bytes[15]; //k - *dst++ = HighNibbleToHexByteChar(b); - *dst = LowNibbleToHexByteChar(b); + public static unsafe void UUIDToByteDashString(ref UUID u, byte* dst) + { + byte b; + if (BitConverter.IsLittleEndian) + { + //a + b = u.bytea3; + *dst = HighNibbleToHexByteChar(b); + *(dst + 1) = LowNibbleToHexByteChar(b); + b = u.bytea2; + *(dst + 2) = HighNibbleToHexByteChar(b); + *(dst + 3) = LowNibbleToHexByteChar(b); + b = u.bytea1; + *(dst + 4) = HighNibbleToHexByteChar(b); + *(dst + 5) = LowNibbleToHexByteChar(b); + b = u.bytea0; + *(dst + 6) = HighNibbleToHexByteChar(b); + *(dst + 7) = LowNibbleToHexByteChar(b); + + *(dst + 8) = ASCIIminus; + //b + b = u.byteb1; + *(dst + 9) = HighNibbleToHexByteChar(b); + *(dst + 10) = LowNibbleToHexByteChar(b); + b = u.byteb0; + *(dst + 11) = HighNibbleToHexByteChar(b); + *(dst + 12) = LowNibbleToHexByteChar(b); + + *(dst + 13) = ASCIIminus; + + //c + b = u.bytec1; + *(dst + 14) = HighNibbleToHexByteChar(b); + *(dst + 15) = LowNibbleToHexByteChar(b); + b = u.bytec0; + *(dst + 16) = HighNibbleToHexByteChar(b); + *(dst + 17) = LowNibbleToHexByteChar(b); + } + else + { + //a + b = u.bytea0; + *dst = HighNibbleToHexByteChar(b); + *(dst + 1) = LowNibbleToHexByteChar(b); + b = u.bytea1; + *(dst + 2) = HighNibbleToHexByteChar(b); + *(dst + 3) = LowNibbleToHexByteChar(b); + b = u.bytea2; + *(dst + 4) = HighNibbleToHexByteChar(b); + *(dst + 5) = LowNibbleToHexByteChar(b); + b = u.bytea3; + *(dst + 6) = HighNibbleToHexByteChar(b); + *(dst + 7) = LowNibbleToHexByteChar(b); + + *(dst + 8) = ASCIIminus; + //b + b = u.byteb0; + *(dst + 9) = HighNibbleToHexByteChar(b); + *(dst + 10) = LowNibbleToHexByteChar(b); + b = u.byteb1; + *(dst + 11) = HighNibbleToHexByteChar(b); + *(dst + 12) = LowNibbleToHexByteChar(b); + + *(dst + 13) = ASCIIminus; + + //c + b = u.bytec0; + *(dst + 14) = HighNibbleToHexByteChar(b); + *(dst + 15) = LowNibbleToHexByteChar(b); + b = u.bytec1; + *(dst + 16) = HighNibbleToHexByteChar(b); + *(dst + 17) = LowNibbleToHexByteChar(b); + } + + *(dst + 18) = ASCIIminus; + + b = u.d; //d + *(dst + 19) = HighNibbleToHexByteChar(b); + *(dst + 20) = LowNibbleToHexByteChar(b); + b = u.e; //e + *(dst + 21) = HighNibbleToHexByteChar(b); + *(dst + 22) = LowNibbleToHexByteChar(b); + + *(dst + 23) = ASCIIminus; + + b = u.f; //f + *(dst + 24) = HighNibbleToHexByteChar(b); + *(dst + 25) = LowNibbleToHexByteChar(b); + b = u.g; //g + *(dst + 26) = HighNibbleToHexByteChar(b); + *(dst + 27) = LowNibbleToHexByteChar(b); + b = u.h; //h + *(dst + 28) = HighNibbleToHexByteChar(b); + *(dst + 29) = LowNibbleToHexByteChar(b); + b = u.i; //i + *(dst + 30) = HighNibbleToHexByteChar(b); + *(dst + 31) = LowNibbleToHexByteChar(b); + b = u.j; //j + *(dst + 32) = HighNibbleToHexByteChar(b); + *(dst + 33) = LowNibbleToHexByteChar(b); + b = u.k; //k + *(dst + 34) = HighNibbleToHexByteChar(b); + *(dst + 35) = LowNibbleToHexByteChar(b); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -2875,10 +2913,145 @@ public static unsafe osUTF8 UUIDToosUTF8(UUID v) { osUTF8 ret = new osUTF8(36); fixed (byte* d = ret.m_data) - UUIDToByteDashString(v, d); + UUIDToByteDashString(ref v, d); ret.m_len = 36; return ret; } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static unsafe osUTF8 UUIDToosUTF8(ref UUID v) + { + osUTF8 ret = new osUTF8(36); + fixed (byte* d = ret.m_data) + UUIDToByteDashString(ref v, d); + ret.m_len = 36; + return ret; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static char charLowNibbleToHexChar(byte b) + { + b &= 0x0f; + return (char)(b > 9 ? b + 0x57 : b + ASCIIzero); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static char charHighNibbleToHexChar(byte b) + { + b >>= 4; + return (char)(b > 9 ? b + 0x57 : b + ASCIIzero); + } + + public static string UUIDToDashString(ref UUID u) + { + char[] dst = new char[36]; + byte b; + if (BitConverter.IsLittleEndian) + { + //a + b = u.bytea3; + dst[0] = charHighNibbleToHexChar(b); + dst[1] = charLowNibbleToHexChar(b); + b = u.bytea2; + dst[2] = charHighNibbleToHexChar(b); + dst[3] = charLowNibbleToHexChar(b); + b = u.bytea1; + dst[4] = charHighNibbleToHexChar(b); + dst[5] = charLowNibbleToHexChar(b); + b = u.bytea0; + dst[6] = charHighNibbleToHexChar(b); + dst[7] = charLowNibbleToHexChar(b); + + dst[8] = '-'; + + //b + b = u.byteb1; + dst[9] = charHighNibbleToHexChar(b); + dst[10] = charLowNibbleToHexChar(b); + b = u.byteb0; + dst[11] = charHighNibbleToHexChar(b); + dst[12] = charLowNibbleToHexChar(b); + + dst[13] = '-'; + + //c + b = u.bytec1; + dst[14] = charHighNibbleToHexChar(b); + dst[15] = charLowNibbleToHexChar(b); + b = u.bytec0; + dst[16] = charHighNibbleToHexChar(b); + dst[17] = charLowNibbleToHexChar(b); + } + else + { + //a + b = u.bytea0; + dst[0] = charHighNibbleToHexChar(b); + dst[1] = charLowNibbleToHexChar(b); + b = u.bytea1; + dst[2] = charHighNibbleToHexChar(b); + dst[3] = charLowNibbleToHexChar(b); + b = u.bytea2; + dst[4] = charHighNibbleToHexChar(b); + dst[5] = charLowNibbleToHexChar(b); + b = u.bytea3; + dst[6] = charHighNibbleToHexChar(b); + dst[7] = charLowNibbleToHexChar(b); + + dst[8] = '-'; + + //b + b = u.byteb0; + dst[9] = charHighNibbleToHexChar(b); + dst[10] = charLowNibbleToHexChar(b); + b = u.byteb1; + dst[11] = charHighNibbleToHexChar(b); + dst[12] = charLowNibbleToHexChar(b); + + dst[13] = '-'; + + //c + b = u.bytec0; + dst[14] = charHighNibbleToHexChar(b); + dst[15] = charLowNibbleToHexChar(b); + b = u.bytec1; + dst[16] = charHighNibbleToHexChar(b); + dst[17] = charLowNibbleToHexChar(b); + } + + + dst[18] = '-'; + + b = u.d; //d + dst[19] = charHighNibbleToHexChar(b); + dst[20] = charLowNibbleToHexChar(b); + b = u.e; //e + dst[21] = charHighNibbleToHexChar(b); + dst[22] = charLowNibbleToHexChar(b); + + dst[23] = '-'; + + b = u.f; //f + dst[24] = charHighNibbleToHexChar(b); + dst[25] = charLowNibbleToHexChar(b); + b = u.g; //g + dst[26] = charHighNibbleToHexChar(b); + dst[27] = charLowNibbleToHexChar(b); + b = u.h; //h + dst[28] = charHighNibbleToHexChar(b); + dst[29] = charLowNibbleToHexChar(b); + b = u.i; //i + dst[30] = charHighNibbleToHexChar(b); + dst[31] = charLowNibbleToHexChar(b); + b = u.j; //j + dst[32] = charHighNibbleToHexChar(b); + dst[33] = charLowNibbleToHexChar(b); + b = u.k; //k + dst[34] = charHighNibbleToHexChar(b); + dst[35] = charLowNibbleToHexChar(b); + return new string(dst); + } + #endregion Miscellaneous } } From 8267575a84f3ad60620ef850e21d47ea523e0a02 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Sun, 9 Jan 2022 21:46:36 +0000 Subject: [PATCH 021/149] change UUID --- OpenMetaverseTypes/OSUTF8Slice.cs | 29 +++-- OpenMetaverseTypes/UUID.cs | 190 ++++++++++++++++++++---------- 2 files changed, 139 insertions(+), 80 deletions(-) diff --git a/OpenMetaverseTypes/OSUTF8Slice.cs b/OpenMetaverseTypes/OSUTF8Slice.cs index 1f428635..72a2150f 100644 --- a/OpenMetaverseTypes/OSUTF8Slice.cs +++ b/OpenMetaverseTypes/OSUTF8Slice.cs @@ -1594,7 +1594,7 @@ public static bool TryParseInt(osUTF8Slice t, out int res) public static bool TryParseUUID(osUTF8Slice inp, out UUID res, bool dashs = true) { - res = UUID.Zero; + res = new UUID(); osUTF8Slice t = new osUTF8Slice(inp); t.SelfTrim(); @@ -1616,8 +1616,8 @@ public static bool TryParseUUID(osUTF8Slice inp, out UUID res, bool dashs = true byte[] data = t.m_data; int dataoffset = t.m_offset; - int _a = 0; - if (!Utils.TryHexToInt(data, dataoffset, 8, out _a)) + UUID utmp = new UUID(); + if (!Utils.TryHexToInt(data, dataoffset, 8, out utmp.a)) return false; dataoffset += 8; @@ -1631,7 +1631,7 @@ public static bool TryParseUUID(osUTF8Slice inp, out UUID res, bool dashs = true int n; if (!Utils.TryHexToInt(data, dataoffset, 4, out n)) return false; - short _b = (short)n; + utmp.b = (short)n; dataoffset += 4; if (dashs) @@ -1643,7 +1643,7 @@ public static bool TryParseUUID(osUTF8Slice inp, out UUID res, bool dashs = true if (!Utils.TryHexToInt(data, dataoffset, 4, out n)) return false; - short _c = (short)n; + utmp.c = (short)n; dataoffset += 4; if (dashs) @@ -1656,8 +1656,8 @@ public static bool TryParseUUID(osUTF8Slice inp, out UUID res, bool dashs = true if (!Utils.TryHexToInt(data, dataoffset, 4, out n)) return false; - byte _d = (byte)(n >> 8); - byte _e = (byte)n; + utmp.d = (byte)(n >> 8); + utmp.e = (byte)n; dataoffset += 4; if (dashs) @@ -1669,19 +1669,18 @@ public static bool TryParseUUID(osUTF8Slice inp, out UUID res, bool dashs = true if (!Utils.TryHexToInt(data, dataoffset, 8, out n)) return false; - byte _f = (byte)(n >> 24); - byte _g = (byte)(n >> 16); - byte _h = (byte)(n >> 8); - byte _i = (byte)n; + utmp.f = (byte)(n >> 24); + utmp.g = (byte)(n >> 16); + utmp.h = (byte)(n >> 8); + utmp.i = (byte)n; dataoffset += 8; if (!Utils.TryHexToInt(data, dataoffset, 4, out n)) return false; - byte _j = (byte)(n >> 8); - byte _k = (byte)n; + utmp.j = (byte)(n >> 8); + utmp.k = (byte)n; - Guid g = new Guid(_a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k); - res = new UUID(g); + res = utmp; return true; } } diff --git a/OpenMetaverseTypes/UUID.cs b/OpenMetaverseTypes/UUID.cs index c5113b52..2d5503b2 100644 --- a/OpenMetaverseTypes/UUID.cs +++ b/OpenMetaverseTypes/UUID.cs @@ -126,23 +126,37 @@ public unsafe UUID(ulong _la, ulong _lb) : this() [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe UUID(byte[] source, int pos) : this() { - if (BitConverter.IsLittleEndian) + fixed (byte* ptr = &source[pos]) { - bytea3 = source[pos + 0]; - bytea2 = source[pos + 1]; - bytea1 = source[pos + 2]; - bytea0 = source[pos + 3]; + if (BitConverter.IsLittleEndian) + { + bytea3 = *ptr; + bytea2 = *(ptr + 1); + bytea1 = *(ptr + 2); + bytea0 = *(ptr + 3); - byteb1 = source[pos + 4]; - byteb0 = source[pos + 5]; + byteb1 = *(ptr + 4); + byteb0 = *(ptr + 5); - bytec1 = source[pos + 6]; - bytec0 = source[pos + 7]; - } - else - ulonga = Utils.BytesToUInt64(source, pos); + bytec1 = *(ptr + 6); + bytec0 = *(ptr + 7); - ulongb = Utils.BytesToUInt64(source, pos + 8); + ulongb = *(ulong*)(ptr + 8); + } + else + { + ulonga = *(ulong*)(ptr); + + d = *(ptr + 8); + e = *(ptr + 9); + f = *(ptr + 10); + g = *(ptr + 11); + h = *(ptr + 12); + i = *(ptr + 13); + j = *(ptr + 14); + k = *(ptr + 15); + } + } } /// @@ -253,23 +267,35 @@ public int CompareTo(UUID id) [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe void FromBytes(byte[] source, int pos) { - if (BitConverter.IsLittleEndian) + fixed (byte* ptr = &source[pos]) { - bytea3 = source[pos + 0]; - bytea2 = source[pos + 1]; - bytea1 = source[pos + 2]; - bytea0 = source[pos + 3]; + if (BitConverter.IsLittleEndian) + { + bytea3 = *ptr; + bytea2 = *(ptr + 1); + bytea1 = *(ptr + 2); + bytea0 = *(ptr + 3); - byteb1 = source[pos + 4]; - byteb0 = source[pos + 5]; + byteb1 = *(ptr + 4); + byteb0 = *(ptr + 5); - bytec1 = source[pos + 6]; - bytec0 = source[pos + 7]; + bytec1 = *(ptr + 6); + bytec0 = *(ptr + 7); + ulongb = *(ulong*)(ptr + 8); + } + else + { + ulonga = *(ulong*)(ptr); + d = *(ptr + 8); + e = *(ptr + 9); + f = *(ptr + 10); + g = *(ptr + 11); + h = *(ptr + 12); + i = *(ptr + 13); + j = *(ptr + 14); + k = *(ptr + 15); + } } - else - ulonga = Utils.BytesToUInt64(source, pos); - - ulongb = Utils.BytesToUInt64(source, pos + 8); } /// @@ -277,26 +303,36 @@ public unsafe void FromBytes(byte[] source, int pos) /// /// A 16 byte array containing this UUID [MethodImpl(MethodImplOptions.AggressiveInlining)] - public byte[] GetBytes() + public unsafe byte[] GetBytes() { byte[] dest = new byte[16]; - if (BitConverter.IsLittleEndian) + fixed (byte* ptr = &dest[0]) { - dest[0] = bytea3; - dest[1] = bytea2; - dest[2] = bytea1; - dest[3] = bytea0; - - dest[4] = byteb1; - dest[5] = byteb0; - - dest[6] = bytec1; - dest[7] = bytec0; + if (BitConverter.IsLittleEndian) + { + *ptr = bytea3; + *(ptr + 1) = bytea2; + *(ptr + 2) = bytea1; + *(ptr + 3) = bytea0; + *(ptr + 4) = byteb1; + *(ptr + 5) = byteb0; + *(ptr + 6) = bytec1; + *(ptr + 7) = bytec0; + *(ulong*)(ptr + 8) = ulongb; + } + else + { + *(ulong*)(ptr) = ulonga; + *(ptr + 8) = d; + *(ptr + 9) = e; + *(ptr + 10) = f; + *(ptr + 11) = g; + *(ptr + 12) = h; + *(ptr + 13) = i; + *(ptr + 14) = j; + *(ptr + 15) = k; + } } - else - Utils.UInt64ToBytesSafepos(ulonga, dest, 0); - - Utils.UInt64ToBytesSafepos(ulongb, dest, 8); return dest; } @@ -307,23 +343,35 @@ public byte[] GetBytes() /// Position in the destination array to start /// writing. Must be at least 16 bytes before the end of the array [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToBytes(byte[] dest, int pos) + public unsafe void ToBytes(byte[] dest, int pos) { - if (BitConverter.IsLittleEndian) + fixed(byte* ptr = &dest[pos]) { - dest[pos + 0] = bytea3; - dest[pos + 1] = bytea2; - dest[pos + 2] = bytea1; - dest[pos + 3] = bytea0; - dest[pos + 4] = byteb1; - dest[pos + 5] = byteb0; - dest[pos + 6] = bytec1; - dest[pos + 7] = bytec0; + if (BitConverter.IsLittleEndian) + { + *ptr = bytea3; + *(ptr + 1) = bytea2; + *(ptr + 2) = bytea1; + *(ptr + 3) = bytea0; + *(ptr + 4) = byteb1; + *(ptr + 5) = byteb0; + *(ptr + 6) = bytec1; + *(ptr + 7) = bytec0; + *(ulong*)(ptr + 8) = ulongb; + } + else + { + *(ulong*)(ptr) = ulonga; + *(ptr + 8) = d; + *(ptr + 9) = e; + *(ptr + 10) = f; + *(ptr + 11) = g; + *(ptr + 12) = h; + *(ptr + 13) = i; + *(ptr + 14) = j; + *(ptr + 15) = k; + } } - else - Utils.UInt64ToBytesSafepos(ulonga, dest, pos); - - Utils.UInt64ToBytesSafepos(ulongb, dest, pos + 8); } /// @@ -336,15 +384,7 @@ public uint CRC() return (uint)a + (uint)intb + (uint)intc + (uint)intd; } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool IsZero() - { - if (ulonga != 0) - return false; - if (ulongb != 0) - return false; - return true; - } + /// /// Create a 64-bit integer representation from the second half of this UUID @@ -484,6 +524,16 @@ public bool Equals(UUID uuid) return true; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool IsZero() + { + if (ulonga != 0) + return false; + if (ulongb != 0) + return false; + return true; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool NotEqual(UUID uuid) { @@ -494,6 +544,16 @@ public bool NotEqual(UUID uuid) return false; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool IsNotZero() + { + if (ulonga != 0) + return true; + if (ulongb != 0) + return true; + return false; + } + /// /// Get a hyphenated string representation of this UUID /// From 6a2766c57d32f89a1dfb62238b9bfe9cf4705e73 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Sun, 9 Jan 2022 23:34:26 +0000 Subject: [PATCH 022/149] change vector2 and 3 a bit --- OpenMetaverseTypes/UUID.cs | 2 - OpenMetaverseTypes/UtilsConversions.cs | 16 ++++- OpenMetaverseTypes/Vector2.cs | 69 +++++++++++++++++--- OpenMetaverseTypes/Vector3.cs | 87 ++++++++++++++++++++++---- 4 files changed, 150 insertions(+), 24 deletions(-) diff --git a/OpenMetaverseTypes/UUID.cs b/OpenMetaverseTypes/UUID.cs index 2d5503b2..1851f5e6 100644 --- a/OpenMetaverseTypes/UUID.cs +++ b/OpenMetaverseTypes/UUID.cs @@ -384,8 +384,6 @@ public uint CRC() return (uint)a + (uint)intb + (uint)intc + (uint)intd; } - - /// /// Create a 64-bit integer representation from the second half of this UUID /// diff --git a/OpenMetaverseTypes/UtilsConversions.cs b/OpenMetaverseTypes/UtilsConversions.cs index e4f9bf2f..ea0c78a0 100644 --- a/OpenMetaverseTypes/UtilsConversions.cs +++ b/OpenMetaverseTypes/UtilsConversions.cs @@ -328,16 +328,28 @@ static bool CheckDirectCopyBE() public static bool ApproxEqual(float a, float b, float tolerance, float reltolerance = float.Epsilon) { float dif = Math.Abs(a - b); - if(dif <= tolerance) + if (dif <= tolerance) return true; a = Math.Abs(a); b = Math.Abs(b); - if(b > a) + if (b > a) a = b; return dif <= a * reltolerance; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool ApproxZero(float a, float tolerance) + { + return Math.Abs(a) <= tolerance; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool ApproxZero(float a) + { + return Math.Abs(a) <= 1e-6; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool ApproxEqual(float a, float b) { diff --git a/OpenMetaverseTypes/Vector2.cs b/OpenMetaverseTypes/Vector2.cs index fb437317..ab4187d8 100644 --- a/OpenMetaverseTypes/Vector2.cs +++ b/OpenMetaverseTypes/Vector2.cs @@ -25,6 +25,7 @@ */ using System; +using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Globalization; @@ -65,7 +66,7 @@ public Vector2(Vector2 vector) #endregion Constructors #region Public Methods - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Abs() { if (X < 0f) @@ -74,14 +75,14 @@ public void Abs() Y = -Y; } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Min(Vector2 v) { if (v.X < X) X = v.X; if (v.Y < Y) Y = v.Y; } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Max(Vector2 v) { if (v.X > X) X = v.X; @@ -97,20 +98,50 @@ public void Max(Vector2 v) /// between the two vectors /// True if the magnitude of difference between the two vectors /// is less than the given tolerance, otherwise false - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool ApproxEquals(Vector2 vec, float tolerance) { return Utils.ApproxEqual(X, vec.X, tolerance) && Utils.ApproxEqual(Y, vec.Y, tolerance); } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool ApproxEquals(Vector2 vec) { return Utils.ApproxEqual(X, vec.X) && Utils.ApproxEqual(Y, vec.Y); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool ApproxZero() + { + if (!Utils.ApproxZero(X)) + return false; + if (!Utils.ApproxZero(Y)) + return false; + return true; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool ApproxZero(float tolerance) + { + if (!Utils.ApproxZero(X, tolerance)) + return false; + if (!Utils.ApproxZero(Y, tolerance)) + return false; + return true; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool IsZero() + { + if (X != 0) + return false; + if (Y != 0) + return false; + return true; + } + /// /// Test if this vector is composed of all finite numbers /// @@ -362,12 +393,24 @@ public static Vector2 TransformNormal(Vector2 position, Matrix4 matrix) public override bool Equals(object obj) { - return (obj is Vector2) ? this == ((Vector2)obj) : false; + if (!(obj is Vector2)) + return false; + + Vector2 other = (Vector2)obj; + if (X != other.X) + return false; + if (Y != other.Y) + return false; + return true; } public bool Equals(Vector2 other) { - return this == other; + if (X != other.X) + return false; + if (Y != other.Y) + return false; + return true; } public override int GetHashCode() @@ -405,12 +448,20 @@ public string ToRawString() public static bool operator ==(Vector2 value1, Vector2 value2) { - return value1.X == value2.X && value1.Y == value2.Y; + if (value1.X != value2.X) + return false; + if (value1.Y != value2.Y) + return false; + return true; } public static bool operator !=(Vector2 value1, Vector2 value2) { - return value1.X != value2.X || value1.Y != value2.Y; + if (value1.X != value2.X) + return true; + if (value1.Y != value2.Y) + return true; + return false; } public static Vector2 operator +(Vector2 value1, Vector2 value2) diff --git a/OpenMetaverseTypes/Vector3.cs b/OpenMetaverseTypes/Vector3.cs index ce7b478c..53c03b94 100644 --- a/OpenMetaverseTypes/Vector3.cs +++ b/OpenMetaverseTypes/Vector3.cs @@ -95,11 +95,11 @@ public Vector3(Vector3 vector) [MethodImpl(MethodImplOptions.AggressiveInlining)] public Vector3(byte[] byteArray, int pos) { - X = Y = Z = 0f; - FromBytes(byteArray, pos); + X = Utils.BytesToFloatSafepos(byteArray, pos); + Y = Utils.BytesToFloatSafepos(byteArray, pos + 4); + Z = Utils.BytesToFloatSafepos(byteArray, pos + 8); } - #endregion Constructors #region Public Methods @@ -182,8 +182,45 @@ public bool ApproxEquals(Vector3 vec) public bool ApproxEquals(Vector3 vec, float tolerance) { return Utils.ApproxEqual(X, vec.X, tolerance) && - Utils.ApproxEqual(Y, vec.Y, tolerance) && - Utils.ApproxEqual(Z, vec.Z, tolerance); + Utils.ApproxEqual(Y, vec.Y, tolerance) && + Utils.ApproxEqual(Z, vec.Z, tolerance); + } + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool ApproxZero() + { + if (!Utils.ApproxZero(X)) + return false; + if (!Utils.ApproxZero(Y)) + return false; + if (!Utils.ApproxZero(Z)) + return false; + return true; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool ApproxZero(float tolerance) + { + if (!Utils.ApproxZero(X, tolerance)) + return false; + if (!Utils.ApproxZero(Y, tolerance)) + return false; + if (!Utils.ApproxZero(Z, tolerance)) + return false; + return true; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool IsZero() + { + if (X != 0) + return false; + if (Y != 0) + return false; + if (Z != 0) + return false; + return true; } /// @@ -496,12 +533,28 @@ public static Vector3 Transform(Vector3 vec, Quaternion rot) public override bool Equals(object obj) { - return (obj is Vector3) ? this == (Vector3)obj : false; + if (!(obj is Vector3)) + return false; + + Vector3 other = (Vector3)obj; + if (X != other.X) + return false; + if (Y != other.Y) + return false; + if (Z != other.Z) + return false; + return true; } public bool Equals(Vector3 other) { - return this == other; + if (X != other.X) + return false; + if (Y != other.Y) + return false; + if (Z != other.Z) + return false; + return true; } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -539,16 +592,28 @@ public string ToRawString() #region Operators + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool operator ==(Vector3 value1, Vector3 value2) { - return value1.X == value2.X - && value1.Y == value2.Y - && value1.Z == value2.Z; + if (value1.X != value2.X) + return false; + if (value1.Y != value2.Y) + return false; + if (value1.Z == value2.Z) + return false; + return true; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool operator !=(Vector3 value1, Vector3 value2) { - return !(value1 == value2); + if (value1.X != value2.X) + return true; + if (value1.Y != value2.Y) + return true; + if (value1.Z == value2.Z) + return true; + return false; } [MethodImpl(MethodImplOptions.AggressiveInlining)] From 3db3bba242d41a87ee6cbed6628ed056b50e1a03 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Mon, 10 Jan 2022 00:09:47 +0000 Subject: [PATCH 023/149] fix vector3 ==() and !=() --- OpenMetaverseTypes/Vector3.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OpenMetaverseTypes/Vector3.cs b/OpenMetaverseTypes/Vector3.cs index 53c03b94..8f95a3a3 100644 --- a/OpenMetaverseTypes/Vector3.cs +++ b/OpenMetaverseTypes/Vector3.cs @@ -599,7 +599,7 @@ public string ToRawString() return false; if (value1.Y != value2.Y) return false; - if (value1.Z == value2.Z) + if (value1.Z != value2.Z) return false; return true; } @@ -611,7 +611,7 @@ public string ToRawString() return true; if (value1.Y != value2.Y) return true; - if (value1.Z == value2.Z) + if (value1.Z != value2.Z) return true; return false; } From fad44276b2ff453b5a8a4b9467270bffeec8369e Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Mon, 10 Jan 2022 02:36:38 +0000 Subject: [PATCH 024/149] a few changes to vector 4 and quat --- OpenMetaverseTypes/Quaternion.cs | 90 +++++++++++++++++++++++++------ OpenMetaverseTypes/Vector4.cs | 91 ++++++++++++++++++++++++++------ 2 files changed, 148 insertions(+), 33 deletions(-) diff --git a/OpenMetaverseTypes/Quaternion.cs b/OpenMetaverseTypes/Quaternion.cs index a2272ff6..91af0a02 100644 --- a/OpenMetaverseTypes/Quaternion.cs +++ b/OpenMetaverseTypes/Quaternion.cs @@ -113,7 +113,7 @@ public Quaternion(Quaternion q) public bool ApproxEquals(Quaternion quat) { // assume normalized - return Math.Abs(quat.X - X) < 1e-6f && + return Math.Abs(quat.X - X) < 1e-6f && Math.Abs(quat.Y - Y) < 1e-6f && Math.Abs(quat.Z - Z) < 1e-6f; } @@ -127,6 +127,30 @@ public bool ApproxEquals(Quaternion quat, float tolerance) Math.Abs(quat.Z - Z) < tolerance; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool IsIdentity() + { + // assume normalized + if(W > (1.0f - 1e-6f)) + return true; + if (W < -(1.0f - 1e-6f)) + return true; + return false; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool IsIdentityOrZero() + { + // assume normalized + if (X != 0) + return false; + if (Y != 0) + return false; + if (Z != 0) + return false; + return true; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public float Length() { @@ -324,8 +348,8 @@ public void GetEulerAngles(out float roll, out float pitch, out float yaw) /// Angle around the axis, in radians public void GetAxisAngle(out Vector3 axis, out float angle) { - Quaternion q = Normalize(this); - float ww = q.W * q.W; + Normalize(); + float ww = W * W; if (ww > 0.9999f) { axis = Vector3.UnitX; @@ -334,21 +358,21 @@ public void GetAxisAngle(out Vector3 axis, out float angle) } if(ww < 0.0001f) { - if (q.W < 0f) - axis = new Vector3(-q.X, -q.Y, -q.Z); + if (W < 0f) + axis = new Vector3(-X, -Y, -Z); else - axis = new Vector3(q.X, q.Y, q.Z); + axis = new Vector3(X, Y, Z); angle = (float)Math.PI; return; } float sin = (float)Math.Sqrt(1.0f - ww); float invSin = 1.0f / sin; - if (q.W < 0) + if (W < 0) invSin = -invSin; - axis = new Vector3(q.X, q.Y, q.Z) * invSin; + axis = new Vector3(X, Y, Z) * invSin; - angle = 2.0f * (float)Math.Acos(q.W); + angle = 2.0f * (float)Math.Acos(W); if (angle > Math.PI) angle = 2.0f * (float)Math.PI - angle; } @@ -396,7 +420,7 @@ public static Quaternion CreateFromAxisAngle(float axisX, float axisY, float axi [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Quaternion CreateFromAxisAngle(Vector3 axis, float angle) { - axis = Vector3.Normalize(axis); + axis.Normalize(); angle *= 0.5f; float c = (float)Math.Cos(angle); @@ -750,15 +774,31 @@ public static bool TryParse(string val, out Quaternion result) public override bool Equals(object obj) { - return (obj is Quaternion) ? this == (Quaternion)obj : false; + if(!(obj is Quaternion)) + return false; + Quaternion other = (Quaternion)obj; + if (X != other.X) + return false; + if (Y != other.Y) + return false; + if (Z != other.Z) + return false; + if (W != other.W) + return false; + return true; } public bool Equals(Quaternion other) { - return W == other.W - && X == other.X - && Y == other.Y - && Z == other.Z; + if (X != other.X) + return false; + if (Y != other.Y) + return false; + if (Z != other.Z) + return false; + if (W != other.W) + return false; + return true; } public override int GetHashCode() @@ -795,13 +835,29 @@ public string ToRawString() [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool operator ==(Quaternion quaternion1, Quaternion quaternion2) { - return quaternion1.Equals(quaternion2); + if (quaternion1.X != quaternion2.X) + return false; + if (quaternion1.Y != quaternion2.Y) + return false; + if (quaternion1.Z != quaternion2.Z) + return false; + if (quaternion1.W != quaternion2.W) + return false; + return true; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool operator !=(Quaternion quaternion1, Quaternion quaternion2) { - return !quaternion1.Equals(quaternion2); + if (quaternion1.X != quaternion2.X) + return true; + if (quaternion1.Y != quaternion2.Y) + return true; + if (quaternion1.Z != quaternion2.Z) + return true; + if (quaternion1.W != quaternion2.W) + return true; + return false; } [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/OpenMetaverseTypes/Vector4.cs b/OpenMetaverseTypes/Vector4.cs index 9af36585..c4e54e2a 100644 --- a/OpenMetaverseTypes/Vector4.cs +++ b/OpenMetaverseTypes/Vector4.cs @@ -25,6 +25,7 @@ */ using System; +using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Globalization; @@ -84,8 +85,10 @@ public Vector4(float value) /// Beginning position in the byte array public Vector4(byte[] byteArray, int pos) { - X = Y = Z = W = 0f; - FromBytes(byteArray, pos); + X = Utils.BytesToFloatSafepos(byteArray, pos); + Y = Utils.BytesToFloatSafepos(byteArray, pos + 4); + Z = Utils.BytesToFloatSafepos(byteArray, pos + 8); + W = Utils.BytesToFloatSafepos(byteArray, pos + 12); } public Vector4(Vector4 value) @@ -99,7 +102,7 @@ public Vector4(Vector4 value) #endregion Constructors #region Public Methods - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Abs() { X = Math.Abs(X); @@ -108,7 +111,7 @@ public void Abs() W = Math.Abs(W); } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Min(Vector4 v) { if (v.X < X) X = v.X; @@ -126,11 +129,13 @@ public void Max(Vector4 v) if (v.W > W) W = v.W; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public float Length() { return (float)Math.Sqrt(X * X + Y * Y + Z * Z + W * W); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public float LengthSquared() { return (X * X) + (Y * Y) + (Z * Z) + (W * W); @@ -138,7 +143,17 @@ public float LengthSquared() public void Normalize() { - this = Normalize(this); + float factor = LengthSquared(); + if (factor > 1e-6) + { + factor = 1f / (float)Math.Sqrt(factor); + X *= factor; + Y *= factor; + Z *= factor; + W *= factor; + } + else + this = new Vector4(); } /// @@ -150,6 +165,7 @@ public void Normalize() /// between the two vectors /// True if the magnitude of difference between the two vectors /// is less than the given tolerance, otherwise false + [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool ApproxEquals(Vector4 vec, float tolerance) { return Utils.ApproxEqual(X, vec.X, tolerance) && @@ -158,6 +174,7 @@ public bool ApproxEquals(Vector4 vec, float tolerance) Utils.ApproxEqual(W, vec.W, tolerance); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool ApproxEquals(Vector4 vec) { return Utils.ApproxEqual(X, vec.X) && @@ -166,6 +183,19 @@ public bool ApproxEquals(Vector4 vec) Utils.ApproxEqual(W, vec.W); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool IsZero() + { + if (X != 0) + return false; + if (Y != 0) + return false; + if (Z != 0) + return false; + if (W != 0) + return false; + return true; + } /// /// IComparable.CompareTo implementation /// @@ -431,15 +461,32 @@ public static bool TryParse(string val, out Vector4 result) public override bool Equals(object obj) { - return (obj is Vector4) ? this == (Vector4)obj : false; + if (!(obj is Vector4)) + return false; + + Vector4 other = (Vector4)obj; + if (X != other.X) + return false; + if (Y != other.Y) + return false; + if (Z != other.Z) + return false; + if (W != other.W) + return false; + return true; } public bool Equals(Vector4 other) { - return W == other.W - && X == other.X - && Y == other.Y - && Z == other.Z; + if (X != other.X) + return false; + if (Y != other.Y) + return false; + if (Z != other.Z) + return false; + if (W != other.W) + return false; + return true; } public override int GetHashCode() @@ -471,16 +518,28 @@ public string ToRawString() public static bool operator ==(Vector4 value1, Vector4 value2) { - return - value1.X == value2.X - && value1.Y == value2.Y - && value1.Z == value2.Z - && value1.W == value2.W; + if (value1.X != value2.X) + return false; + if (value1.Y != value2.Y) + return false; + if (value1.Z != value2.Z) + return false; + if (value1.W != value2.W) + return false; + return true; } public static bool operator !=(Vector4 value1, Vector4 value2) { - return !(value1 == value2); + if (value1.X != value2.X) + return true; + if (value1.Y != value2.Y) + return true; + if (value1.Z != value2.Z) + return true; + if (value1.W != value2.W) + return true; + return false; } public static Vector4 operator +(Vector4 value1, Vector4 value2) From ceb5895885bef56bed788bf661609f4b05bdc8d1 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Mon, 10 Jan 2022 21:27:21 +0000 Subject: [PATCH 025/149] proper bypass lludp header extra bytes, even if not seen so far; a few changes to acks decode --- OpenMetaverse.Tests/PacketTests.cs | 2 +- OpenMetaverse/Simulator.cs | 2 +- OpenMetaverse/_Packets_.cs | 830 ++++++++++++------------- OpenMetaverseTypes/UtilsConversions.cs | 9 + Programs/GridProxy/GridProxy.cs | 4 +- Programs/WinGridProxy/SessionTypes.cs | 2 +- Programs/mapgenerator/mapgenerator.cs | 27 +- 7 files changed, 439 insertions(+), 437 deletions(-) diff --git a/OpenMetaverse.Tests/PacketTests.cs b/OpenMetaverse.Tests/PacketTests.cs index ac84a36b..75814684 100644 --- a/OpenMetaverse.Tests/PacketTests.cs +++ b/OpenMetaverse.Tests/PacketTests.cs @@ -134,7 +134,7 @@ public void ToBytesMultiple() for (int i = 0; i < splitPackets.Length; i++) { byte[] packetData = splitPackets[i]; - int len = packetData.Length - 1; + int len = packetData.Length; DirPlacesReplyPacket packet = (DirPlacesReplyPacket)Packet.BuildPacket(packetData, ref len, packetData); Assert.IsTrue(packet.AgentData.AgentID == bigPacket.AgentData.AgentID); diff --git a/OpenMetaverse/Simulator.cs b/OpenMetaverse/Simulator.cs index a1c386f2..442b0c80 100644 --- a/OpenMetaverse/Simulator.cs +++ b/OpenMetaverse/Simulator.cs @@ -1052,7 +1052,7 @@ protected override void PacketReceived(UDPPacketBuffer buffer) #region Packet Decoding - int packetEnd = buffer.DataLength - 1; + int packetEnd = buffer.DataLength; try { diff --git a/OpenMetaverse/_Packets_.cs b/OpenMetaverse/_Packets_.cs index c71cef14..62b6d8a6 100644 --- a/OpenMetaverse/_Packets_.cs +++ b/OpenMetaverse/_Packets_.cs @@ -151,7 +151,7 @@ public void AcksToBytes(byte[] bytes, ref int i) /// /// /// - public static Header BuildHeader(byte[] bytes, ref int pos, ref int packetEnd) + public static Header BuildHeader(byte[] bytes, ref int pos, ref int packetLength) { Header header; byte flags = bytes[pos]; @@ -160,8 +160,9 @@ public static Header BuildHeader(byte[] bytes, ref int pos, ref int packetEnd) header.Reliable = (flags & Helpers.MSG_RELIABLE) != 0; header.Resent = (flags & Helpers.MSG_RESENT) != 0; header.Zerocoded = (flags & Helpers.MSG_ZEROCODED) != 0; - header.Sequence = (uint)((bytes[pos + 1] << 24) + (bytes[pos + 2] << 16) + (bytes[pos + 3] << 8) + bytes[pos + 4]); + header.Sequence = (uint)Utils.BytesToIntBig(bytes, 1); + pos += bytes[pos + 5]; // Set the frequency and packet ID number if (bytes[pos + 6] == 0xFF) { @@ -191,36 +192,21 @@ public static Header BuildHeader(byte[] bytes, ref int pos, ref int packetEnd) pos += 7; } - header.AckList = null; - CreateAckList(ref header, bytes, ref packetEnd); - - return header; - } - - /// - /// - /// - /// - /// - /// - static void CreateAckList(ref Header header, byte[] bytes, ref int packetEnd) - { if (header.AppendedAcks) { - int count = bytes[packetEnd--]; + --packetLength; + int count = bytes[packetLength]; header.AckList = new uint[count]; - for (int i = 0; i < count; i++) { - header.AckList[i] = (uint)( - (bytes[(packetEnd - i * 4) - 3] << 24) | - (bytes[(packetEnd - i * 4) - 2] << 16) | - (bytes[(packetEnd - i * 4) - 1] << 8) | - (bytes[(packetEnd - i * 4) ])); + packetLength -= 4; + header.AckList[i] = (uint)Utils.BytesToIntBig(bytes, packetLength); } - - packetEnd -= (count * 4); } + else + header.AckList = null; + + return header; } } @@ -1067,413 +1053,415 @@ public static PacketType GetType(ushort id, PacketFrequency frequency) return PacketType.Default; } - public static Packet BuildPacket(PacketType type) - { - if(type == PacketType.StartPingCheck) return new StartPingCheckPacket(); - if(type == PacketType.CompletePingCheck) return new CompletePingCheckPacket(); - if(type == PacketType.AgentUpdate) return new AgentUpdatePacket(); - if(type == PacketType.AgentAnimation) return new AgentAnimationPacket(); - if(type == PacketType.AgentRequestSit) return new AgentRequestSitPacket(); - if(type == PacketType.AgentSit) return new AgentSitPacket(); - if(type == PacketType.RequestImage) return new RequestImagePacket(); - if(type == PacketType.ImageData) return new ImageDataPacket(); - if(type == PacketType.ImagePacket) return new ImagePacketPacket(); - if(type == PacketType.LayerData) return new LayerDataPacket(); - if(type == PacketType.ObjectUpdate) return new ObjectUpdatePacket(); - if(type == PacketType.ObjectUpdateCompressed) return new ObjectUpdateCompressedPacket(); - if(type == PacketType.ObjectUpdateCached) return new ObjectUpdateCachedPacket(); - if(type == PacketType.ImprovedTerseObjectUpdate) return new ImprovedTerseObjectUpdatePacket(); - if(type == PacketType.KillObject) return new KillObjectPacket(); - if(type == PacketType.TransferPacket) return new TransferPacketPacket(); - if(type == PacketType.SendXferPacket) return new SendXferPacketPacket(); - if(type == PacketType.ConfirmXferPacket) return new ConfirmXferPacketPacket(); - if(type == PacketType.AvatarAnimation) return new AvatarAnimationPacket(); - if(type == PacketType.AvatarSitResponse) return new AvatarSitResponsePacket(); - if(type == PacketType.CameraConstraint) return new CameraConstraintPacket(); - if(type == PacketType.ParcelProperties) return new ParcelPropertiesPacket(); - if(type == PacketType.ChildAgentUpdate) return new ChildAgentUpdatePacket(); - if(type == PacketType.ChildAgentAlive) return new ChildAgentAlivePacket(); - if(type == PacketType.ChildAgentPositionUpdate) return new ChildAgentPositionUpdatePacket(); - if(type == PacketType.SoundTrigger) return new SoundTriggerPacket(); - if(type == PacketType.ObjectAnimation) return new ObjectAnimationPacket(); - if(type == PacketType.ObjectAdd) return new ObjectAddPacket(); - if(type == PacketType.MultipleObjectUpdate) return new MultipleObjectUpdatePacket(); - if(type == PacketType.RequestMultipleObjects) return new RequestMultipleObjectsPacket(); - if(type == PacketType.ObjectPosition) return new ObjectPositionPacket(); - if(type == PacketType.RequestObjectPropertiesFamily) return new RequestObjectPropertiesFamilyPacket(); - if(type == PacketType.CoarseLocationUpdate) return new CoarseLocationUpdatePacket(); - if(type == PacketType.CrossedRegion) return new CrossedRegionPacket(); - if(type == PacketType.ConfirmEnableSimulator) return new ConfirmEnableSimulatorPacket(); - if(type == PacketType.ObjectProperties) return new ObjectPropertiesPacket(); - if(type == PacketType.ObjectPropertiesFamily) return new ObjectPropertiesFamilyPacket(); - if(type == PacketType.ParcelPropertiesRequest) return new ParcelPropertiesRequestPacket(); - if(type == PacketType.AttachedSound) return new AttachedSoundPacket(); - if(type == PacketType.AttachedSoundGainChange) return new AttachedSoundGainChangePacket(); - if(type == PacketType.PreloadSound) return new PreloadSoundPacket(); - if(type == PacketType.ViewerEffect) return new ViewerEffectPacket(); - if(type == PacketType.TestMessage) return new TestMessagePacket(); - if(type == PacketType.UseCircuitCode) return new UseCircuitCodePacket(); - if(type == PacketType.TelehubInfo) return new TelehubInfoPacket(); - if(type == PacketType.EconomyDataRequest) return new EconomyDataRequestPacket(); - if(type == PacketType.EconomyData) return new EconomyDataPacket(); - if(type == PacketType.AvatarPickerRequest) return new AvatarPickerRequestPacket(); - if(type == PacketType.AvatarPickerReply) return new AvatarPickerReplyPacket(); - if(type == PacketType.PlacesQuery) return new PlacesQueryPacket(); - if(type == PacketType.PlacesReply) return new PlacesReplyPacket(); - if(type == PacketType.DirFindQuery) return new DirFindQueryPacket(); - if(type == PacketType.DirPlacesQuery) return new DirPlacesQueryPacket(); - if(type == PacketType.DirPlacesReply) return new DirPlacesReplyPacket(); - if(type == PacketType.DirPeopleReply) return new DirPeopleReplyPacket(); - if(type == PacketType.DirEventsReply) return new DirEventsReplyPacket(); - if(type == PacketType.DirGroupsReply) return new DirGroupsReplyPacket(); - if(type == PacketType.DirClassifiedQuery) return new DirClassifiedQueryPacket(); - if(type == PacketType.DirClassifiedReply) return new DirClassifiedReplyPacket(); - if(type == PacketType.AvatarClassifiedReply) return new AvatarClassifiedReplyPacket(); - if(type == PacketType.ClassifiedInfoRequest) return new ClassifiedInfoRequestPacket(); - if(type == PacketType.ClassifiedInfoReply) return new ClassifiedInfoReplyPacket(); - if(type == PacketType.ClassifiedInfoUpdate) return new ClassifiedInfoUpdatePacket(); - if(type == PacketType.ClassifiedDelete) return new ClassifiedDeletePacket(); - if(type == PacketType.ClassifiedGodDelete) return new ClassifiedGodDeletePacket(); - if(type == PacketType.DirLandQuery) return new DirLandQueryPacket(); - if(type == PacketType.DirLandReply) return new DirLandReplyPacket(); - if(type == PacketType.DirPopularQuery) return new DirPopularQueryPacket(); - if(type == PacketType.DirPopularReply) return new DirPopularReplyPacket(); - if(type == PacketType.ParcelInfoRequest) return new ParcelInfoRequestPacket(); - if(type == PacketType.ParcelInfoReply) return new ParcelInfoReplyPacket(); - if(type == PacketType.ParcelObjectOwnersRequest) return new ParcelObjectOwnersRequestPacket(); - if(type == PacketType.ParcelObjectOwnersReply) return new ParcelObjectOwnersReplyPacket(); - if(type == PacketType.GroupNoticesListRequest) return new GroupNoticesListRequestPacket(); - if(type == PacketType.GroupNoticesListReply) return new GroupNoticesListReplyPacket(); - if(type == PacketType.GroupNoticeRequest) return new GroupNoticeRequestPacket(); - if(type == PacketType.TeleportRequest) return new TeleportRequestPacket(); - if(type == PacketType.TeleportLocationRequest) return new TeleportLocationRequestPacket(); - if(type == PacketType.TeleportLocal) return new TeleportLocalPacket(); - if(type == PacketType.TeleportLandmarkRequest) return new TeleportLandmarkRequestPacket(); - if(type == PacketType.TeleportProgress) return new TeleportProgressPacket(); - if(type == PacketType.TeleportFinish) return new TeleportFinishPacket(); - if(type == PacketType.StartLure) return new StartLurePacket(); - if(type == PacketType.TeleportLureRequest) return new TeleportLureRequestPacket(); - if(type == PacketType.TeleportCancel) return new TeleportCancelPacket(); - if(type == PacketType.TeleportStart) return new TeleportStartPacket(); - if(type == PacketType.TeleportFailed) return new TeleportFailedPacket(); - if(type == PacketType.Undo) return new UndoPacket(); - if(type == PacketType.Redo) return new RedoPacket(); - if(type == PacketType.UndoLand) return new UndoLandPacket(); - if(type == PacketType.AgentPause) return new AgentPausePacket(); - if(type == PacketType.AgentResume) return new AgentResumePacket(); - if(type == PacketType.ChatFromViewer) return new ChatFromViewerPacket(); - if(type == PacketType.AgentThrottle) return new AgentThrottlePacket(); - if(type == PacketType.AgentFOV) return new AgentFOVPacket(); - if(type == PacketType.AgentHeightWidth) return new AgentHeightWidthPacket(); - if(type == PacketType.AgentSetAppearance) return new AgentSetAppearancePacket(); - if(type == PacketType.AgentQuitCopy) return new AgentQuitCopyPacket(); - if(type == PacketType.ImageNotInDatabase) return new ImageNotInDatabasePacket(); - if(type == PacketType.RebakeAvatarTextures) return new RebakeAvatarTexturesPacket(); - if(type == PacketType.SetAlwaysRun) return new SetAlwaysRunPacket(); - if(type == PacketType.ObjectDelete) return new ObjectDeletePacket(); - if(type == PacketType.ObjectDuplicate) return new ObjectDuplicatePacket(); - if(type == PacketType.ObjectDuplicateOnRay) return new ObjectDuplicateOnRayPacket(); - if(type == PacketType.ObjectScale) return new ObjectScalePacket(); - if(type == PacketType.ObjectRotation) return new ObjectRotationPacket(); - if(type == PacketType.ObjectFlagUpdate) return new ObjectFlagUpdatePacket(); - if(type == PacketType.ObjectClickAction) return new ObjectClickActionPacket(); - if(type == PacketType.ObjectImage) return new ObjectImagePacket(); - if(type == PacketType.ObjectMaterial) return new ObjectMaterialPacket(); - if(type == PacketType.ObjectShape) return new ObjectShapePacket(); - if(type == PacketType.ObjectExtraParams) return new ObjectExtraParamsPacket(); - if(type == PacketType.ObjectOwner) return new ObjectOwnerPacket(); - if(type == PacketType.ObjectGroup) return new ObjectGroupPacket(); - if(type == PacketType.ObjectBuy) return new ObjectBuyPacket(); - if(type == PacketType.BuyObjectInventory) return new BuyObjectInventoryPacket(); - if(type == PacketType.DerezContainer) return new DerezContainerPacket(); - if(type == PacketType.ObjectPermissions) return new ObjectPermissionsPacket(); - if(type == PacketType.ObjectSaleInfo) return new ObjectSaleInfoPacket(); - if(type == PacketType.ObjectName) return new ObjectNamePacket(); - if(type == PacketType.ObjectDescription) return new ObjectDescriptionPacket(); - if(type == PacketType.ObjectCategory) return new ObjectCategoryPacket(); - if(type == PacketType.ObjectSelect) return new ObjectSelectPacket(); - if(type == PacketType.ObjectDeselect) return new ObjectDeselectPacket(); - if(type == PacketType.ObjectAttach) return new ObjectAttachPacket(); - if(type == PacketType.ObjectDetach) return new ObjectDetachPacket(); - if(type == PacketType.ObjectDrop) return new ObjectDropPacket(); - if(type == PacketType.ObjectLink) return new ObjectLinkPacket(); - if(type == PacketType.ObjectDelink) return new ObjectDelinkPacket(); - if(type == PacketType.ObjectGrab) return new ObjectGrabPacket(); - if(type == PacketType.ObjectGrabUpdate) return new ObjectGrabUpdatePacket(); - if(type == PacketType.ObjectDeGrab) return new ObjectDeGrabPacket(); - if(type == PacketType.ObjectSpinStart) return new ObjectSpinStartPacket(); - if(type == PacketType.ObjectSpinUpdate) return new ObjectSpinUpdatePacket(); - if(type == PacketType.ObjectSpinStop) return new ObjectSpinStopPacket(); - if(type == PacketType.ObjectExportSelected) return new ObjectExportSelectedPacket(); - if(type == PacketType.ModifyLand) return new ModifyLandPacket(); - if(type == PacketType.VelocityInterpolateOn) return new VelocityInterpolateOnPacket(); - if(type == PacketType.VelocityInterpolateOff) return new VelocityInterpolateOffPacket(); - if(type == PacketType.StateSave) return new StateSavePacket(); - if(type == PacketType.ReportAutosaveCrash) return new ReportAutosaveCrashPacket(); - if(type == PacketType.SimWideDeletes) return new SimWideDeletesPacket(); - if(type == PacketType.TrackAgent) return new TrackAgentPacket(); - if(type == PacketType.ViewerStats) return new ViewerStatsPacket(); - if(type == PacketType.ScriptAnswerYes) return new ScriptAnswerYesPacket(); - if(type == PacketType.UserReport) return new UserReportPacket(); - if(type == PacketType.AlertMessage) return new AlertMessagePacket(); - if(type == PacketType.AgentAlertMessage) return new AgentAlertMessagePacket(); - if(type == PacketType.MeanCollisionAlert) return new MeanCollisionAlertPacket(); - if(type == PacketType.ViewerFrozenMessage) return new ViewerFrozenMessagePacket(); - if(type == PacketType.HealthMessage) return new HealthMessagePacket(); - if(type == PacketType.ChatFromSimulator) return new ChatFromSimulatorPacket(); - if(type == PacketType.SimStats) return new SimStatsPacket(); - if(type == PacketType.RequestRegionInfo) return new RequestRegionInfoPacket(); - if(type == PacketType.RegionInfo) return new RegionInfoPacket(); - if(type == PacketType.GodUpdateRegionInfo) return new GodUpdateRegionInfoPacket(); - if(type == PacketType.RegionHandshake) return new RegionHandshakePacket(); - if(type == PacketType.RegionHandshakeReply) return new RegionHandshakeReplyPacket(); - if(type == PacketType.SimulatorViewerTimeMessage) return new SimulatorViewerTimeMessagePacket(); - if(type == PacketType.EnableSimulator) return new EnableSimulatorPacket(); - if(type == PacketType.DisableSimulator) return new DisableSimulatorPacket(); - if(type == PacketType.TransferRequest) return new TransferRequestPacket(); - if(type == PacketType.TransferInfo) return new TransferInfoPacket(); - if(type == PacketType.TransferAbort) return new TransferAbortPacket(); - if(type == PacketType.RequestXfer) return new RequestXferPacket(); - if(type == PacketType.AbortXfer) return new AbortXferPacket(); - if(type == PacketType.AvatarAppearance) return new AvatarAppearancePacket(); - if(type == PacketType.SetFollowCamProperties) return new SetFollowCamPropertiesPacket(); - if(type == PacketType.ClearFollowCamProperties) return new ClearFollowCamPropertiesPacket(); - if(type == PacketType.RequestPayPrice) return new RequestPayPricePacket(); - if(type == PacketType.PayPriceReply) return new PayPriceReplyPacket(); - if(type == PacketType.KickUser) return new KickUserPacket(); - if(type == PacketType.GodKickUser) return new GodKickUserPacket(); - if(type == PacketType.EjectUser) return new EjectUserPacket(); - if(type == PacketType.FreezeUser) return new FreezeUserPacket(); - if(type == PacketType.AvatarPropertiesRequest) return new AvatarPropertiesRequestPacket(); - if(type == PacketType.AvatarPropertiesReply) return new AvatarPropertiesReplyPacket(); - if(type == PacketType.AvatarInterestsReply) return new AvatarInterestsReplyPacket(); - if(type == PacketType.AvatarGroupsReply) return new AvatarGroupsReplyPacket(); - if(type == PacketType.AvatarPropertiesUpdate) return new AvatarPropertiesUpdatePacket(); - if(type == PacketType.AvatarInterestsUpdate) return new AvatarInterestsUpdatePacket(); - if(type == PacketType.AvatarNotesReply) return new AvatarNotesReplyPacket(); - if(type == PacketType.AvatarNotesUpdate) return new AvatarNotesUpdatePacket(); - if(type == PacketType.AvatarPicksReply) return new AvatarPicksReplyPacket(); - if(type == PacketType.EventInfoRequest) return new EventInfoRequestPacket(); - if(type == PacketType.EventInfoReply) return new EventInfoReplyPacket(); - if(type == PacketType.EventNotificationAddRequest) return new EventNotificationAddRequestPacket(); - if(type == PacketType.EventNotificationRemoveRequest) return new EventNotificationRemoveRequestPacket(); - if(type == PacketType.EventGodDelete) return new EventGodDeletePacket(); - if(type == PacketType.PickInfoReply) return new PickInfoReplyPacket(); - if(type == PacketType.PickInfoUpdate) return new PickInfoUpdatePacket(); - if(type == PacketType.PickDelete) return new PickDeletePacket(); - if(type == PacketType.PickGodDelete) return new PickGodDeletePacket(); - if(type == PacketType.ScriptQuestion) return new ScriptQuestionPacket(); - if(type == PacketType.ScriptControlChange) return new ScriptControlChangePacket(); - if(type == PacketType.ScriptDialog) return new ScriptDialogPacket(); - if(type == PacketType.ScriptDialogReply) return new ScriptDialogReplyPacket(); - if(type == PacketType.ForceScriptControlRelease) return new ForceScriptControlReleasePacket(); - if(type == PacketType.RevokePermissions) return new RevokePermissionsPacket(); - if(type == PacketType.LoadURL) return new LoadURLPacket(); - if(type == PacketType.ScriptTeleportRequest) return new ScriptTeleportRequestPacket(); - if(type == PacketType.ParcelOverlay) return new ParcelOverlayPacket(); - if(type == PacketType.ParcelPropertiesRequestByID) return new ParcelPropertiesRequestByIDPacket(); - if(type == PacketType.ParcelPropertiesUpdate) return new ParcelPropertiesUpdatePacket(); - if(type == PacketType.ParcelReturnObjects) return new ParcelReturnObjectsPacket(); - if(type == PacketType.ParcelSetOtherCleanTime) return new ParcelSetOtherCleanTimePacket(); - if(type == PacketType.ParcelDisableObjects) return new ParcelDisableObjectsPacket(); - if(type == PacketType.ParcelSelectObjects) return new ParcelSelectObjectsPacket(); - if(type == PacketType.EstateCovenantRequest) return new EstateCovenantRequestPacket(); - if(type == PacketType.EstateCovenantReply) return new EstateCovenantReplyPacket(); - if(type == PacketType.ForceObjectSelect) return new ForceObjectSelectPacket(); - if(type == PacketType.ParcelBuyPass) return new ParcelBuyPassPacket(); - if(type == PacketType.ParcelDeedToGroup) return new ParcelDeedToGroupPacket(); - if(type == PacketType.ParcelReclaim) return new ParcelReclaimPacket(); - if(type == PacketType.ParcelClaim) return new ParcelClaimPacket(); - if(type == PacketType.ParcelJoin) return new ParcelJoinPacket(); - if(type == PacketType.ParcelDivide) return new ParcelDividePacket(); - if(type == PacketType.ParcelRelease) return new ParcelReleasePacket(); - if(type == PacketType.ParcelBuy) return new ParcelBuyPacket(); - if(type == PacketType.ParcelGodForceOwner) return new ParcelGodForceOwnerPacket(); - if(type == PacketType.ParcelAccessListRequest) return new ParcelAccessListRequestPacket(); - if(type == PacketType.ParcelAccessListReply) return new ParcelAccessListReplyPacket(); - if(type == PacketType.ParcelAccessListUpdate) return new ParcelAccessListUpdatePacket(); - if(type == PacketType.ParcelDwellRequest) return new ParcelDwellRequestPacket(); - if(type == PacketType.ParcelDwellReply) return new ParcelDwellReplyPacket(); - if(type == PacketType.ParcelGodMarkAsContent) return new ParcelGodMarkAsContentPacket(); - if(type == PacketType.ViewerStartAuction) return new ViewerStartAuctionPacket(); - if(type == PacketType.UUIDNameRequest) return new UUIDNameRequestPacket(); - if(type == PacketType.UUIDNameReply) return new UUIDNameReplyPacket(); - if(type == PacketType.UUIDGroupNameRequest) return new UUIDGroupNameRequestPacket(); - if(type == PacketType.UUIDGroupNameReply) return new UUIDGroupNameReplyPacket(); - if(type == PacketType.ChildAgentDying) return new ChildAgentDyingPacket(); - if(type == PacketType.ChildAgentUnknown) return new ChildAgentUnknownPacket(); - if(type == PacketType.GetScriptRunning) return new GetScriptRunningPacket(); - if(type == PacketType.ScriptRunningReply) return new ScriptRunningReplyPacket(); - if(type == PacketType.SetScriptRunning) return new SetScriptRunningPacket(); - if(type == PacketType.ScriptReset) return new ScriptResetPacket(); - if(type == PacketType.ScriptSensorRequest) return new ScriptSensorRequestPacket(); - if(type == PacketType.ScriptSensorReply) return new ScriptSensorReplyPacket(); - if(type == PacketType.CompleteAgentMovement) return new CompleteAgentMovementPacket(); - if(type == PacketType.AgentMovementComplete) return new AgentMovementCompletePacket(); - if(type == PacketType.LogoutRequest) return new LogoutRequestPacket(); - if(type == PacketType.LogoutReply) return new LogoutReplyPacket(); - if(type == PacketType.ImprovedInstantMessage) return new ImprovedInstantMessagePacket(); - if(type == PacketType.RetrieveInstantMessages) return new RetrieveInstantMessagesPacket(); - if(type == PacketType.FindAgent) return new FindAgentPacket(); - if(type == PacketType.RequestGodlikePowers) return new RequestGodlikePowersPacket(); - if(type == PacketType.GrantGodlikePowers) return new GrantGodlikePowersPacket(); - if(type == PacketType.GodlikeMessage) return new GodlikeMessagePacket(); - if(type == PacketType.EstateOwnerMessage) return new EstateOwnerMessagePacket(); - if(type == PacketType.GenericMessage) return new GenericMessagePacket(); - if(type == PacketType.MuteListRequest) return new MuteListRequestPacket(); - if(type == PacketType.UpdateMuteListEntry) return new UpdateMuteListEntryPacket(); - if(type == PacketType.RemoveMuteListEntry) return new RemoveMuteListEntryPacket(); - if(type == PacketType.CopyInventoryFromNotecard) return new CopyInventoryFromNotecardPacket(); - if(type == PacketType.UpdateInventoryItem) return new UpdateInventoryItemPacket(); - if(type == PacketType.UpdateCreateInventoryItem) return new UpdateCreateInventoryItemPacket(); - if(type == PacketType.MoveInventoryItem) return new MoveInventoryItemPacket(); - if(type == PacketType.CopyInventoryItem) return new CopyInventoryItemPacket(); - if(type == PacketType.RemoveInventoryItem) return new RemoveInventoryItemPacket(); - if(type == PacketType.ChangeInventoryItemFlags) return new ChangeInventoryItemFlagsPacket(); - if(type == PacketType.SaveAssetIntoInventory) return new SaveAssetIntoInventoryPacket(); - if(type == PacketType.CreateInventoryFolder) return new CreateInventoryFolderPacket(); - if(type == PacketType.UpdateInventoryFolder) return new UpdateInventoryFolderPacket(); - if(type == PacketType.MoveInventoryFolder) return new MoveInventoryFolderPacket(); - if(type == PacketType.RemoveInventoryFolder) return new RemoveInventoryFolderPacket(); - if(type == PacketType.FetchInventoryDescendents) return new FetchInventoryDescendentsPacket(); - if(type == PacketType.InventoryDescendents) return new InventoryDescendentsPacket(); - if(type == PacketType.FetchInventory) return new FetchInventoryPacket(); - if(type == PacketType.FetchInventoryReply) return new FetchInventoryReplyPacket(); - if(type == PacketType.BulkUpdateInventory) return new BulkUpdateInventoryPacket(); - if(type == PacketType.RemoveInventoryObjects) return new RemoveInventoryObjectsPacket(); - if(type == PacketType.PurgeInventoryDescendents) return new PurgeInventoryDescendentsPacket(); - if(type == PacketType.UpdateTaskInventory) return new UpdateTaskInventoryPacket(); - if(type == PacketType.RemoveTaskInventory) return new RemoveTaskInventoryPacket(); - if(type == PacketType.MoveTaskInventory) return new MoveTaskInventoryPacket(); - if(type == PacketType.RequestTaskInventory) return new RequestTaskInventoryPacket(); - if(type == PacketType.ReplyTaskInventory) return new ReplyTaskInventoryPacket(); - if(type == PacketType.DeRezObject) return new DeRezObjectPacket(); - if(type == PacketType.DeRezAck) return new DeRezAckPacket(); - if(type == PacketType.RezObject) return new RezObjectPacket(); - if(type == PacketType.RezObjectFromNotecard) return new RezObjectFromNotecardPacket(); - if(type == PacketType.AcceptFriendship) return new AcceptFriendshipPacket(); - if(type == PacketType.DeclineFriendship) return new DeclineFriendshipPacket(); - if(type == PacketType.TerminateFriendship) return new TerminateFriendshipPacket(); - if(type == PacketType.OfferCallingCard) return new OfferCallingCardPacket(); - if(type == PacketType.AcceptCallingCard) return new AcceptCallingCardPacket(); - if(type == PacketType.DeclineCallingCard) return new DeclineCallingCardPacket(); - if(type == PacketType.RezScript) return new RezScriptPacket(); - if(type == PacketType.CreateInventoryItem) return new CreateInventoryItemPacket(); - if(type == PacketType.CreateLandmarkForEvent) return new CreateLandmarkForEventPacket(); - if(type == PacketType.RegionHandleRequest) return new RegionHandleRequestPacket(); - if(type == PacketType.RegionIDAndHandleReply) return new RegionIDAndHandleReplyPacket(); - if(type == PacketType.MoneyTransferRequest) return new MoneyTransferRequestPacket(); - if(type == PacketType.MoneyBalanceRequest) return new MoneyBalanceRequestPacket(); - if(type == PacketType.MoneyBalanceReply) return new MoneyBalanceReplyPacket(); - if(type == PacketType.RoutedMoneyBalanceReply) return new RoutedMoneyBalanceReplyPacket(); - if(type == PacketType.ActivateGestures) return new ActivateGesturesPacket(); - if(type == PacketType.DeactivateGestures) return new DeactivateGesturesPacket(); - if(type == PacketType.MuteListUpdate) return new MuteListUpdatePacket(); - if(type == PacketType.UseCachedMuteList) return new UseCachedMuteListPacket(); - if(type == PacketType.GrantUserRights) return new GrantUserRightsPacket(); - if(type == PacketType.ChangeUserRights) return new ChangeUserRightsPacket(); - if(type == PacketType.OnlineNotification) return new OnlineNotificationPacket(); - if(type == PacketType.OfflineNotification) return new OfflineNotificationPacket(); - if(type == PacketType.SetStartLocationRequest) return new SetStartLocationRequestPacket(); - if(type == PacketType.AssetUploadRequest) return new AssetUploadRequestPacket(); - if(type == PacketType.AssetUploadComplete) return new AssetUploadCompletePacket(); - if(type == PacketType.CreateGroupRequest) return new CreateGroupRequestPacket(); - if(type == PacketType.CreateGroupReply) return new CreateGroupReplyPacket(); - if(type == PacketType.UpdateGroupInfo) return new UpdateGroupInfoPacket(); - if(type == PacketType.GroupRoleChanges) return new GroupRoleChangesPacket(); - if(type == PacketType.JoinGroupRequest) return new JoinGroupRequestPacket(); - if(type == PacketType.JoinGroupReply) return new JoinGroupReplyPacket(); - if(type == PacketType.EjectGroupMemberRequest) return new EjectGroupMemberRequestPacket(); - if(type == PacketType.EjectGroupMemberReply) return new EjectGroupMemberReplyPacket(); - if(type == PacketType.LeaveGroupRequest) return new LeaveGroupRequestPacket(); - if(type == PacketType.LeaveGroupReply) return new LeaveGroupReplyPacket(); - if(type == PacketType.InviteGroupRequest) return new InviteGroupRequestPacket(); - if(type == PacketType.GroupProfileRequest) return new GroupProfileRequestPacket(); - if(type == PacketType.GroupProfileReply) return new GroupProfileReplyPacket(); - if(type == PacketType.GroupAccountSummaryRequest) return new GroupAccountSummaryRequestPacket(); - if(type == PacketType.GroupAccountSummaryReply) return new GroupAccountSummaryReplyPacket(); - if(type == PacketType.GroupAccountDetailsRequest) return new GroupAccountDetailsRequestPacket(); - if(type == PacketType.GroupAccountDetailsReply) return new GroupAccountDetailsReplyPacket(); - if(type == PacketType.GroupAccountTransactionsRequest) return new GroupAccountTransactionsRequestPacket(); - if(type == PacketType.GroupAccountTransactionsReply) return new GroupAccountTransactionsReplyPacket(); - if(type == PacketType.GroupActiveProposalsRequest) return new GroupActiveProposalsRequestPacket(); - if(type == PacketType.GroupActiveProposalItemReply) return new GroupActiveProposalItemReplyPacket(); - if(type == PacketType.GroupVoteHistoryRequest) return new GroupVoteHistoryRequestPacket(); - if(type == PacketType.GroupVoteHistoryItemReply) return new GroupVoteHistoryItemReplyPacket(); - if(type == PacketType.StartGroupProposal) return new StartGroupProposalPacket(); - if(type == PacketType.GroupProposalBallot) return new GroupProposalBallotPacket(); - if(type == PacketType.GroupMembersRequest) return new GroupMembersRequestPacket(); - if(type == PacketType.GroupMembersReply) return new GroupMembersReplyPacket(); - if(type == PacketType.ActivateGroup) return new ActivateGroupPacket(); - if(type == PacketType.SetGroupContribution) return new SetGroupContributionPacket(); - if(type == PacketType.SetGroupAcceptNotices) return new SetGroupAcceptNoticesPacket(); - if(type == PacketType.GroupRoleDataRequest) return new GroupRoleDataRequestPacket(); - if(type == PacketType.GroupRoleDataReply) return new GroupRoleDataReplyPacket(); - if(type == PacketType.GroupRoleMembersRequest) return new GroupRoleMembersRequestPacket(); - if(type == PacketType.GroupRoleMembersReply) return new GroupRoleMembersReplyPacket(); - if(type == PacketType.GroupTitlesRequest) return new GroupTitlesRequestPacket(); - if(type == PacketType.GroupTitlesReply) return new GroupTitlesReplyPacket(); - if(type == PacketType.GroupTitleUpdate) return new GroupTitleUpdatePacket(); - if(type == PacketType.GroupRoleUpdate) return new GroupRoleUpdatePacket(); - if(type == PacketType.LiveHelpGroupRequest) return new LiveHelpGroupRequestPacket(); - if(type == PacketType.LiveHelpGroupReply) return new LiveHelpGroupReplyPacket(); - if(type == PacketType.AgentWearablesRequest) return new AgentWearablesRequestPacket(); - if(type == PacketType.AgentWearablesUpdate) return new AgentWearablesUpdatePacket(); - if(type == PacketType.AgentIsNowWearing) return new AgentIsNowWearingPacket(); - if(type == PacketType.AgentCachedTexture) return new AgentCachedTexturePacket(); - if(type == PacketType.AgentCachedTextureResponse) return new AgentCachedTextureResponsePacket(); - if(type == PacketType.AgentDataUpdateRequest) return new AgentDataUpdateRequestPacket(); - if(type == PacketType.AgentDataUpdate) return new AgentDataUpdatePacket(); - if(type == PacketType.GroupDataUpdate) return new GroupDataUpdatePacket(); - if(type == PacketType.AgentGroupDataUpdate) return new AgentGroupDataUpdatePacket(); - if(type == PacketType.AgentDropGroup) return new AgentDropGroupPacket(); - if(type == PacketType.RezSingleAttachmentFromInv) return new RezSingleAttachmentFromInvPacket(); - if(type == PacketType.RezMultipleAttachmentsFromInv) return new RezMultipleAttachmentsFromInvPacket(); - if(type == PacketType.DetachAttachmentIntoInv) return new DetachAttachmentIntoInvPacket(); - if(type == PacketType.CreateNewOutfitAttachments) return new CreateNewOutfitAttachmentsPacket(); - if(type == PacketType.UserInfoRequest) return new UserInfoRequestPacket(); - if(type == PacketType.UserInfoReply) return new UserInfoReplyPacket(); - if(type == PacketType.UpdateUserInfo) return new UpdateUserInfoPacket(); - if(type == PacketType.InitiateDownload) return new InitiateDownloadPacket(); - if(type == PacketType.MapLayerRequest) return new MapLayerRequestPacket(); - if(type == PacketType.MapLayerReply) return new MapLayerReplyPacket(); - if(type == PacketType.MapBlockRequest) return new MapBlockRequestPacket(); - if(type == PacketType.MapNameRequest) return new MapNameRequestPacket(); - if(type == PacketType.MapBlockReply) return new MapBlockReplyPacket(); - if(type == PacketType.MapItemRequest) return new MapItemRequestPacket(); - if(type == PacketType.MapItemReply) return new MapItemReplyPacket(); - if(type == PacketType.SendPostcard) return new SendPostcardPacket(); - if(type == PacketType.ParcelMediaCommandMessage) return new ParcelMediaCommandMessagePacket(); - if(type == PacketType.ParcelMediaUpdate) return new ParcelMediaUpdatePacket(); - if(type == PacketType.LandStatRequest) return new LandStatRequestPacket(); - if(type == PacketType.LandStatReply) return new LandStatReplyPacket(); - if(type == PacketType.Error) return new ErrorPacket(); - if(type == PacketType.ObjectIncludeInSearch) return new ObjectIncludeInSearchPacket(); - if(type == PacketType.RezRestoreToWorld) return new RezRestoreToWorldPacket(); - if(type == PacketType.LinkInventoryItem) return new LinkInventoryItemPacket(); - if(type == PacketType.LargeGenericMessage) return new LargeGenericMessagePacket(); - if(type == PacketType.PacketAck) return new PacketAckPacket(); - if(type == PacketType.OpenCircuit) return new OpenCircuitPacket(); - if(type == PacketType.CloseCircuit) return new CloseCircuitPacket(); - return null; - - } - - public static Packet BuildPacket(byte[] packetBuffer, ref int packetEnd, byte[] zeroBuffer) + public static Packet BuildPacket(PacketType type) + { + switch(type) + { + case PacketType.StartPingCheck: return new StartPingCheckPacket(); + case PacketType.CompletePingCheck: return new CompletePingCheckPacket(); + case PacketType.AgentUpdate: return new AgentUpdatePacket(); + case PacketType.AgentAnimation: return new AgentAnimationPacket(); + case PacketType.AgentRequestSit: return new AgentRequestSitPacket(); + case PacketType.AgentSit: return new AgentSitPacket(); + case PacketType.RequestImage: return new RequestImagePacket(); + case PacketType.ImageData: return new ImageDataPacket(); + case PacketType.ImagePacket: return new ImagePacketPacket(); + case PacketType.LayerData: return new LayerDataPacket(); + case PacketType.ObjectUpdate: return new ObjectUpdatePacket(); + case PacketType.ObjectUpdateCompressed: return new ObjectUpdateCompressedPacket(); + case PacketType.ObjectUpdateCached: return new ObjectUpdateCachedPacket(); + case PacketType.ImprovedTerseObjectUpdate: return new ImprovedTerseObjectUpdatePacket(); + case PacketType.KillObject: return new KillObjectPacket(); + case PacketType.TransferPacket: return new TransferPacketPacket(); + case PacketType.SendXferPacket: return new SendXferPacketPacket(); + case PacketType.ConfirmXferPacket: return new ConfirmXferPacketPacket(); + case PacketType.AvatarAnimation: return new AvatarAnimationPacket(); + case PacketType.AvatarSitResponse: return new AvatarSitResponsePacket(); + case PacketType.CameraConstraint: return new CameraConstraintPacket(); + case PacketType.ParcelProperties: return new ParcelPropertiesPacket(); + case PacketType.ChildAgentUpdate: return new ChildAgentUpdatePacket(); + case PacketType.ChildAgentAlive: return new ChildAgentAlivePacket(); + case PacketType.ChildAgentPositionUpdate: return new ChildAgentPositionUpdatePacket(); + case PacketType.SoundTrigger: return new SoundTriggerPacket(); + case PacketType.ObjectAnimation: return new ObjectAnimationPacket(); + case PacketType.ObjectAdd: return new ObjectAddPacket(); + case PacketType.MultipleObjectUpdate: return new MultipleObjectUpdatePacket(); + case PacketType.RequestMultipleObjects: return new RequestMultipleObjectsPacket(); + case PacketType.ObjectPosition: return new ObjectPositionPacket(); + case PacketType.RequestObjectPropertiesFamily: return new RequestObjectPropertiesFamilyPacket(); + case PacketType.CoarseLocationUpdate: return new CoarseLocationUpdatePacket(); + case PacketType.CrossedRegion: return new CrossedRegionPacket(); + case PacketType.ConfirmEnableSimulator: return new ConfirmEnableSimulatorPacket(); + case PacketType.ObjectProperties: return new ObjectPropertiesPacket(); + case PacketType.ObjectPropertiesFamily: return new ObjectPropertiesFamilyPacket(); + case PacketType.ParcelPropertiesRequest: return new ParcelPropertiesRequestPacket(); + case PacketType.AttachedSound: return new AttachedSoundPacket(); + case PacketType.AttachedSoundGainChange: return new AttachedSoundGainChangePacket(); + case PacketType.PreloadSound: return new PreloadSoundPacket(); + case PacketType.ViewerEffect: return new ViewerEffectPacket(); + case PacketType.TestMessage: return new TestMessagePacket(); + case PacketType.UseCircuitCode: return new UseCircuitCodePacket(); + case PacketType.TelehubInfo: return new TelehubInfoPacket(); + case PacketType.EconomyDataRequest: return new EconomyDataRequestPacket(); + case PacketType.EconomyData: return new EconomyDataPacket(); + case PacketType.AvatarPickerRequest: return new AvatarPickerRequestPacket(); + case PacketType.AvatarPickerReply: return new AvatarPickerReplyPacket(); + case PacketType.PlacesQuery: return new PlacesQueryPacket(); + case PacketType.PlacesReply: return new PlacesReplyPacket(); + case PacketType.DirFindQuery: return new DirFindQueryPacket(); + case PacketType.DirPlacesQuery: return new DirPlacesQueryPacket(); + case PacketType.DirPlacesReply: return new DirPlacesReplyPacket(); + case PacketType.DirPeopleReply: return new DirPeopleReplyPacket(); + case PacketType.DirEventsReply: return new DirEventsReplyPacket(); + case PacketType.DirGroupsReply: return new DirGroupsReplyPacket(); + case PacketType.DirClassifiedQuery: return new DirClassifiedQueryPacket(); + case PacketType.DirClassifiedReply: return new DirClassifiedReplyPacket(); + case PacketType.AvatarClassifiedReply: return new AvatarClassifiedReplyPacket(); + case PacketType.ClassifiedInfoRequest: return new ClassifiedInfoRequestPacket(); + case PacketType.ClassifiedInfoReply: return new ClassifiedInfoReplyPacket(); + case PacketType.ClassifiedInfoUpdate: return new ClassifiedInfoUpdatePacket(); + case PacketType.ClassifiedDelete: return new ClassifiedDeletePacket(); + case PacketType.ClassifiedGodDelete: return new ClassifiedGodDeletePacket(); + case PacketType.DirLandQuery: return new DirLandQueryPacket(); + case PacketType.DirLandReply: return new DirLandReplyPacket(); + case PacketType.DirPopularQuery: return new DirPopularQueryPacket(); + case PacketType.DirPopularReply: return new DirPopularReplyPacket(); + case PacketType.ParcelInfoRequest: return new ParcelInfoRequestPacket(); + case PacketType.ParcelInfoReply: return new ParcelInfoReplyPacket(); + case PacketType.ParcelObjectOwnersRequest: return new ParcelObjectOwnersRequestPacket(); + case PacketType.ParcelObjectOwnersReply: return new ParcelObjectOwnersReplyPacket(); + case PacketType.GroupNoticesListRequest: return new GroupNoticesListRequestPacket(); + case PacketType.GroupNoticesListReply: return new GroupNoticesListReplyPacket(); + case PacketType.GroupNoticeRequest: return new GroupNoticeRequestPacket(); + case PacketType.TeleportRequest: return new TeleportRequestPacket(); + case PacketType.TeleportLocationRequest: return new TeleportLocationRequestPacket(); + case PacketType.TeleportLocal: return new TeleportLocalPacket(); + case PacketType.TeleportLandmarkRequest: return new TeleportLandmarkRequestPacket(); + case PacketType.TeleportProgress: return new TeleportProgressPacket(); + case PacketType.TeleportFinish: return new TeleportFinishPacket(); + case PacketType.StartLure: return new StartLurePacket(); + case PacketType.TeleportLureRequest: return new TeleportLureRequestPacket(); + case PacketType.TeleportCancel: return new TeleportCancelPacket(); + case PacketType.TeleportStart: return new TeleportStartPacket(); + case PacketType.TeleportFailed: return new TeleportFailedPacket(); + case PacketType.Undo: return new UndoPacket(); + case PacketType.Redo: return new RedoPacket(); + case PacketType.UndoLand: return new UndoLandPacket(); + case PacketType.AgentPause: return new AgentPausePacket(); + case PacketType.AgentResume: return new AgentResumePacket(); + case PacketType.ChatFromViewer: return new ChatFromViewerPacket(); + case PacketType.AgentThrottle: return new AgentThrottlePacket(); + case PacketType.AgentFOV: return new AgentFOVPacket(); + case PacketType.AgentHeightWidth: return new AgentHeightWidthPacket(); + case PacketType.AgentSetAppearance: return new AgentSetAppearancePacket(); + case PacketType.AgentQuitCopy: return new AgentQuitCopyPacket(); + case PacketType.ImageNotInDatabase: return new ImageNotInDatabasePacket(); + case PacketType.RebakeAvatarTextures: return new RebakeAvatarTexturesPacket(); + case PacketType.SetAlwaysRun: return new SetAlwaysRunPacket(); + case PacketType.ObjectDelete: return new ObjectDeletePacket(); + case PacketType.ObjectDuplicate: return new ObjectDuplicatePacket(); + case PacketType.ObjectDuplicateOnRay: return new ObjectDuplicateOnRayPacket(); + case PacketType.ObjectScale: return new ObjectScalePacket(); + case PacketType.ObjectRotation: return new ObjectRotationPacket(); + case PacketType.ObjectFlagUpdate: return new ObjectFlagUpdatePacket(); + case PacketType.ObjectClickAction: return new ObjectClickActionPacket(); + case PacketType.ObjectImage: return new ObjectImagePacket(); + case PacketType.ObjectMaterial: return new ObjectMaterialPacket(); + case PacketType.ObjectShape: return new ObjectShapePacket(); + case PacketType.ObjectExtraParams: return new ObjectExtraParamsPacket(); + case PacketType.ObjectOwner: return new ObjectOwnerPacket(); + case PacketType.ObjectGroup: return new ObjectGroupPacket(); + case PacketType.ObjectBuy: return new ObjectBuyPacket(); + case PacketType.BuyObjectInventory: return new BuyObjectInventoryPacket(); + case PacketType.DerezContainer: return new DerezContainerPacket(); + case PacketType.ObjectPermissions: return new ObjectPermissionsPacket(); + case PacketType.ObjectSaleInfo: return new ObjectSaleInfoPacket(); + case PacketType.ObjectName: return new ObjectNamePacket(); + case PacketType.ObjectDescription: return new ObjectDescriptionPacket(); + case PacketType.ObjectCategory: return new ObjectCategoryPacket(); + case PacketType.ObjectSelect: return new ObjectSelectPacket(); + case PacketType.ObjectDeselect: return new ObjectDeselectPacket(); + case PacketType.ObjectAttach: return new ObjectAttachPacket(); + case PacketType.ObjectDetach: return new ObjectDetachPacket(); + case PacketType.ObjectDrop: return new ObjectDropPacket(); + case PacketType.ObjectLink: return new ObjectLinkPacket(); + case PacketType.ObjectDelink: return new ObjectDelinkPacket(); + case PacketType.ObjectGrab: return new ObjectGrabPacket(); + case PacketType.ObjectGrabUpdate: return new ObjectGrabUpdatePacket(); + case PacketType.ObjectDeGrab: return new ObjectDeGrabPacket(); + case PacketType.ObjectSpinStart: return new ObjectSpinStartPacket(); + case PacketType.ObjectSpinUpdate: return new ObjectSpinUpdatePacket(); + case PacketType.ObjectSpinStop: return new ObjectSpinStopPacket(); + case PacketType.ObjectExportSelected: return new ObjectExportSelectedPacket(); + case PacketType.ModifyLand: return new ModifyLandPacket(); + case PacketType.VelocityInterpolateOn: return new VelocityInterpolateOnPacket(); + case PacketType.VelocityInterpolateOff: return new VelocityInterpolateOffPacket(); + case PacketType.StateSave: return new StateSavePacket(); + case PacketType.ReportAutosaveCrash: return new ReportAutosaveCrashPacket(); + case PacketType.SimWideDeletes: return new SimWideDeletesPacket(); + case PacketType.TrackAgent: return new TrackAgentPacket(); + case PacketType.ViewerStats: return new ViewerStatsPacket(); + case PacketType.ScriptAnswerYes: return new ScriptAnswerYesPacket(); + case PacketType.UserReport: return new UserReportPacket(); + case PacketType.AlertMessage: return new AlertMessagePacket(); + case PacketType.AgentAlertMessage: return new AgentAlertMessagePacket(); + case PacketType.MeanCollisionAlert: return new MeanCollisionAlertPacket(); + case PacketType.ViewerFrozenMessage: return new ViewerFrozenMessagePacket(); + case PacketType.HealthMessage: return new HealthMessagePacket(); + case PacketType.ChatFromSimulator: return new ChatFromSimulatorPacket(); + case PacketType.SimStats: return new SimStatsPacket(); + case PacketType.RequestRegionInfo: return new RequestRegionInfoPacket(); + case PacketType.RegionInfo: return new RegionInfoPacket(); + case PacketType.GodUpdateRegionInfo: return new GodUpdateRegionInfoPacket(); + case PacketType.RegionHandshake: return new RegionHandshakePacket(); + case PacketType.RegionHandshakeReply: return new RegionHandshakeReplyPacket(); + case PacketType.SimulatorViewerTimeMessage: return new SimulatorViewerTimeMessagePacket(); + case PacketType.EnableSimulator: return new EnableSimulatorPacket(); + case PacketType.DisableSimulator: return new DisableSimulatorPacket(); + case PacketType.TransferRequest: return new TransferRequestPacket(); + case PacketType.TransferInfo: return new TransferInfoPacket(); + case PacketType.TransferAbort: return new TransferAbortPacket(); + case PacketType.RequestXfer: return new RequestXferPacket(); + case PacketType.AbortXfer: return new AbortXferPacket(); + case PacketType.AvatarAppearance: return new AvatarAppearancePacket(); + case PacketType.SetFollowCamProperties: return new SetFollowCamPropertiesPacket(); + case PacketType.ClearFollowCamProperties: return new ClearFollowCamPropertiesPacket(); + case PacketType.RequestPayPrice: return new RequestPayPricePacket(); + case PacketType.PayPriceReply: return new PayPriceReplyPacket(); + case PacketType.KickUser: return new KickUserPacket(); + case PacketType.GodKickUser: return new GodKickUserPacket(); + case PacketType.EjectUser: return new EjectUserPacket(); + case PacketType.FreezeUser: return new FreezeUserPacket(); + case PacketType.AvatarPropertiesRequest: return new AvatarPropertiesRequestPacket(); + case PacketType.AvatarPropertiesReply: return new AvatarPropertiesReplyPacket(); + case PacketType.AvatarInterestsReply: return new AvatarInterestsReplyPacket(); + case PacketType.AvatarGroupsReply: return new AvatarGroupsReplyPacket(); + case PacketType.AvatarPropertiesUpdate: return new AvatarPropertiesUpdatePacket(); + case PacketType.AvatarInterestsUpdate: return new AvatarInterestsUpdatePacket(); + case PacketType.AvatarNotesReply: return new AvatarNotesReplyPacket(); + case PacketType.AvatarNotesUpdate: return new AvatarNotesUpdatePacket(); + case PacketType.AvatarPicksReply: return new AvatarPicksReplyPacket(); + case PacketType.EventInfoRequest: return new EventInfoRequestPacket(); + case PacketType.EventInfoReply: return new EventInfoReplyPacket(); + case PacketType.EventNotificationAddRequest: return new EventNotificationAddRequestPacket(); + case PacketType.EventNotificationRemoveRequest: return new EventNotificationRemoveRequestPacket(); + case PacketType.EventGodDelete: return new EventGodDeletePacket(); + case PacketType.PickInfoReply: return new PickInfoReplyPacket(); + case PacketType.PickInfoUpdate: return new PickInfoUpdatePacket(); + case PacketType.PickDelete: return new PickDeletePacket(); + case PacketType.PickGodDelete: return new PickGodDeletePacket(); + case PacketType.ScriptQuestion: return new ScriptQuestionPacket(); + case PacketType.ScriptControlChange: return new ScriptControlChangePacket(); + case PacketType.ScriptDialog: return new ScriptDialogPacket(); + case PacketType.ScriptDialogReply: return new ScriptDialogReplyPacket(); + case PacketType.ForceScriptControlRelease: return new ForceScriptControlReleasePacket(); + case PacketType.RevokePermissions: return new RevokePermissionsPacket(); + case PacketType.LoadURL: return new LoadURLPacket(); + case PacketType.ScriptTeleportRequest: return new ScriptTeleportRequestPacket(); + case PacketType.ParcelOverlay: return new ParcelOverlayPacket(); + case PacketType.ParcelPropertiesRequestByID: return new ParcelPropertiesRequestByIDPacket(); + case PacketType.ParcelPropertiesUpdate: return new ParcelPropertiesUpdatePacket(); + case PacketType.ParcelReturnObjects: return new ParcelReturnObjectsPacket(); + case PacketType.ParcelSetOtherCleanTime: return new ParcelSetOtherCleanTimePacket(); + case PacketType.ParcelDisableObjects: return new ParcelDisableObjectsPacket(); + case PacketType.ParcelSelectObjects: return new ParcelSelectObjectsPacket(); + case PacketType.EstateCovenantRequest: return new EstateCovenantRequestPacket(); + case PacketType.EstateCovenantReply: return new EstateCovenantReplyPacket(); + case PacketType.ForceObjectSelect: return new ForceObjectSelectPacket(); + case PacketType.ParcelBuyPass: return new ParcelBuyPassPacket(); + case PacketType.ParcelDeedToGroup: return new ParcelDeedToGroupPacket(); + case PacketType.ParcelReclaim: return new ParcelReclaimPacket(); + case PacketType.ParcelClaim: return new ParcelClaimPacket(); + case PacketType.ParcelJoin: return new ParcelJoinPacket(); + case PacketType.ParcelDivide: return new ParcelDividePacket(); + case PacketType.ParcelRelease: return new ParcelReleasePacket(); + case PacketType.ParcelBuy: return new ParcelBuyPacket(); + case PacketType.ParcelGodForceOwner: return new ParcelGodForceOwnerPacket(); + case PacketType.ParcelAccessListRequest: return new ParcelAccessListRequestPacket(); + case PacketType.ParcelAccessListReply: return new ParcelAccessListReplyPacket(); + case PacketType.ParcelAccessListUpdate: return new ParcelAccessListUpdatePacket(); + case PacketType.ParcelDwellRequest: return new ParcelDwellRequestPacket(); + case PacketType.ParcelDwellReply: return new ParcelDwellReplyPacket(); + case PacketType.ParcelGodMarkAsContent: return new ParcelGodMarkAsContentPacket(); + case PacketType.ViewerStartAuction: return new ViewerStartAuctionPacket(); + case PacketType.UUIDNameRequest: return new UUIDNameRequestPacket(); + case PacketType.UUIDNameReply: return new UUIDNameReplyPacket(); + case PacketType.UUIDGroupNameRequest: return new UUIDGroupNameRequestPacket(); + case PacketType.UUIDGroupNameReply: return new UUIDGroupNameReplyPacket(); + case PacketType.ChildAgentDying: return new ChildAgentDyingPacket(); + case PacketType.ChildAgentUnknown: return new ChildAgentUnknownPacket(); + case PacketType.GetScriptRunning: return new GetScriptRunningPacket(); + case PacketType.ScriptRunningReply: return new ScriptRunningReplyPacket(); + case PacketType.SetScriptRunning: return new SetScriptRunningPacket(); + case PacketType.ScriptReset: return new ScriptResetPacket(); + case PacketType.ScriptSensorRequest: return new ScriptSensorRequestPacket(); + case PacketType.ScriptSensorReply: return new ScriptSensorReplyPacket(); + case PacketType.CompleteAgentMovement: return new CompleteAgentMovementPacket(); + case PacketType.AgentMovementComplete: return new AgentMovementCompletePacket(); + case PacketType.LogoutRequest: return new LogoutRequestPacket(); + case PacketType.LogoutReply: return new LogoutReplyPacket(); + case PacketType.ImprovedInstantMessage: return new ImprovedInstantMessagePacket(); + case PacketType.RetrieveInstantMessages: return new RetrieveInstantMessagesPacket(); + case PacketType.FindAgent: return new FindAgentPacket(); + case PacketType.RequestGodlikePowers: return new RequestGodlikePowersPacket(); + case PacketType.GrantGodlikePowers: return new GrantGodlikePowersPacket(); + case PacketType.GodlikeMessage: return new GodlikeMessagePacket(); + case PacketType.EstateOwnerMessage: return new EstateOwnerMessagePacket(); + case PacketType.GenericMessage: return new GenericMessagePacket(); + case PacketType.MuteListRequest: return new MuteListRequestPacket(); + case PacketType.UpdateMuteListEntry: return new UpdateMuteListEntryPacket(); + case PacketType.RemoveMuteListEntry: return new RemoveMuteListEntryPacket(); + case PacketType.CopyInventoryFromNotecard: return new CopyInventoryFromNotecardPacket(); + case PacketType.UpdateInventoryItem: return new UpdateInventoryItemPacket(); + case PacketType.UpdateCreateInventoryItem: return new UpdateCreateInventoryItemPacket(); + case PacketType.MoveInventoryItem: return new MoveInventoryItemPacket(); + case PacketType.CopyInventoryItem: return new CopyInventoryItemPacket(); + case PacketType.RemoveInventoryItem: return new RemoveInventoryItemPacket(); + case PacketType.ChangeInventoryItemFlags: return new ChangeInventoryItemFlagsPacket(); + case PacketType.SaveAssetIntoInventory: return new SaveAssetIntoInventoryPacket(); + case PacketType.CreateInventoryFolder: return new CreateInventoryFolderPacket(); + case PacketType.UpdateInventoryFolder: return new UpdateInventoryFolderPacket(); + case PacketType.MoveInventoryFolder: return new MoveInventoryFolderPacket(); + case PacketType.RemoveInventoryFolder: return new RemoveInventoryFolderPacket(); + case PacketType.FetchInventoryDescendents: return new FetchInventoryDescendentsPacket(); + case PacketType.InventoryDescendents: return new InventoryDescendentsPacket(); + case PacketType.FetchInventory: return new FetchInventoryPacket(); + case PacketType.FetchInventoryReply: return new FetchInventoryReplyPacket(); + case PacketType.BulkUpdateInventory: return new BulkUpdateInventoryPacket(); + case PacketType.RemoveInventoryObjects: return new RemoveInventoryObjectsPacket(); + case PacketType.PurgeInventoryDescendents: return new PurgeInventoryDescendentsPacket(); + case PacketType.UpdateTaskInventory: return new UpdateTaskInventoryPacket(); + case PacketType.RemoveTaskInventory: return new RemoveTaskInventoryPacket(); + case PacketType.MoveTaskInventory: return new MoveTaskInventoryPacket(); + case PacketType.RequestTaskInventory: return new RequestTaskInventoryPacket(); + case PacketType.ReplyTaskInventory: return new ReplyTaskInventoryPacket(); + case PacketType.DeRezObject: return new DeRezObjectPacket(); + case PacketType.DeRezAck: return new DeRezAckPacket(); + case PacketType.RezObject: return new RezObjectPacket(); + case PacketType.RezObjectFromNotecard: return new RezObjectFromNotecardPacket(); + case PacketType.AcceptFriendship: return new AcceptFriendshipPacket(); + case PacketType.DeclineFriendship: return new DeclineFriendshipPacket(); + case PacketType.TerminateFriendship: return new TerminateFriendshipPacket(); + case PacketType.OfferCallingCard: return new OfferCallingCardPacket(); + case PacketType.AcceptCallingCard: return new AcceptCallingCardPacket(); + case PacketType.DeclineCallingCard: return new DeclineCallingCardPacket(); + case PacketType.RezScript: return new RezScriptPacket(); + case PacketType.CreateInventoryItem: return new CreateInventoryItemPacket(); + case PacketType.CreateLandmarkForEvent: return new CreateLandmarkForEventPacket(); + case PacketType.RegionHandleRequest: return new RegionHandleRequestPacket(); + case PacketType.RegionIDAndHandleReply: return new RegionIDAndHandleReplyPacket(); + case PacketType.MoneyTransferRequest: return new MoneyTransferRequestPacket(); + case PacketType.MoneyBalanceRequest: return new MoneyBalanceRequestPacket(); + case PacketType.MoneyBalanceReply: return new MoneyBalanceReplyPacket(); + case PacketType.RoutedMoneyBalanceReply: return new RoutedMoneyBalanceReplyPacket(); + case PacketType.ActivateGestures: return new ActivateGesturesPacket(); + case PacketType.DeactivateGestures: return new DeactivateGesturesPacket(); + case PacketType.MuteListUpdate: return new MuteListUpdatePacket(); + case PacketType.UseCachedMuteList: return new UseCachedMuteListPacket(); + case PacketType.GrantUserRights: return new GrantUserRightsPacket(); + case PacketType.ChangeUserRights: return new ChangeUserRightsPacket(); + case PacketType.OnlineNotification: return new OnlineNotificationPacket(); + case PacketType.OfflineNotification: return new OfflineNotificationPacket(); + case PacketType.SetStartLocationRequest: return new SetStartLocationRequestPacket(); + case PacketType.AssetUploadRequest: return new AssetUploadRequestPacket(); + case PacketType.AssetUploadComplete: return new AssetUploadCompletePacket(); + case PacketType.CreateGroupRequest: return new CreateGroupRequestPacket(); + case PacketType.CreateGroupReply: return new CreateGroupReplyPacket(); + case PacketType.UpdateGroupInfo: return new UpdateGroupInfoPacket(); + case PacketType.GroupRoleChanges: return new GroupRoleChangesPacket(); + case PacketType.JoinGroupRequest: return new JoinGroupRequestPacket(); + case PacketType.JoinGroupReply: return new JoinGroupReplyPacket(); + case PacketType.EjectGroupMemberRequest: return new EjectGroupMemberRequestPacket(); + case PacketType.EjectGroupMemberReply: return new EjectGroupMemberReplyPacket(); + case PacketType.LeaveGroupRequest: return new LeaveGroupRequestPacket(); + case PacketType.LeaveGroupReply: return new LeaveGroupReplyPacket(); + case PacketType.InviteGroupRequest: return new InviteGroupRequestPacket(); + case PacketType.GroupProfileRequest: return new GroupProfileRequestPacket(); + case PacketType.GroupProfileReply: return new GroupProfileReplyPacket(); + case PacketType.GroupAccountSummaryRequest: return new GroupAccountSummaryRequestPacket(); + case PacketType.GroupAccountSummaryReply: return new GroupAccountSummaryReplyPacket(); + case PacketType.GroupAccountDetailsRequest: return new GroupAccountDetailsRequestPacket(); + case PacketType.GroupAccountDetailsReply: return new GroupAccountDetailsReplyPacket(); + case PacketType.GroupAccountTransactionsRequest: return new GroupAccountTransactionsRequestPacket(); + case PacketType.GroupAccountTransactionsReply: return new GroupAccountTransactionsReplyPacket(); + case PacketType.GroupActiveProposalsRequest: return new GroupActiveProposalsRequestPacket(); + case PacketType.GroupActiveProposalItemReply: return new GroupActiveProposalItemReplyPacket(); + case PacketType.GroupVoteHistoryRequest: return new GroupVoteHistoryRequestPacket(); + case PacketType.GroupVoteHistoryItemReply: return new GroupVoteHistoryItemReplyPacket(); + case PacketType.StartGroupProposal: return new StartGroupProposalPacket(); + case PacketType.GroupProposalBallot: return new GroupProposalBallotPacket(); + case PacketType.GroupMembersRequest: return new GroupMembersRequestPacket(); + case PacketType.GroupMembersReply: return new GroupMembersReplyPacket(); + case PacketType.ActivateGroup: return new ActivateGroupPacket(); + case PacketType.SetGroupContribution: return new SetGroupContributionPacket(); + case PacketType.SetGroupAcceptNotices: return new SetGroupAcceptNoticesPacket(); + case PacketType.GroupRoleDataRequest: return new GroupRoleDataRequestPacket(); + case PacketType.GroupRoleDataReply: return new GroupRoleDataReplyPacket(); + case PacketType.GroupRoleMembersRequest: return new GroupRoleMembersRequestPacket(); + case PacketType.GroupRoleMembersReply: return new GroupRoleMembersReplyPacket(); + case PacketType.GroupTitlesRequest: return new GroupTitlesRequestPacket(); + case PacketType.GroupTitlesReply: return new GroupTitlesReplyPacket(); + case PacketType.GroupTitleUpdate: return new GroupTitleUpdatePacket(); + case PacketType.GroupRoleUpdate: return new GroupRoleUpdatePacket(); + case PacketType.LiveHelpGroupRequest: return new LiveHelpGroupRequestPacket(); + case PacketType.LiveHelpGroupReply: return new LiveHelpGroupReplyPacket(); + case PacketType.AgentWearablesRequest: return new AgentWearablesRequestPacket(); + case PacketType.AgentWearablesUpdate: return new AgentWearablesUpdatePacket(); + case PacketType.AgentIsNowWearing: return new AgentIsNowWearingPacket(); + case PacketType.AgentCachedTexture: return new AgentCachedTexturePacket(); + case PacketType.AgentCachedTextureResponse: return new AgentCachedTextureResponsePacket(); + case PacketType.AgentDataUpdateRequest: return new AgentDataUpdateRequestPacket(); + case PacketType.AgentDataUpdate: return new AgentDataUpdatePacket(); + case PacketType.GroupDataUpdate: return new GroupDataUpdatePacket(); + case PacketType.AgentGroupDataUpdate: return new AgentGroupDataUpdatePacket(); + case PacketType.AgentDropGroup: return new AgentDropGroupPacket(); + case PacketType.RezSingleAttachmentFromInv: return new RezSingleAttachmentFromInvPacket(); + case PacketType.RezMultipleAttachmentsFromInv: return new RezMultipleAttachmentsFromInvPacket(); + case PacketType.DetachAttachmentIntoInv: return new DetachAttachmentIntoInvPacket(); + case PacketType.CreateNewOutfitAttachments: return new CreateNewOutfitAttachmentsPacket(); + case PacketType.UserInfoRequest: return new UserInfoRequestPacket(); + case PacketType.UserInfoReply: return new UserInfoReplyPacket(); + case PacketType.UpdateUserInfo: return new UpdateUserInfoPacket(); + case PacketType.InitiateDownload: return new InitiateDownloadPacket(); + case PacketType.MapLayerRequest: return new MapLayerRequestPacket(); + case PacketType.MapLayerReply: return new MapLayerReplyPacket(); + case PacketType.MapBlockRequest: return new MapBlockRequestPacket(); + case PacketType.MapNameRequest: return new MapNameRequestPacket(); + case PacketType.MapBlockReply: return new MapBlockReplyPacket(); + case PacketType.MapItemRequest: return new MapItemRequestPacket(); + case PacketType.MapItemReply: return new MapItemReplyPacket(); + case PacketType.SendPostcard: return new SendPostcardPacket(); + case PacketType.ParcelMediaCommandMessage: return new ParcelMediaCommandMessagePacket(); + case PacketType.ParcelMediaUpdate: return new ParcelMediaUpdatePacket(); + case PacketType.LandStatRequest: return new LandStatRequestPacket(); + case PacketType.LandStatReply: return new LandStatReplyPacket(); + case PacketType.Error: return new ErrorPacket(); + case PacketType.ObjectIncludeInSearch: return new ObjectIncludeInSearchPacket(); + case PacketType.RezRestoreToWorld: return new RezRestoreToWorldPacket(); + case PacketType.LinkInventoryItem: return new LinkInventoryItemPacket(); + case PacketType.LargeGenericMessage: return new LargeGenericMessagePacket(); + case PacketType.PacketAck: return new PacketAckPacket(); + case PacketType.OpenCircuit: return new OpenCircuitPacket(); + case PacketType.CloseCircuit: return new CloseCircuitPacket(); + } + return null; + } + + public static Packet BuildPacket(byte[] packetBuffer, ref int packetLength, byte[] zeroBuffer) { byte[] bytes; int i = 0; - Header header = Header.BuildHeader(packetBuffer, ref i, ref packetEnd); + Header header = Header.BuildHeader(packetBuffer, ref i, ref packetLength); if (header.Zerocoded) { - packetEnd = Helpers.ZeroDecode(packetBuffer, packetEnd + 1, zeroBuffer) - 1; + packetLength = Helpers.ZeroDecode(packetBuffer, packetLength, zeroBuffer); bytes = zeroBuffer; } else { bytes = packetBuffer; } - Array.Clear(bytes, packetEnd + 1, bytes.Length - packetEnd - 1); + //Array.Clear(bytes, packetEnd + 1, bytes.Length - packetEnd - 1); switch (header.Frequency) { diff --git a/OpenMetaverseTypes/UtilsConversions.cs b/OpenMetaverseTypes/UtilsConversions.cs index ea0c78a0..f6ea586d 100644 --- a/OpenMetaverseTypes/UtilsConversions.cs +++ b/OpenMetaverseTypes/UtilsConversions.cs @@ -507,6 +507,15 @@ public static int BytesToIntBig(byte[] bytes) bytes[3]; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int BytesToIntBig(byte[] bytes, int pos) + { + return (bytes[pos] << 24) | + (bytes[pos + 1] << 16) | + (bytes[pos + 2] << 8) | + bytes[pos + 3]; + } + /// /// Convert the first eight bytes of the given array in little endian /// ordering to a signed long integer diff --git a/Programs/GridProxy/GridProxy.cs b/Programs/GridProxy/GridProxy.cs index 1c4efb54..266e932b 100644 --- a/Programs/GridProxy/GridProxy.cs +++ b/Programs/GridProxy/GridProxy.cs @@ -1384,7 +1384,7 @@ private void ReceiveFromSim(IAsyncResult ar) // interpret the packet according to the SL protocol Packet packet; - int end = length - 1; + int end = length; packet = Packet.BuildPacket(receiveBuffer, ref end, zeroBuffer); @@ -1722,7 +1722,7 @@ private void ReceiveFromClient(IAsyncResult ar) if (length != 0) { // interpret the packet according to the SL protocol - int end = length - 1; + int end = length; Packet packet = OpenMetaverse.Packets.Packet.BuildPacket(receiveBuffer, ref end, zeroBuffer); //OpenMetaverse.Logger.Log("-> " + packet.Type + " #" + packet.Header.Sequence, Helpers.LogLevel.Debug); diff --git a/Programs/WinGridProxy/SessionTypes.cs b/Programs/WinGridProxy/SessionTypes.cs index 3103ae26..0b6ad489 100644 --- a/Programs/WinGridProxy/SessionTypes.cs +++ b/Programs/WinGridProxy/SessionTypes.cs @@ -175,7 +175,7 @@ public override Session Deserialize(byte[] bytes) byte[] packetData = map["PacketBytes"].AsBinary(); this.Length = packetData.Length; - int packetEnd = packetData.Length - 1; + int packetEnd = packetData.Length; this.Packet = Packet.BuildPacket(packetData, ref packetEnd, null); this.Name = this.Packet.Type.ToString(); return this; diff --git a/Programs/mapgenerator/mapgenerator.cs b/Programs/mapgenerator/mapgenerator.cs index 9ccddc0f..39cb72f1 100644 --- a/Programs/mapgenerator/mapgenerator.cs +++ b/Programs/mapgenerator/mapgenerator.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.IO; +using System.Text; namespace mapgenerator { @@ -1032,37 +1033,41 @@ static int Main(string[] args) " return PacketType.Default;" + Environment.NewLine + " }" + Environment.NewLine); // Write the Packet.BuildPacket(PacketType) function - writer.WriteLine(" public static Packet BuildPacket(PacketType type)"); - writer.WriteLine(" {"); + writer.WriteLine(" public static Packet BuildPacket(PacketType type)"); + writer.WriteLine(" {"); + writer.WriteLine(" switch(type)"); + writer.WriteLine(" {"); foreach (MapPacket packet in protocol.HighMaps) if (packet != null) - writer.WriteLine(" if(type == PacketType." + packet.Name + ") return new " + packet.Name + "Packet();"); + writer.WriteLine(" case PacketType." + packet.Name + ": return new " + packet.Name + "Packet();"); + foreach (MapPacket packet in protocol.MediumMaps) if (packet != null) - writer.WriteLine(" if(type == PacketType." + packet.Name + ") return new " + packet.Name + "Packet();"); + writer.WriteLine(" case PacketType." + packet.Name + ": return new " + packet.Name + "Packet();"); foreach (MapPacket packet in protocol.LowMaps) if (packet != null) - writer.WriteLine(" if(type == PacketType." + packet.Name + ") return new " + packet.Name + "Packet();"); - writer.WriteLine(" return null;" + Environment.NewLine); - writer.WriteLine(" }"); + writer.WriteLine(" case PacketType." + packet.Name + ": return new " + packet.Name + "Packet();"); + writer.WriteLine(" }"); + writer.WriteLine(" return null;"); + writer.WriteLine(" }"); // Write the Packet.BuildPacket() function writer.WriteLine(@" - public static Packet BuildPacket(byte[] packetBuffer, ref int packetEnd, byte[] zeroBuffer) + public static Packet BuildPacket(byte[] packetBuffer, ref int packetLength, byte[] zeroBuffer) { byte[] bytes; int i = 0; - Header header = Header.BuildHeader(packetBuffer, ref i, ref packetEnd); + Header header = Header.BuildHeader(packetBuffer, ref i, ref packetLength); if (header.Zerocoded) { - packetEnd = Helpers.ZeroDecode(packetBuffer, packetEnd + 1, zeroBuffer) - 1; + packetLength = Helpers.ZeroDecode(packetBuffer, packetLength, zeroBuffer); bytes = zeroBuffer; } else { bytes = packetBuffer; } - Array.Clear(bytes, packetEnd + 1, bytes.Length - packetEnd - 1); + //Array.Clear(bytes, packetEnd + 1, bytes.Length - packetEnd - 1); switch (header.Frequency) { From 5b20c2f7589dc7f94bce2445e1f1470892426a7e Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Wed, 12 Jan 2022 05:57:38 +0000 Subject: [PATCH 026/149] fix uuid xml serielization --- OpenMetaverseTypes/UUID.cs | 63 +++++++++++++++++++------------------- 1 file changed, 32 insertions(+), 31 deletions(-) diff --git a/OpenMetaverseTypes/UUID.cs b/OpenMetaverseTypes/UUID.cs index 1851f5e6..26de61b9 100644 --- a/OpenMetaverseTypes/UUID.cs +++ b/OpenMetaverseTypes/UUID.cs @@ -27,6 +27,7 @@ using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; +using System.Xml.Serialization; namespace OpenMetaverse { @@ -36,41 +37,41 @@ namespace OpenMetaverse /// [StructLayout(LayoutKind.Explicit)] - [Serializable] + [Serializable()] public struct UUID : IComparable,IComparable, IEquatable { // still a big piece of *** because how stupid .net structs are. // .net5 unsafe may remove the need for this union - [FieldOffset(0)] public int a; - [FieldOffset(4)] public short b; - [FieldOffset(6)] public short c; - - [FieldOffset(8)] public byte d; - [FieldOffset(9)] public byte e; - [FieldOffset(10)] public byte f; - [FieldOffset(11)] public byte g; - [FieldOffset(12)] public byte h; - [FieldOffset(13)] public byte i; - [FieldOffset(14)] public byte j; - [FieldOffset(15)] public byte k; - - [FieldOffset(0)] public byte bytea0; - [FieldOffset(1)] public byte bytea1; - [FieldOffset(2)] public byte bytea2; - [FieldOffset(3)] public byte bytea3; - - [FieldOffset(4)] public byte byteb0; - [FieldOffset(5)] public byte byteb1; - - [FieldOffset(6)] public byte bytec0; - [FieldOffset(7)] public byte bytec1; - - [FieldOffset(4)] public int intb; - [FieldOffset(8)] public int intc; - [FieldOffset(12)] public int intd; - - [FieldOffset(0)] public ulong ulonga; - [FieldOffset(8)] public ulong ulongb; + [XmlIgnore] [NonSerialized()] [FieldOffset(0)] public int a; + [XmlIgnore] [NonSerialized()] [FieldOffset(4)] public short b; + [XmlIgnore] [NonSerialized()] [FieldOffset(6)] public short c; + + [XmlIgnore] [NonSerialized()] [FieldOffset(8)] public byte d; + [XmlIgnore] [NonSerialized()] [FieldOffset(9)] public byte e; + [XmlIgnore] [NonSerialized()] [FieldOffset(10)] public byte f; + [XmlIgnore] [NonSerialized()] [FieldOffset(11)] public byte g; + [XmlIgnore] [NonSerialized()] [FieldOffset(12)] public byte h; + [XmlIgnore] [NonSerialized()] [FieldOffset(13)] public byte i; + [XmlIgnore] [NonSerialized()] [FieldOffset(14)] public byte j; + [XmlIgnore] [NonSerialized()] [FieldOffset(15)] public byte k; + + [XmlIgnore] [NonSerialized()] [FieldOffset(0)] public byte bytea0; + [XmlIgnore] [NonSerialized()] [FieldOffset(1)] public byte bytea1; + [XmlIgnore] [NonSerialized()] [FieldOffset(2)] public byte bytea2; + [XmlIgnore] [NonSerialized()] [FieldOffset(3)] public byte bytea3; + + [XmlIgnore] [NonSerialized()] [FieldOffset(4)] public byte byteb0; + [XmlIgnore] [NonSerialized()] [FieldOffset(5)] public byte byteb1; + + [XmlIgnore] [NonSerialized()] [FieldOffset(6)] public byte bytec0; + [XmlIgnore] [NonSerialized()] [FieldOffset(7)] public byte bytec1; + + [XmlIgnore] [NonSerialized()] [FieldOffset(4)] public int intb; + [XmlIgnore] [NonSerialized()] [FieldOffset(8)] public int intc; + [XmlIgnore] [NonSerialized()] [FieldOffset(12)] public int intd; + + [XmlIgnore] [NonSerialized()] [FieldOffset(0)] public ulong ulonga; + [XmlIgnore] [NonSerialized()] [FieldOffset(8)] public ulong ulongb; [FieldOffset(0)] public Guid Guid; From b957832dbfe2a1e90e26afb05badfe0888041573 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Wed, 12 Jan 2022 05:59:44 +0000 Subject: [PATCH 027/149] a few changes to lludp decode --- OpenMetaverse/Helpers.cs | 25 +- OpenMetaverse/_Packets_.cs | 1932 ++++++++++--------------- Programs/mapgenerator/mapgenerator.cs | 7 +- Programs/mapgenerator/template.cs | 36 +- 4 files changed, 794 insertions(+), 1206 deletions(-) diff --git a/OpenMetaverse/Helpers.cs b/OpenMetaverse/Helpers.cs index fa533829..6b5d1657 100644 --- a/OpenMetaverse/Helpers.cs +++ b/OpenMetaverse/Helpers.cs @@ -318,17 +318,13 @@ public static int ZeroDecode(byte[] src, int srclen, byte[] dest) if (srclen > src.Length) throw new ArgumentException("srclen cannot be greater than src.Length"); - uint zerolen = 0; - int bodylen = 0; + uint zerolen = 6; uint i = 0; try { Buffer.BlockCopy(src, 0, dest, 0, 6); - zerolen = 6; - bodylen = srclen; - - for (i = zerolen; i < bodylen; i++) + for (i = zerolen; i < srclen; i++) { if (src[i] == 0x00) { @@ -343,23 +339,16 @@ public static int ZeroDecode(byte[] src, int srclen, byte[] dest) { dest[zerolen++] = src[i]; } - } - - // Copy appended ACKs - for (; i < srclen; i++) - { - dest[zerolen++] = src[i]; - } - + } return (int)zerolen; } catch (Exception ex) { - Logger.Log(String.Format("Zerodecoding error: i={0}, srclen={1}, bodylen={2}, zerolen={3}\n{4}\n{5}", - i, srclen, bodylen, zerolen, Utils.BytesToHexString(src, srclen, null), ex), LogLevel.Error); + Logger.Log(String.Format("Zerodecoding error: i={0}, srclen={1}, zerolen={2}\n{3}\n{4}", + i, srclen, zerolen, Utils.BytesToHexString(src, srclen, null), ex), LogLevel.Error); - throw new IndexOutOfRangeException(String.Format("Zerodecoding error: i={0}, srclen={1}, bodylen={2}, zerolen={3}\n{4}\n{5}", - i, srclen, bodylen, zerolen, Utils.BytesToHexString(src, srclen, null), ex.InnerException)); + throw new IndexOutOfRangeException(String.Format("Zerodecoding error: i={0}, srclen={1}, zerolen={2}\n{3}\n{4}", + i, srclen, zerolen, Utils.BytesToHexString(src, srclen, null), ex.InnerException)); } } diff --git a/OpenMetaverse/_Packets_.cs b/OpenMetaverse/_Packets_.cs index 62b6d8a6..d8b02907 100644 --- a/OpenMetaverse/_Packets_.cs +++ b/OpenMetaverse/_Packets_.cs @@ -639,7 +639,7 @@ public abstract partial class Packet public PacketType Type; public abstract int Length { get; } public abstract void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer); - public abstract void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd); + public abstract void FromBytes(Header header, byte[] bytes, ref int i); public abstract byte[] ToBytes(); public abstract byte[][] ToBytesMultiple(); @@ -2012,11 +2012,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public TestMessagePacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; TestBlock1.FromBytes(bytes, ref i); @@ -2138,11 +2137,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public UseCircuitCodePacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; CircuitCode.FromBytes(bytes, ref i); @@ -2314,11 +2312,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public TelehubInfoPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; TelehubBlock.FromBytes(bytes, ref i); @@ -2448,11 +2445,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public EconomyDataRequestPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; } @@ -2605,11 +2601,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public EconomyDataPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; Info.FromBytes(bytes, ref i); @@ -2770,11 +2765,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public AvatarPickerRequestPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -2953,11 +2947,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public AvatarPickerReplyPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -3239,11 +3232,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public PlacesQueryPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -3502,11 +3494,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public PlacesReplyPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -3744,11 +3735,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public DirFindQueryPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -3929,11 +3919,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public DirPlacesQueryPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -4212,11 +4201,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public DirPlacesReplyPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -4570,11 +4558,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public DirPeopleReplyPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -4919,11 +4906,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public DirEventsReplyPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -5238,11 +5224,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public DirGroupsReplyPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -5483,11 +5468,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public DirClassifiedQueryPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -5761,11 +5745,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public DirClassifiedReplyPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -6034,11 +6017,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public AvatarClassifiedReplyPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -6256,11 +6238,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ClassifiedInfoRequestPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -6473,11 +6454,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ClassifiedInfoReplyPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -6670,11 +6650,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ClassifiedInfoUpdatePacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -6829,11 +6808,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ClassifiedDeletePacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -6991,11 +6969,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ClassifiedGodDeletePacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -7166,11 +7143,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public DirLandQueryPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -7394,11 +7370,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public DirLandReplyPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -7624,11 +7599,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public DirPopularQueryPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -7843,11 +7817,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public DirPopularReplyPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -8069,11 +8042,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ParcelInfoRequestPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -8282,11 +8254,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ParcelInfoReplyPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -8441,11 +8412,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ParcelObjectOwnersRequestPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -8573,11 +8543,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ParcelObjectOwnersReplyPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; int count = (int)bytes[i++]; @@ -8789,11 +8758,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public GroupNoticesListRequestPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -8983,11 +8951,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public GroupNoticesListReplyPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -9204,11 +9171,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public GroupNoticeRequestPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -9369,11 +9335,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public TeleportRequestPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -9534,11 +9499,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public TeleportLocationRequestPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -9660,11 +9624,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public TeleportLocalPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; Info.FromBytes(bytes, ref i); @@ -9778,11 +9741,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public TeleportLandmarkRequestPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; Info.FromBytes(bytes, ref i); @@ -9940,11 +9902,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public TeleportProgressPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -10083,11 +10044,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public TeleportFinishPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; Info.FromBytes(bytes, ref i); @@ -10298,11 +10258,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public StartLurePacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -10488,11 +10447,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public TeleportLureRequestPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; Info.FromBytes(bytes, ref i); @@ -10602,11 +10560,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public TeleportCancelPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; Info.FromBytes(bytes, ref i); @@ -10713,11 +10670,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public TeleportStartPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; Info.FromBytes(bytes, ref i); @@ -10896,11 +10852,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public TeleportFailedPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; Info.FromBytes(bytes, ref i); @@ -11128,11 +11083,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public UndoPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -11360,11 +11314,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public RedoPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -11539,11 +11492,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public UndoLandPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -11656,11 +11608,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public AgentPausePacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -11773,11 +11724,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public AgentResumePacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -11943,11 +11893,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ChatFromViewerPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -12115,11 +12064,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public AgentThrottlePacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -12280,11 +12228,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public AgentFOVPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -12448,11 +12395,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public AgentHeightWidthPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -12724,11 +12670,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public AgentSetAppearancePacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -12907,11 +12852,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public AgentQuitCopyPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -13021,11 +12965,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ImageNotInDatabasePacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; ImageID.FromBytes(bytes, ref i); @@ -13132,11 +13075,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public RebakeAvatarTexturesPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; TextureData.FromBytes(bytes, ref i); @@ -13249,11 +13191,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public SetAlwaysRunPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -13417,11 +13358,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ObjectDeletePacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -13695,11 +13635,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ObjectDuplicatePacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -13957,11 +13896,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ObjectDuplicateOnRayPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -14190,11 +14128,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ObjectScalePacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -14423,11 +14360,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ObjectRotationPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -14680,11 +14616,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ObjectFlagUpdatePacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -14913,11 +14848,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ObjectClickActionPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -15160,11 +15094,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ObjectImagePacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -15393,11 +15326,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ObjectMaterialPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -15677,11 +15609,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ObjectShapePacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -15925,11 +15856,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ObjectExtraParamsPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -16203,11 +16133,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ObjectOwnerPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -16441,11 +16370,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ObjectGroupPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -16683,11 +16611,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ObjectBuyPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -16911,11 +16838,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public BuyObjectInventoryPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -17029,11 +16955,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public DerezContainerPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; Data.FromBytes(bytes, ref i); @@ -17245,11 +17170,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ObjectPermissionsPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -17486,11 +17410,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ObjectSaleInfoPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -17725,11 +17648,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ObjectNamePacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -17964,11 +17886,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ObjectDescriptionPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -18197,11 +18118,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ObjectCategoryPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -18427,11 +18347,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ObjectSelectPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -18657,11 +18576,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ObjectDeselectPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -18893,11 +18811,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ObjectAttachPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -19122,11 +19039,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ObjectDetachPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -19351,11 +19267,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ObjectDropPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -19580,11 +19495,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ObjectLinkPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -19809,11 +19723,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ObjectDelinkPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -20099,11 +20012,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ObjectGrabPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -20400,11 +20312,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ObjectGrabUpdatePacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -20691,11 +20602,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ObjectDeGrabPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -20918,11 +20828,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ObjectSpinStartPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -21081,11 +20990,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ObjectSpinUpdatePacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -21241,11 +21149,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ObjectSpinStopPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -21412,11 +21319,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ObjectExportSelectedPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -21755,11 +21661,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ModifyLandPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -21969,11 +21874,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public VelocityInterpolateOnPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -22083,11 +21987,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public VelocityInterpolateOffPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -22245,11 +22148,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public StateSavePacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -22362,11 +22264,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ReportAutosaveCrashPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AutosaveData.FromBytes(bytes, ref i); @@ -22521,11 +22422,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public SimWideDeletesPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -22680,11 +22580,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public TrackAgentPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -23067,11 +22966,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ViewerStatsPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -23315,11 +23213,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ScriptAnswerYesPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -23527,11 +23424,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public UserReportPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -23710,11 +23606,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public AlertMessagePacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AlertData.FromBytes(bytes, ref i); @@ -23937,11 +23832,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public AgentAlertMessagePacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -24072,11 +23966,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public MeanCollisionAlertPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; int count = (int)bytes[i++]; @@ -24243,11 +24136,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ViewerFrozenMessagePacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; FrozenData.FromBytes(bytes, ref i); @@ -24355,11 +24247,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public HealthMessagePacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; HealthData.FromBytes(bytes, ref i); @@ -24498,11 +24389,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ChatFromSimulatorPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; ChatData.FromBytes(bytes, ref i); @@ -24763,11 +24653,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public SimStatsPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; Region.FromBytes(bytes, ref i); @@ -24904,11 +24793,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public RequestRegionInfoPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -25226,11 +25114,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public RegionInfoPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -25535,11 +25422,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public GodUpdateRegionInfoPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -25955,11 +25841,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public RegionHandshakePacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; RegionInfo.FromBytes(bytes, ref i); @@ -26187,11 +26072,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public RegionHandshakeReplyPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -26316,11 +26200,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public SimulatorViewerTimeMessagePacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; TimeInfo.FromBytes(bytes, ref i); @@ -26434,11 +26317,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public EnableSimulatorPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; SimulatorInfo.FromBytes(bytes, ref i); @@ -26503,11 +26385,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public DisableSimulatorPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; } @@ -26631,11 +26512,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public TransferRequestPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; TransferInfo.FromBytes(bytes, ref i); @@ -26765,11 +26645,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public TransferInfoPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; TransferInfo.FromBytes(bytes, ref i); @@ -26880,11 +26759,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public TransferAbortPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; TransferInfo.FromBytes(bytes, ref i); @@ -27016,11 +26894,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public RequestXferPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; XferID.FromBytes(bytes, ref i); @@ -27130,11 +27007,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public AbortXferPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; XferID.FromBytes(bytes, ref i); @@ -27450,11 +27326,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public AvatarAppearancePacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; Sender.FromBytes(bytes, ref i); @@ -27744,11 +27619,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public SetFollowCamPropertiesPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; ObjectData.FromBytes(bytes, ref i); @@ -27920,11 +27794,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ClearFollowCamPropertiesPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; ObjectData.FromBytes(bytes, ref i); @@ -28031,11 +27904,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public RequestPayPricePacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; ObjectData.FromBytes(bytes, ref i); @@ -28195,11 +28067,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public PayPriceReplyPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; ObjectData.FromBytes(bytes, ref i); @@ -28430,11 +28301,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public KickUserPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; TargetBlock.FromBytes(bytes, ref i); @@ -28563,11 +28433,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public GodKickUserPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; UserInfo.FromBytes(bytes, ref i); @@ -28722,11 +28591,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public EjectUserPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -28884,11 +28752,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public FreezeUserPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -29004,11 +28871,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public AvatarPropertiesRequestPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -29208,11 +29074,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public AvatarPropertiesReplyPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -29394,11 +29259,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public AvatarInterestsReplyPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -29629,11 +29493,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public AvatarGroupsReplyPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -29834,11 +29697,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public AvatarPropertiesUpdatePacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -30020,11 +29882,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public AvatarInterestsUpdatePacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -30186,11 +30047,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public AvatarNotesReplyPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -30355,11 +30215,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public AvatarNotesUpdatePacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -30531,11 +30390,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public AvatarPicksReplyPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -30752,11 +30610,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public EventInfoRequestPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -30971,11 +30828,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public EventInfoReplyPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -31130,11 +30986,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public EventNotificationAddRequestPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -31289,11 +31144,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public EventNotificationRemoveRequestPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -31505,11 +31359,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public EventGodDeletePacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -31723,11 +31576,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public PickInfoReplyPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -31920,11 +31772,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public PickInfoUpdatePacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -32079,11 +31930,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public PickDeletePacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -32241,11 +32091,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public PickGodDeletePacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -32419,11 +32268,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ScriptQuestionPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; Data.FromBytes(bytes, ref i); @@ -32547,11 +32395,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ScriptControlChangePacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; int count = (int)bytes[i++]; @@ -32862,11 +32709,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ScriptDialogPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; Data.FromBytes(bytes, ref i); @@ -33129,11 +32975,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ScriptDialogReplyPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -33246,11 +33091,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ForceScriptControlReleasePacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -33405,11 +33249,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public RevokePermissionsPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -33548,11 +33391,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public LoadURLPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; Data.FromBytes(bytes, ref i); @@ -33678,11 +33520,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ScriptTeleportRequestPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; Data.FromBytes(bytes, ref i); @@ -33800,11 +33641,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ParcelOverlayPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; ParcelData.FromBytes(bytes, ref i); @@ -33960,11 +33800,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ParcelPropertiesRequestByIDPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -34192,11 +34031,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ParcelPropertiesUpdatePacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -34455,11 +34293,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ParcelReturnObjectsPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -34715,11 +34552,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ParcelSetOtherCleanTimePacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -34978,11 +34814,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ParcelDisableObjectsPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -35288,11 +35123,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ParcelSelectObjectsPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -35472,11 +35306,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public EstateCovenantRequestPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -35598,11 +35431,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public EstateCovenantReplyPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; Data.FromBytes(bytes, ref i); @@ -35759,11 +35591,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ForceObjectSelectPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; _Header.FromBytes(bytes, ref i); @@ -35980,11 +35811,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ParcelBuyPassPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -36142,11 +35972,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ParcelDeedToGroupPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -36301,11 +36130,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ParcelReclaimPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -36526,11 +36354,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ParcelClaimPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -36761,11 +36588,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ParcelJoinPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -36929,11 +36755,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ParcelDividePacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -37088,11 +36913,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ParcelReleasePacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -37305,11 +37129,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ParcelBuyPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -37471,11 +37294,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ParcelGodForceOwnerPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -37637,11 +37459,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ParcelAccessListRequestPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -37817,11 +37638,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ParcelAccessListReplyPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; Data.FromBytes(bytes, ref i); @@ -38107,11 +37927,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ParcelAccessListUpdatePacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -38336,11 +38155,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ParcelDwellRequestPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -38498,11 +38316,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ParcelDwellReplyPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -38657,11 +38474,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ParcelGodMarkAsContentPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -38819,11 +38635,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ViewerStartAuctionPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -38941,11 +38756,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public UUIDNameRequestPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; int count = (int)bytes[i++]; @@ -39136,11 +38950,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public UUIDNameReplyPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; int count = (int)bytes[i++]; @@ -39315,11 +39128,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public UUIDGroupNameRequestPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; int count = (int)bytes[i++]; @@ -39503,11 +39315,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public UUIDGroupNameReplyPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; int count = (int)bytes[i++]; @@ -39678,11 +39489,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ChildAgentDyingPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -39792,11 +39602,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ChildAgentUnknownPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -39906,11 +39715,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public GetScriptRunningPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; Script.FromBytes(bytes, ref i); @@ -40023,11 +39831,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ScriptRunningReplyPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; Script.FromBytes(bytes, ref i); @@ -40185,11 +39992,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public SetScriptRunningPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -40347,11 +40153,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ScriptResetPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -40498,11 +40303,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ScriptSensorRequestPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; Requester.FromBytes(bytes, ref i); @@ -40690,11 +40494,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ScriptSensorReplyPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; Requester.FromBytes(bytes, ref i); @@ -40872,11 +40675,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public CompleteAgentMovementPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -41086,11 +40888,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public AgentMovementCompletePacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -41206,11 +41007,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public LogoutRequestPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -41371,11 +41171,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public LogoutReplyPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -41642,11 +41441,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ImprovedInstantMessagePacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -41759,11 +41557,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public RetrieveInstantMessagesPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -41929,11 +41726,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public FindAgentPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentBlock.FromBytes(bytes, ref i); @@ -42153,11 +41949,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public RequestGodlikePowersPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -42315,11 +42110,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public GrantGodlikePowersPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -42543,11 +42337,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public GodlikeMessagePacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -42838,11 +42631,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public EstateOwnerMessagePacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -43133,11 +42925,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public GenericMessagePacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -43359,11 +43150,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public MuteListRequestPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -43533,11 +43323,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public UpdateMuteListEntryPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -43701,11 +43490,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public RemoveMuteListEntryPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -43917,11 +43705,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public CopyInventoryFromNotecardPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -44228,11 +44015,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public UpdateInventoryItemPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -44534,11 +44320,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public UpdateCreateInventoryItemPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -44779,11 +44564,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public MoveInventoryItemPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -45027,11 +44811,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public CopyInventoryItemPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -45256,11 +45039,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public RemoveInventoryItemPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -45488,11 +45270,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ChangeInventoryItemFlagsPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -45709,11 +45490,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public SaveAssetIntoInventoryPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -45883,11 +45663,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public CreateInventoryFolderPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -46065,11 +45844,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public UpdateInventoryFolderPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -46301,11 +46079,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public MoveInventoryFolderPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -46530,11 +46307,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public RemoveInventoryFolderPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -46764,11 +46540,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public FetchInventoryDescendentsPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -47076,11 +46851,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public InventoryDescendentsPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -47339,11 +47113,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public FetchInventoryPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -47636,11 +47409,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public FetchInventoryReplyPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -48004,11 +47776,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public BulkUpdateInventoryPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -48313,11 +48084,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public RemoveInventoryObjectsPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -48565,11 +48335,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public PurgeInventoryDescendentsPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -48840,11 +48609,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public UpdateTaskInventoryPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -49006,11 +48774,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public RemoveTaskInventoryPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -49171,11 +48938,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public MoveTaskInventoryPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -49330,11 +49096,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public RequestTaskInventoryPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -49457,11 +49222,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ReplyTaskInventoryPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; InventoryData.FromBytes(bytes, ref i); @@ -49679,11 +49443,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public DeRezObjectPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -49863,11 +49626,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public DeRezAckPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; TransactionData.FromBytes(bytes, ref i); @@ -50168,11 +49930,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public RezObjectPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -50462,11 +50223,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public RezObjectFromNotecardPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -50743,11 +50503,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public AcceptFriendshipPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -50969,11 +50728,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public DeclineFriendshipPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -51128,11 +50886,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public TerminateFriendshipPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -51290,11 +51047,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public OfferCallingCardPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -51499,11 +51255,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public AcceptCallingCardPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -51725,11 +51480,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public DeclineCallingCardPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -52003,11 +51757,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public RezScriptPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -52200,11 +51953,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public CreateInventoryItemPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -52411,11 +52163,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public CreateLandmarkForEventPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -52528,11 +52279,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public RegionHandleRequestPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; RequestBlock.FromBytes(bytes, ref i); @@ -52642,11 +52392,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public RegionIDAndHandleReplyPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; ReplyBlock.FromBytes(bytes, ref i); @@ -52826,11 +52575,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public MoneyTransferRequestPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -52986,11 +52734,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public MoneyBalanceRequestPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -53191,11 +52938,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public MoneyBalanceReplyPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; MoneyData.FromBytes(bytes, ref i); @@ -53442,11 +53188,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public RoutedMoneyBalanceReplyPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; TargetBlock.FromBytes(bytes, ref i); @@ -53621,11 +53366,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ActivateGesturesPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -53856,11 +53600,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public DeactivateGesturesPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -54041,11 +53784,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public MuteListUpdatePacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; MuteData.FromBytes(bytes, ref i); @@ -54152,11 +53894,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public UseCachedMuteListPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -54319,11 +54060,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public GrantUserRightsPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -54548,11 +54288,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ChangeUserRightsPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -54732,11 +54471,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public OnlineNotificationPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; int count = (int)bytes[i++]; @@ -54911,11 +54649,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public OfflineNotificationPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; int count = (int)bytes[i++]; @@ -55143,11 +54880,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public SetStartLocationRequestPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -55276,11 +55012,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public AssetUploadRequestPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AssetBlock.FromBytes(bytes, ref i); @@ -55393,11 +55128,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public AssetUploadCompletePacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AssetBlock.FromBytes(bytes, ref i); @@ -55582,11 +55316,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public CreateGroupRequestPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -55750,11 +55483,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public CreateGroupReplyPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -55938,11 +55670,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public UpdateGroupInfoPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -56114,11 +55845,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public GroupRoleChangesPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -56336,11 +56066,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public JoinGroupRequestPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -56495,11 +56224,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public JoinGroupReplyPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -56704,11 +56432,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public EjectGroupMemberRequestPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -56969,11 +56696,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public EjectGroupMemberReplyPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -57131,11 +56857,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public LeaveGroupRequestPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -57290,11 +57015,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public LeaveGroupReplyPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -57502,11 +57226,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public InviteGroupRequestPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -57728,11 +57451,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public GroupProfileRequestPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -57945,11 +57667,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public GroupProfileReplyPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -58114,11 +57835,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public GroupAccountSummaryRequestPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -58345,11 +58065,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public GroupAccountSummaryReplyPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -58514,11 +58233,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public GroupAccountDetailsRequestPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -58748,11 +58466,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public GroupAccountDetailsReplyPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -58984,11 +58701,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public GroupAccountTransactionsRequestPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -59235,11 +58951,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public GroupAccountTransactionsReplyPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -59503,11 +59218,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public GroupActiveProposalsRequestPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -59768,11 +59482,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public GroupActiveProposalItemReplyPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -60036,11 +59749,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public GroupVoteHistoryRequestPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -60360,11 +60072,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public GroupVoteHistoryItemReplyPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -60610,11 +60321,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public StartGroupProposalPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -60781,11 +60491,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public GroupProposalBallotPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -60943,11 +60652,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public GroupMembersRequestPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -61181,11 +60889,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public GroupMembersReplyPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -61369,11 +61076,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ActivateGroupPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -61528,11 +61234,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public SetGroupContributionPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -61732,11 +61437,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public SetGroupAcceptNoticesPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -61897,11 +61601,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public GroupRoleDataRequestPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -62138,11 +61841,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public GroupRoleDataReplyPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -62367,11 +62069,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public GroupRoleMembersRequestPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -62543,11 +62244,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public GroupRoleMembersReplyPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -62728,11 +62428,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public GroupTitlesRequestPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -62908,11 +62607,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public GroupTitlesReplyPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -63093,11 +62791,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public GroupTitleUpdatePacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -63289,11 +62986,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public GroupRoleUpdatePacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -63468,11 +63164,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public LiveHelpGroupRequestPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; RequestData.FromBytes(bytes, ref i); @@ -63591,11 +63286,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public LiveHelpGroupReplyPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; ReplyData.FromBytes(bytes, ref i); @@ -63705,11 +63399,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public AgentWearablesRequestPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -63879,11 +63572,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public AgentWearablesUpdatePacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -64112,11 +63804,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public AgentIsNowWearingPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -64347,11 +64038,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public AgentCachedTexturePacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -64591,11 +64281,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public AgentCachedTextureResponsePacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -64770,11 +64459,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public AgentDataUpdateRequestPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -64918,11 +64606,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public AgentDataUpdatePacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -65053,11 +64740,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public GroupDataUpdatePacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; int count = (int)bytes[i++]; @@ -65296,11 +64982,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public AgentGroupDataUpdatePacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -65476,11 +65161,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public AgentDropGroupPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -65667,11 +65351,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public RezSingleAttachmentFromInvPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -65917,11 +65600,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public RezMultipleAttachmentsFromInvPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -66101,11 +65783,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public DetachAttachmentIntoInvPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; ObjectData.FromBytes(bytes, ref i); @@ -66310,11 +65991,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public CreateNewOutfitAttachmentsPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -66494,11 +66174,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public UserInfoRequestPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -66664,11 +66343,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public UserInfoReplyPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -66832,11 +66510,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public UpdateUserInfoPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -67001,11 +66678,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public InitiateDownloadPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -67127,11 +66803,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public MapLayerRequestPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -67303,11 +66978,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public MapLayerReplyPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -67542,11 +67216,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public MapBlockRequestPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -67716,11 +67389,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public MapNameRequestPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -67963,11 +67635,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public MapBlockReplyPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -68226,11 +67897,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public MapItemRequestPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -68456,11 +68126,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public MapItemReplyPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -68690,11 +68359,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public SendPostcardPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -68807,11 +68475,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ParcelMediaCommandMessagePacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; CommandBlock.FromBytes(bytes, ref i); @@ -68994,11 +68661,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ParcelMediaUpdatePacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; DataBlock.FromBytes(bytes, ref i); @@ -69168,11 +68834,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public LandStatRequestPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -69369,11 +69034,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public LandStatReplyPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; RequestData.FromBytes(bytes, ref i); @@ -69623,11 +69287,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ErrorPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -69793,11 +69456,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ObjectIncludeInSearchPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -70084,11 +69746,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public RezRestoreToWorldPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -70275,11 +69936,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public LinkInventoryItemPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -70503,11 +70163,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public LargeGenericMessagePacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -70692,11 +70351,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public PacketAckPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; int count = (int)bytes[i++]; @@ -70867,11 +70525,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public OpenCircuitPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; CircuitInfo.FromBytes(bytes, ref i); @@ -70936,11 +70593,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public CloseCircuitPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; } @@ -71177,11 +70833,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ObjectAddPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -71357,11 +71012,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public MultipleObjectUpdatePacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -71590,11 +71244,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public RequestMultipleObjectsPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -71823,11 +71476,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ObjectPositionPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -72048,11 +71700,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public RequestObjectPropertiesFamilyPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -72271,11 +71922,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public CoarseLocationUpdatePacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; int count = (int)bytes[i++]; @@ -72513,11 +72163,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public CrossedRegionPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -72633,11 +72282,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ConfirmEnableSimulatorPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -72853,11 +72501,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ObjectPropertiesPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; int count = (int)bytes[i++]; @@ -73080,11 +72727,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ObjectPropertiesFamilyPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; ObjectData.FromBytes(bytes, ref i); @@ -73252,11 +72898,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ParcelPropertiesRequestPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -73378,11 +73023,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public AttachedSoundPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; DataBlock.FromBytes(bytes, ref i); @@ -73492,11 +73136,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public AttachedSoundGainChangePacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; DataBlock.FromBytes(bytes, ref i); @@ -73617,11 +73260,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public PreloadSoundPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; int count = (int)bytes[i++]; @@ -73864,11 +73506,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ViewerEffectPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -74043,11 +73684,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public StartPingCheckPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; PingID.FromBytes(bytes, ref i); @@ -74154,11 +73794,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public CompletePingCheckPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; PingID.FromBytes(bytes, ref i); @@ -74299,11 +73938,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public AgentUpdatePacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -74522,11 +74160,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public AgentAnimationPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -74777,11 +74414,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public AgentRequestSitPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -74894,11 +74530,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public AgentSitPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -75070,11 +74705,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public RequestImagePacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -75304,11 +74938,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ImageDataPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; ImageID.FromBytes(bytes, ref i); @@ -75470,11 +75103,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ImagePacketPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; ImageID.FromBytes(bytes, ref i); @@ -75633,11 +75265,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public LayerDataPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; LayerID.FromBytes(bytes, ref i); @@ -75978,11 +75609,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ObjectUpdatePacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; RegionData.FromBytes(bytes, ref i); @@ -76217,11 +75847,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ObjectUpdateCompressedPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; RegionData.FromBytes(bytes, ref i); @@ -76452,11 +76081,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ObjectUpdateCachedPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; RegionData.FromBytes(bytes, ref i); @@ -76695,11 +76323,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ImprovedTerseObjectUpdatePacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; RegionData.FromBytes(bytes, ref i); @@ -76879,11 +76506,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public KillObjectPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; int count = (int)bytes[i++]; @@ -77069,11 +76695,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public TransferPacketPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; TransferData.FromBytes(bytes, ref i); @@ -77232,11 +76857,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public SendXferPacketPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; XferID.FromBytes(bytes, ref i); @@ -77349,11 +76973,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ConfirmXferPacketPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; XferID.FromBytes(bytes, ref i); @@ -77619,11 +77242,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public AvatarAnimationPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; Sender.FromBytes(bytes, ref i); @@ -77913,11 +77535,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public AvatarSitResponsePacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; SitObject.FromBytes(bytes, ref i); @@ -78028,11 +77649,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public CameraConstraintPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; CameraCollidePlane.FromBytes(bytes, ref i); @@ -78436,11 +78056,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ParcelPropertiesPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; ParcelData.FromBytes(bytes, ref i); @@ -79012,11 +78631,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ChildAgentUpdatePacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -79377,11 +78995,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ChildAgentAlivePacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -79521,11 +79138,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ChildAgentPositionUpdatePacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; AgentData.FromBytes(bytes, ref i); @@ -79650,11 +79266,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public SoundTriggerPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; SoundData.FromBytes(bytes, ref i); @@ -79814,11 +79429,10 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ public ObjectAnimationPacket(Header head, byte[] bytes, ref int i): this() { - int packetEnd = bytes.Length - 1; - FromBytes(head, bytes, ref i, ref packetEnd); + FromBytes(head, bytes, ref i); } - override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; Sender.FromBytes(bytes, ref i); diff --git a/Programs/mapgenerator/mapgenerator.cs b/Programs/mapgenerator/mapgenerator.cs index 39cb72f1..caf2eaf3 100644 --- a/Programs/mapgenerator/mapgenerator.cs +++ b/Programs/mapgenerator/mapgenerator.cs @@ -557,11 +557,10 @@ static void WritePacketClass(TextWriter writer, MapPacket packet) //writer.WriteLine(" /// Constructor that takes a byte array and a prebuilt header"); writer.WriteLine(" public " + packet.Name + "Packet(Header head, byte[] bytes, ref int i): this()" + Environment.NewLine + " {" + Environment.NewLine + - " int packetEnd = bytes.Length - 1;" + Environment.NewLine + - " FromBytes(head, bytes, ref i, ref packetEnd);" + Environment.NewLine + + " FromBytes(head, bytes, ref i);" + Environment.NewLine + " }" + Environment.NewLine); - writer.WriteLine(" override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)" + Environment.NewLine + + writer.WriteLine(" override public void FromBytes(Header header, byte[] bytes, ref int i)" + Environment.NewLine + " {"); writer.WriteLine(" Header = header;"); foreach (MapBlock block in packet.Blocks) @@ -996,7 +995,7 @@ static int Main(string[] args) " public PacketType Type;" + Environment.NewLine + " public abstract int Length { get; }" + Environment.NewLine + " public abstract void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer);" + Environment.NewLine + - " public abstract void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd);" + Environment.NewLine + + " public abstract void FromBytes(Header header, byte[] bytes, ref int i);" + Environment.NewLine + " public abstract byte[] ToBytes();" + Environment.NewLine + " public abstract byte[][] ToBytesMultiple();" ); diff --git a/Programs/mapgenerator/template.cs b/Programs/mapgenerator/template.cs index fb7f3649..71313de7 100644 --- a/Programs/mapgenerator/template.cs +++ b/Programs/mapgenerator/template.cs @@ -151,7 +151,7 @@ public void AcksToBytes(byte[] bytes, ref int i) /// /// /// - public static Header BuildHeader(byte[] bytes, ref int pos, ref int packetEnd) + public static Header BuildHeader(byte[] bytes, ref int pos, ref int packetLength) { Header header; byte flags = bytes[pos]; @@ -160,8 +160,9 @@ public static Header BuildHeader(byte[] bytes, ref int pos, ref int packetEnd) header.Reliable = (flags & Helpers.MSG_RELIABLE) != 0; header.Resent = (flags & Helpers.MSG_RESENT) != 0; header.Zerocoded = (flags & Helpers.MSG_ZEROCODED) != 0; - header.Sequence = (uint)((bytes[pos + 1] << 24) + (bytes[pos + 2] << 16) + (bytes[pos + 3] << 8) + bytes[pos + 4]); + header.Sequence = (uint)Utils.BytesToIntBig(bytes, 1); + pos += bytes[pos + 5]; // Set the frequency and packet ID number if (bytes[pos + 6] == 0xFF) { @@ -191,36 +192,21 @@ public static Header BuildHeader(byte[] bytes, ref int pos, ref int packetEnd) pos += 7; } - header.AckList = null; - CreateAckList(ref header, bytes, ref packetEnd); - - return header; - } - - /// - /// - /// - /// - /// - /// - static void CreateAckList(ref Header header, byte[] bytes, ref int packetEnd) - { if (header.AppendedAcks) { - int count = bytes[packetEnd--]; + --packetLength; + int count = bytes[packetLength]; header.AckList = new uint[count]; - for (int i = 0; i < count; i++) { - header.AckList[i] = (uint)( - (bytes[(packetEnd - i * 4) - 3] << 24) | - (bytes[(packetEnd - i * 4) - 2] << 16) | - (bytes[(packetEnd - i * 4) - 1] << 8) | - (bytes[(packetEnd - i * 4) ])); + packetLength -= 4; + header.AckList[i] = (uint)Utils.BytesToIntBig(bytes, packetLength); } - - packetEnd -= (count * 4); } + else + header.AckList = null; + + return header; } } From cd6dc15f71fe87f8a48c352de0cd35c2586bd185 Mon Sep 17 00:00:00 2001 From: Michael Schlenker Date: Mon, 7 Feb 2022 22:44:21 +0100 Subject: [PATCH 028/149] Add aarch64 to Makefile Allow compiling the library for AARCH64 (ARM) --- openjpeg-dotnet/Makefile | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/openjpeg-dotnet/Makefile b/openjpeg-dotnet/Makefile index 2e9383f9..c337990e 100644 --- a/openjpeg-dotnet/Makefile +++ b/openjpeg-dotnet/Makefile @@ -32,6 +32,11 @@ ifeq ($(OSNAME), Linux) ARCHFLAGS=-m64 ARCHSET=1 endif + ifeq ($(ARCH), aarch64) + ARCH=-aarch64 + ARCHFLAGS= + ARCHSET=1 + endif ifeq ($(ARCHSET), 0) ARCH=-i686 ARCHFLAGS=-m32 From 2ca1ff3d57a9d5a350758cc51c36af0975ed8a23 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Fri, 11 Feb 2022 17:36:52 +0000 Subject: [PATCH 029/149] a few changes to osutf8* --- OpenMetaverseTypes/OSUTF8.cs | 31 +++++++++++++++ OpenMetaverseTypes/OSUTF8Slice.cs | 63 +++++++++++++++++++++++++++++++ 2 files changed, 94 insertions(+) diff --git a/OpenMetaverseTypes/OSUTF8.cs b/OpenMetaverseTypes/OSUTF8.cs index 7bfac0e4..cf1427af 100644 --- a/OpenMetaverseTypes/OSUTF8.cs +++ b/OpenMetaverseTypes/OSUTF8.cs @@ -66,6 +66,12 @@ public osUTF8(byte[] source) m_len = source.Length; } + public osUTF8(byte[] source, int len) + { + m_data = source; + m_len = len; + } + public osUTF8(osUTF8Slice source) { m_data = source.ToArray(); @@ -290,6 +296,7 @@ public unsafe bool ACSIILowerEquals(osUTF8 o) return true; } + public unsafe bool ACSIILowerEquals(osUTF8Slice o) { if (o == null || m_len != o.m_len) @@ -314,6 +321,30 @@ public unsafe bool ACSIILowerEquals(osUTF8Slice o) return true; } + public unsafe bool ACSIILowerEquals(byte[] o) + { + if (o == null || m_len != o.Length) + return false; + + fixed (byte* a = m_data, b = o) + { + byte* ptr = a; + byte* end = a + m_len; + byte* ptrb = b; + while (ptr < end) + { + byte c = *ptr; + if (c >= 0x41 && c <= 0x5a) + c |= 0x20; + if (c != *ptrb) + return false; + ++ptr; + ++ptrb; + } + } + return true; + } + public unsafe bool ACSIILowerEquals(string o) { if (string.IsNullOrEmpty(o) || m_len != o.Length) diff --git a/OpenMetaverseTypes/OSUTF8Slice.cs b/OpenMetaverseTypes/OSUTF8Slice.cs index 72a2150f..af9473e3 100644 --- a/OpenMetaverseTypes/OSUTF8Slice.cs +++ b/OpenMetaverseTypes/OSUTF8Slice.cs @@ -179,6 +179,27 @@ public void MoveStart(int of) m_len = m_data.Length - m_offset; } + public void FromBytesSafe(byte[] source, int offset, int len) + { + m_data = source; + m_offset = offset; + m_len = len; + } + + public void FromBytes(byte[] source, int offset, int len) + { + if (source == null || offset >= source.Length || offset + len >= source.Length) + { + m_offset = 0; + m_len = 0; + } + if (len < 0) + len = 0; + m_data = source; + m_offset = offset; + m_len = len; + } + public static bool IsNullOrEmpty(osUTF8Slice u) { return (u == null || u.m_len == 0); @@ -1547,6 +1568,48 @@ public osUTF8Slice RemoveBytes(int start, int len) return o; } + public bool TryParseInt(out int res) + { + res = 0; + + SelfTrim(); + if (m_len == 0) + return false; + + int len = m_len; + int start = m_offset; + len += start; + + bool neg = false; + if (m_data[start] == (byte)'-') + { + neg = true; + ++start; + } + else if (m_data[start] == (byte)'+') + ++start; + + int b; + try + { + while (start < len) + { + b = m_data[start]; + b -= (byte)'0'; + if (b < 0 || b > 9) + break; + + res *= 10; + res += b; + ++start; + } + if (neg) + res = -res; + return true; + } + catch { } + return false; + } public static bool TryParseInt(osUTF8Slice t, out int res) { res = 0; From e0a7550c822480e35a8969c3e7beddca0e74832f Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Fri, 11 Feb 2022 17:46:19 +0000 Subject: [PATCH 030/149] cosmetics --- .../JSON/JsonMapper.cs | 866 ++++++++++-------- OpenMetaverse.StructuredData/JSON/OSDJson.cs | 4 + 2 files changed, 471 insertions(+), 399 deletions(-) diff --git a/OpenMetaverse.StructuredData/JSON/JsonMapper.cs b/OpenMetaverse.StructuredData/JSON/JsonMapper.cs index 598797a4..3c6614f8 100644 --- a/OpenMetaverse.StructuredData/JSON/JsonMapper.cs +++ b/OpenMetaverse.StructuredData/JSON/JsonMapper.cs @@ -22,22 +22,22 @@ namespace LitJson internal struct PropertyMetadata { public MemberInfo Info; - public bool IsField; - public Type Type; + public bool IsField; + public Type Type; } - internal struct ArrayMetadata { private Type element_type; private bool is_array; private bool is_list; - - public Type ElementType { - get { + public Type ElementType + { + get + { if (element_type == null) - return typeof (JsonData); + return typeof(JsonData); return element_type; } @@ -45,18 +45,19 @@ public Type ElementType { set { element_type = value; } } - public bool IsArray { + public bool IsArray + { get { return is_array; } set { is_array = value; } } - public bool IsList { + public bool IsList + { get { return is_list; } set { is_list = value; } } } - internal struct ObjectMetadata { private Type element_type; @@ -64,11 +65,12 @@ internal struct ObjectMetadata private IDictionary properties; - - public Type ElementType { - get { + public Type ElementType + { + get + { if (element_type == null) - return typeof (JsonData); + return typeof(JsonData); return element_type; } @@ -76,26 +78,26 @@ public Type ElementType { set { element_type = value; } } - public bool IsDictionary { + public bool IsDictionary + { get { return is_dictionary; } set { is_dictionary = value; } } - public IDictionary Properties { + public IDictionary Properties + { get { return properties; } set { properties = value; } } } + internal delegate void ExporterFunc(object obj, JsonWriter writer); + public delegate void ExporterFunc(T obj, JsonWriter writer); - internal delegate void ExporterFunc (object obj, JsonWriter writer); - public delegate void ExporterFunc (T obj, JsonWriter writer); - - internal delegate object ImporterFunc (object input); - public delegate TValue ImporterFunc (TJson input); - - public delegate IJsonWrapper WrapperFactory (); + internal delegate object ImporterFunc(object input); + public delegate TValue ImporterFunc(TJson input); + public delegate IJsonWrapper WrapperFactory(); public class JsonMapper { @@ -107,195 +109,208 @@ public class JsonMapper private static IDictionary base_exporters_table; private static IDictionary custom_exporters_table; - private static IDictionary> base_importers_table; - private static IDictionary> custom_importers_table; + private static IDictionary> base_importers_table; + private static IDictionary> custom_importers_table; private static IDictionary array_metadata; - private static readonly object array_metadata_lock = new Object (); + private static readonly object array_metadata_lock = new object(); - private static IDictionary> conv_ops; - private static readonly object conv_ops_lock = new Object (); + private static IDictionary> conv_ops; + private static readonly object conv_ops_lock = new object(); private static IDictionary object_metadata; - private static readonly object object_metadata_lock = new Object (); + private static readonly object object_metadata_lock = new object(); - private static IDictionary> type_properties; - private static readonly object type_properties_lock = new Object (); + private static IDictionary> type_properties; + private static readonly object type_properties_lock = new object(); - private static JsonWriter static_writer; - private static readonly object static_writer_lock = new Object (); + private static JsonWriter static_writer; + private static readonly object static_writer_lock = new object(); #endregion - #region Constructors - static JsonMapper () + static JsonMapper() { max_nesting_depth = 100; - array_metadata = new Dictionary (); - conv_ops = new Dictionary> (); - object_metadata = new Dictionary (); - type_properties = new Dictionary> (); + array_metadata = new Dictionary(); + conv_ops = new Dictionary>(); + object_metadata = new Dictionary(); + type_properties = new Dictionary>(); - static_writer = new JsonWriter (); + static_writer = new JsonWriter(); datetime_format = DateTimeFormatInfo.InvariantInfo; - base_exporters_table = new Dictionary (); - custom_exporters_table = new Dictionary (); + base_exporters_table = new Dictionary(); + custom_exporters_table = new Dictionary(); - base_importers_table = new Dictionary> (); - custom_importers_table = new Dictionary> (); + base_importers_table = new Dictionary>(); + custom_importers_table = new Dictionary>(); - RegisterBaseExporters (); - RegisterBaseImporters (); + RegisterBaseExporters(); + RegisterBaseImporters(); } #endregion - #region Private Methods - private static void AddArrayMetadata (Type type) + private static void AddArrayMetadata(Type type) { - if (array_metadata.ContainsKey (type)) + if (array_metadata.ContainsKey(type)) return; - ArrayMetadata data = new ArrayMetadata (); + ArrayMetadata data = new ArrayMetadata(); data.IsArray = type.IsArray; - if (type.GetInterface ("System.Collections.IList") != null) + if (type.GetInterface("System.Collections.IList") != null) data.IsList = true; - foreach (PropertyInfo p_info in type.GetProperties ()) { + foreach (PropertyInfo p_info in type.GetProperties()) + { if (p_info.Name != "Item") continue; - ParameterInfo[] parameters = p_info.GetIndexParameters (); + ParameterInfo[] parameters = p_info.GetIndexParameters(); if (parameters.Length != 1) continue; - if (parameters[0].ParameterType == typeof (int)) + if (parameters[0].ParameterType == typeof(int)) data.ElementType = p_info.PropertyType; } - lock (array_metadata_lock) { - try { - array_metadata.Add (type, data); - } catch (ArgumentException) { + lock (array_metadata_lock) + { + try + { + array_metadata.Add(type, data); + } + catch (ArgumentException) + { return; } } } - private static void AddObjectMetadata (Type type) + private static void AddObjectMetadata(Type type) { - if (object_metadata.ContainsKey (type)) + if (object_metadata.ContainsKey(type)) return; - ObjectMetadata data = new ObjectMetadata (); + ObjectMetadata data = new ObjectMetadata(); - if (type.GetInterface ("System.Collections.IDictionary") != null) + if (type.GetInterface("System.Collections.IDictionary") != null) data.IsDictionary = true; - data.Properties = new Dictionary (); + data.Properties = new Dictionary(); - foreach (PropertyInfo p_info in type.GetProperties ()) { - if (p_info.Name == "Item") { - ParameterInfo[] parameters = p_info.GetIndexParameters (); + foreach (PropertyInfo p_info in type.GetProperties()) + { + if (p_info.Name == "Item") + { + ParameterInfo[] parameters = p_info.GetIndexParameters(); if (parameters.Length != 1) continue; - if (parameters[0].ParameterType == typeof (string)) + if (parameters[0].ParameterType == typeof(string)) data.ElementType = p_info.PropertyType; continue; } - PropertyMetadata p_data = new PropertyMetadata (); + PropertyMetadata p_data = new PropertyMetadata(); p_data.Info = p_info; p_data.Type = p_info.PropertyType; - data.Properties.Add (p_info.Name, p_data); + data.Properties.Add(p_info.Name, p_data); } - foreach (FieldInfo f_info in type.GetFields ()) { - PropertyMetadata p_data = new PropertyMetadata (); + foreach (FieldInfo f_info in type.GetFields()) + { + PropertyMetadata p_data = new PropertyMetadata(); p_data.Info = f_info; p_data.IsField = true; p_data.Type = f_info.FieldType; - data.Properties.Add (f_info.Name, p_data); + data.Properties.Add(f_info.Name, p_data); } - lock (object_metadata_lock) { - try { - object_metadata.Add (type, data); - } catch (ArgumentException) { + lock (object_metadata_lock) + { + try + { + object_metadata.Add(type, data); + } + catch (ArgumentException) + { return; } } } - private static void AddTypeProperties (Type type) + private static void AddTypeProperties(Type type) { - if (type_properties.ContainsKey (type)) + if (type_properties.ContainsKey(type)) return; - IList props = new List (); + IList props = new List(); - foreach (PropertyInfo p_info in type.GetProperties ()) { + foreach (PropertyInfo p_info in type.GetProperties()) + { if (p_info.Name == "Item") continue; - PropertyMetadata p_data = new PropertyMetadata (); + PropertyMetadata p_data = new PropertyMetadata(); p_data.Info = p_info; p_data.IsField = false; - props.Add (p_data); + props.Add(p_data); } - foreach (FieldInfo f_info in type.GetFields ()) { - PropertyMetadata p_data = new PropertyMetadata (); + foreach (FieldInfo f_info in type.GetFields()) + { + PropertyMetadata p_data = new PropertyMetadata(); p_data.Info = f_info; p_data.IsField = true; - props.Add (p_data); + props.Add(p_data); } - lock (type_properties_lock) { - try { - type_properties.Add (type, props); - } catch (ArgumentException) { + lock (type_properties_lock) + { + try + { + type_properties.Add(type, props); + } + catch (ArgumentException) + { return; } } } - private static MethodInfo GetConvOp (Type t1, Type t2) + private static MethodInfo GetConvOp(Type t1, Type t2) { - lock (conv_ops_lock) { - if (! conv_ops.ContainsKey (t1)) - conv_ops.Add (t1, new Dictionary ()); + lock (conv_ops_lock) + { + if (!conv_ops.ContainsKey(t1)) + conv_ops.Add(t1, new Dictionary()); } - if (conv_ops[t1].ContainsKey (t2)) + if (conv_ops[t1].ContainsKey(t2)) return conv_ops[t1][t2]; - MethodInfo op = t1.GetMethod ( - "op_Implicit", new Type[] { t2 }); + MethodInfo op = t1.GetMethod("op_Implicit", new Type[] { t2 }); - lock (conv_ops_lock) { - try { - conv_ops[t1].Add (t2, op); - } catch (ArgumentException) { + lock (conv_ops_lock) + { + try + { + conv_ops[t1].Add(t2, op); + } + catch (ArgumentException) + { return conv_ops[t1][t2]; } } @@ -303,9 +318,9 @@ private static MethodInfo GetConvOp (Type t1, Type t2) return op; } - private static object ReadValue (Type inst_type, JsonReader reader) + private static object ReadValue(Type inst_type, JsonReader reader) { - reader.Read (); + reader.Read(); if (reader.Token == JsonToken.ArrayEnd) return null; @@ -313,12 +328,14 @@ private static object ReadValue (Type inst_type, JsonReader reader) Type underlying_type = Nullable.GetUnderlyingType(inst_type); Type value_type = underlying_type ?? inst_type; - if (reader.Token == JsonToken.Null) { - if (inst_type.IsClass || underlying_type != null) { + if (reader.Token == JsonToken.Null) + { + if (inst_type.IsClass || underlying_type != null) + { return null; } - throw new JsonException (String.Format ( + throw new JsonException(String.Format( "Can't assign null to an instance of type {0}", inst_type)); } @@ -327,211 +344,221 @@ private static object ReadValue (Type inst_type, JsonReader reader) reader.Token == JsonToken.Int || reader.Token == JsonToken.Long || reader.Token == JsonToken.String || - reader.Token == JsonToken.Boolean) { - - Type json_type = reader.Value.GetType (); + reader.Token == JsonToken.Boolean) + { + Type json_type = reader.Value.GetType(); - if (value_type.IsAssignableFrom (json_type)) + if (value_type.IsAssignableFrom(json_type)) return reader.Value; // If there's a custom importer that fits, use it - if (custom_importers_table.ContainsKey (json_type) && - custom_importers_table[json_type].ContainsKey ( - value_type)) { - - ImporterFunc importer = - custom_importers_table[json_type][value_type]; - - return importer (reader.Value); + if (custom_importers_table.ContainsKey(json_type) && + custom_importers_table[json_type].ContainsKey(value_type)) + { + ImporterFunc importer = custom_importers_table[json_type][value_type]; + return importer(reader.Value); } // Maybe there's a base importer that works - if (base_importers_table.ContainsKey (json_type) && - base_importers_table[json_type].ContainsKey ( - value_type)) { - - ImporterFunc importer = - base_importers_table[json_type][value_type]; - - return importer (reader.Value); + if (base_importers_table.ContainsKey(json_type) && + base_importers_table[json_type].ContainsKey(value_type)) + { + ImporterFunc importer = base_importers_table[json_type][value_type]; + return importer(reader.Value); } // Maybe it's an enum if (value_type.IsEnum) - return Enum.ToObject (value_type, reader.Value); + return Enum.ToObject(value_type, reader.Value); // Try using an implicit conversion operator - MethodInfo conv_op = GetConvOp (value_type, json_type); + MethodInfo conv_op = GetConvOp(value_type, json_type); if (conv_op != null) - return conv_op.Invoke (null, - new object[] { reader.Value }); + return conv_op.Invoke(null, new object[] { reader.Value }); // No luck - throw new JsonException (String.Format ( + throw new JsonException(String.Format( "Can't assign value '{0}' (type {1}) to type {2}", reader.Value, json_type, inst_type)); } object instance = null; - if (reader.Token == JsonToken.ArrayStart) { - - AddArrayMetadata (inst_type); + if (reader.Token == JsonToken.ArrayStart) + { + AddArrayMetadata(inst_type); ArrayMetadata t_data = array_metadata[inst_type]; - if (! t_data.IsArray && ! t_data.IsList) - throw new JsonException (String.Format ( + if (!t_data.IsArray && !t_data.IsList) + throw new JsonException(String.Format( "Type {0} can't act as an array", inst_type)); IList list; Type elem_type; - if (! t_data.IsArray) { - list = (IList) Activator.CreateInstance (inst_type); + if (!t_data.IsArray) + { + list = (IList)Activator.CreateInstance(inst_type); elem_type = t_data.ElementType; - } else { - list = new ArrayList (); - elem_type = inst_type.GetElementType (); + } + else + { + list = new ArrayList(); + elem_type = inst_type.GetElementType(); } - while (true) { - object item = ReadValue (elem_type, reader); + while (true) + { + object item = ReadValue(elem_type, reader); if (item == null && reader.Token == JsonToken.ArrayEnd) break; - list.Add (item); + list.Add(item); } - if (t_data.IsArray) { + if (t_data.IsArray) + { int n = list.Count; - instance = Array.CreateInstance (elem_type, n); + instance = Array.CreateInstance(elem_type, n); for (int i = 0; i < n; i++) - ((Array) instance).SetValue (list[i], i); - } else + ((Array)instance).SetValue(list[i], i); + } + else instance = list; - } else if (reader.Token == JsonToken.ObjectStart) { - AddObjectMetadata (value_type); + } + else if (reader.Token == JsonToken.ObjectStart) + { + AddObjectMetadata(value_type); ObjectMetadata t_data = object_metadata[value_type]; - instance = Activator.CreateInstance (value_type); + instance = Activator.CreateInstance(value_type); - while (true) { - reader.Read (); + while (true) + { + reader.Read(); if (reader.Token == JsonToken.ObjectEnd) break; - string property = (string) reader.Value; + string property = (string)reader.Value; - if (t_data.Properties.ContainsKey (property)) { - PropertyMetadata prop_data = - t_data.Properties[property]; + if (t_data.Properties.ContainsKey(property)) + { + PropertyMetadata prop_data = t_data.Properties[property]; - if (prop_data.IsField) { - ((FieldInfo) prop_data.Info).SetValue ( - instance, ReadValue (prop_data.Type, reader)); - } else { - PropertyInfo p_info = - (PropertyInfo) prop_data.Info; + if (prop_data.IsField) + { + ((FieldInfo)prop_data.Info).SetValue( + instance, ReadValue(prop_data.Type, reader)); + } + else + { + PropertyInfo p_info = (PropertyInfo)prop_data.Info; if (p_info.CanWrite) - p_info.SetValue ( - instance, - ReadValue (prop_data.Type, reader), - null); + p_info.SetValue(instance, ReadValue(prop_data.Type, reader), null); else - ReadValue (prop_data.Type, reader); + ReadValue(prop_data.Type, reader); } - } else { - if (! t_data.IsDictionary) { - - if (! reader.SkipNonMembers) { - throw new JsonException (String.Format ( + } + else + { + if (!t_data.IsDictionary) + { + + if (!reader.SkipNonMembers) + { + throw new JsonException(String.Format( "The type {0} doesn't have the " + "property '{1}'", inst_type, property)); - } else { - ReadSkip (reader); + } + else + { + ReadSkip(reader); continue; } } - ((IDictionary) instance).Add ( - property, ReadValue ( - t_data.ElementType, reader)); + ((IDictionary)instance).Add( property, ReadValue(t_data.ElementType, reader)); } - } - } return instance; } - private static IJsonWrapper ReadValue (WrapperFactory factory, - JsonReader reader) + private static IJsonWrapper ReadValue(WrapperFactory factory, JsonReader reader) { - reader.Read (); + reader.Read(); - if (reader.Token == JsonToken.ArrayEnd || - reader.Token == JsonToken.Null) + if (reader.Token == JsonToken.ArrayEnd || reader.Token == JsonToken.Null) return null; - IJsonWrapper instance = factory (); + IJsonWrapper instance = factory(); - if (reader.Token == JsonToken.String) { - instance.SetString ((string) reader.Value); + if (reader.Token == JsonToken.String) + { + instance.SetString((string)reader.Value); return instance; } - if (reader.Token == JsonToken.Double) { - instance.SetDouble ((double) reader.Value); + if (reader.Token == JsonToken.Double) + { + instance.SetDouble((double)reader.Value); return instance; } - if (reader.Token == JsonToken.Int) { - instance.SetInt ((int) reader.Value); + if (reader.Token == JsonToken.Int) + { + instance.SetInt((int)reader.Value); return instance; } - if (reader.Token == JsonToken.Long) { - instance.SetLong ((long) reader.Value); + if (reader.Token == JsonToken.Long) + { + instance.SetLong((long)reader.Value); return instance; } - if (reader.Token == JsonToken.Boolean) { - instance.SetBoolean ((bool) reader.Value); + if (reader.Token == JsonToken.Boolean) + { + instance.SetBoolean((bool)reader.Value); return instance; } - if (reader.Token == JsonToken.ArrayStart) { - instance.SetJsonType (JsonType.Array); + if (reader.Token == JsonToken.ArrayStart) + { + instance.SetJsonType(JsonType.Array); - while (true) { - IJsonWrapper item = ReadValue (factory, reader); + while (true) + { + IJsonWrapper item = ReadValue(factory, reader); if (item == null && reader.Token == JsonToken.ArrayEnd) break; - ((IList) instance).Add (item); + ((IList)instance).Add(item); } } - else if (reader.Token == JsonToken.ObjectStart) { - instance.SetJsonType (JsonType.Object); + else if (reader.Token == JsonToken.ObjectStart) + { + instance.SetJsonType(JsonType.Object); - while (true) { - reader.Read (); + while (true) + { + reader.Read(); if (reader.Token == JsonToken.ObjectEnd) break; - string property = (string) reader.Value; + string property = (string)reader.Value; - ((IDictionary) instance)[property] = ReadValue ( + ((IDictionary)instance)[property] = ReadValue( factory, reader); } @@ -540,388 +567,429 @@ private static IJsonWrapper ReadValue (WrapperFactory factory, return instance; } - private static void ReadSkip (JsonReader reader) + private static void ReadSkip(JsonReader reader) { - ToWrapper ( - delegate { return new JsonMockWrapper (); }, reader); + ToWrapper(delegate { return new JsonMockWrapper(); }, reader); } - private static void RegisterBaseExporters () + private static void RegisterBaseExporters() { - base_exporters_table[typeof (byte)] = - delegate (object obj, JsonWriter writer) { - writer.Write (Convert.ToInt32 ((byte) obj)); + base_exporters_table[typeof(byte)] = + delegate (object obj, JsonWriter writer) + { + writer.Write(Convert.ToInt32((byte)obj)); }; - base_exporters_table[typeof (char)] = - delegate (object obj, JsonWriter writer) { - writer.Write (Convert.ToString ((char) obj)); + base_exporters_table[typeof(char)] = + delegate (object obj, JsonWriter writer) + { + writer.Write(Convert.ToString((char)obj)); }; - base_exporters_table[typeof (DateTime)] = - delegate (object obj, JsonWriter writer) { - writer.Write (Convert.ToString ((DateTime) obj, + base_exporters_table[typeof(DateTime)] = + delegate (object obj, JsonWriter writer) + { + writer.Write(Convert.ToString((DateTime)obj, datetime_format)); }; - base_exporters_table[typeof (decimal)] = - delegate (object obj, JsonWriter writer) { - writer.Write ((decimal) obj); + base_exporters_table[typeof(decimal)] = + delegate (object obj, JsonWriter writer) + { + writer.Write((decimal)obj); }; - base_exporters_table[typeof (sbyte)] = - delegate (object obj, JsonWriter writer) { - writer.Write (Convert.ToInt32 ((sbyte) obj)); + base_exporters_table[typeof(sbyte)] = + delegate (object obj, JsonWriter writer) + { + writer.Write(Convert.ToInt32((sbyte)obj)); }; - base_exporters_table[typeof (short)] = - delegate (object obj, JsonWriter writer) { - writer.Write (Convert.ToInt32 ((short) obj)); + base_exporters_table[typeof(short)] = + delegate (object obj, JsonWriter writer) + { + writer.Write(Convert.ToInt32((short)obj)); }; - base_exporters_table[typeof (ushort)] = - delegate (object obj, JsonWriter writer) { - writer.Write (Convert.ToInt32 ((ushort) obj)); + base_exporters_table[typeof(ushort)] = + delegate (object obj, JsonWriter writer) + { + writer.Write(Convert.ToInt32((ushort)obj)); }; - base_exporters_table[typeof (uint)] = - delegate (object obj, JsonWriter writer) { - writer.Write (Convert.ToUInt64 ((uint) obj)); + base_exporters_table[typeof(uint)] = + delegate (object obj, JsonWriter writer) + { + writer.Write(Convert.ToUInt64((uint)obj)); }; - base_exporters_table[typeof (ulong)] = - delegate (object obj, JsonWriter writer) { - writer.Write ((ulong) obj); + base_exporters_table[typeof(ulong)] = + delegate (object obj, JsonWriter writer) + { + writer.Write((ulong)obj); }; } - private static void RegisterBaseImporters () + private static void RegisterBaseImporters() { ImporterFunc importer; - importer = delegate (object input) { - return Convert.ToByte ((int) input); + importer = delegate (object input) + { + return Convert.ToByte((int)input); }; - RegisterImporter (base_importers_table, typeof (int), - typeof (byte), importer); + RegisterImporter(base_importers_table, typeof(int), + typeof(byte), importer); - importer = delegate (object input) { - return Convert.ToUInt64 ((int) input); + importer = delegate (object input) + { + return Convert.ToUInt64((int)input); }; - RegisterImporter (base_importers_table, typeof (int), - typeof (ulong), importer); + RegisterImporter(base_importers_table, typeof(int), + typeof(ulong), importer); - importer = delegate (object input) { - return Convert.ToSByte ((int) input); + importer = delegate (object input) + { + return Convert.ToSByte((int)input); }; - RegisterImporter (base_importers_table, typeof (int), - typeof (sbyte), importer); + RegisterImporter(base_importers_table, typeof(int), + typeof(sbyte), importer); - importer = delegate (object input) { - return Convert.ToInt16 ((int) input); + importer = delegate (object input) + { + return Convert.ToInt16((int)input); }; - RegisterImporter (base_importers_table, typeof (int), - typeof (short), importer); + RegisterImporter(base_importers_table, typeof(int), + typeof(short), importer); - importer = delegate (object input) { - return Convert.ToUInt16 ((int) input); + importer = delegate (object input) + { + return Convert.ToUInt16((int)input); }; - RegisterImporter (base_importers_table, typeof (int), - typeof (ushort), importer); + RegisterImporter(base_importers_table, typeof(int), + typeof(ushort), importer); - importer = delegate (object input) { - return Convert.ToUInt32 ((int) input); + importer = delegate (object input) + { + return Convert.ToUInt32((int)input); }; - RegisterImporter (base_importers_table, typeof (int), - typeof (uint), importer); + RegisterImporter(base_importers_table, typeof(int), + typeof(uint), importer); - importer = delegate (object input) { - return Convert.ToSingle ((int) input); + importer = delegate (object input) + { + return Convert.ToSingle((int)input); }; - RegisterImporter (base_importers_table, typeof (int), - typeof (float), importer); + RegisterImporter(base_importers_table, typeof(int), + typeof(float), importer); - importer = delegate (object input) { - return Convert.ToDouble ((int) input); + importer = delegate (object input) + { + return Convert.ToDouble((int)input); }; - RegisterImporter (base_importers_table, typeof (int), - typeof (double), importer); + RegisterImporter(base_importers_table, typeof(int), + typeof(double), importer); - importer = delegate (object input) { - return Convert.ToDecimal ((double) input); + importer = delegate (object input) + { + return Convert.ToDecimal((double)input); }; - RegisterImporter (base_importers_table, typeof (double), - typeof (decimal), importer); + RegisterImporter(base_importers_table, typeof(double), + typeof(decimal), importer); - importer = delegate (object input) { - return Convert.ToUInt32 ((long) input); + importer = delegate (object input) + { + return Convert.ToUInt32((long)input); }; - RegisterImporter (base_importers_table, typeof (long), - typeof (uint), importer); + RegisterImporter(base_importers_table, typeof(long), + typeof(uint), importer); - importer = delegate (object input) { - return Convert.ToChar ((string) input); + importer = delegate (object input) + { + return Convert.ToChar((string)input); }; - RegisterImporter (base_importers_table, typeof (string), - typeof (char), importer); + RegisterImporter(base_importers_table, typeof(string), + typeof(char), importer); - importer = delegate (object input) { - return Convert.ToDateTime ((string) input, datetime_format); + importer = delegate (object input) + { + return Convert.ToDateTime((string)input, datetime_format); }; - RegisterImporter (base_importers_table, typeof (string), - typeof (DateTime), importer); + RegisterImporter(base_importers_table, typeof(string), + typeof(DateTime), importer); } - private static void RegisterImporter ( + private static void RegisterImporter( IDictionary> table, Type json_type, Type value_type, ImporterFunc importer) { - if (! table.ContainsKey (json_type)) - table.Add (json_type, new Dictionary ()); + if (!table.ContainsKey(json_type)) + table.Add(json_type, new Dictionary()); table[json_type][value_type] = importer; } - private static void WriteValue (object obj, JsonWriter writer, + private static void WriteValue(object obj, JsonWriter writer, bool writer_is_private, int depth) { if (depth > max_nesting_depth) - throw new JsonException ( - String.Format ("Max allowed object depth reached while " + + throw new JsonException( + String.Format("Max allowed object depth reached while " + "trying to export from type {0}", - obj.GetType ())); + obj.GetType())); - if (obj == null) { - writer.Write (null); + if (obj == null) + { + writer.Write(null); return; } - if (obj is IJsonWrapper) { + if (obj is IJsonWrapper) + { if (writer_is_private) - writer.TextWriter.Write (((IJsonWrapper) obj).ToJson ()); + writer.TextWriter.Write(((IJsonWrapper)obj).ToJson()); else - ((IJsonWrapper) obj).ToJson (writer); + ((IJsonWrapper)obj).ToJson(writer); return; } - if (obj is String) { - writer.Write ((string) obj); + if (obj is String) + { + writer.Write((string)obj); return; } - if (obj is Double) { - writer.Write ((double) obj); + if (obj is Double) + { + writer.Write((double)obj); return; } - if (obj is Int32) { - writer.Write ((int) obj); + if (obj is Int32) + { + writer.Write((int)obj); return; } - if (obj is Boolean) { - writer.Write ((bool) obj); + if (obj is Boolean) + { + writer.Write((bool)obj); return; } - if (obj is Int64) { - writer.Write ((long) obj); + if (obj is Int64) + { + writer.Write((long)obj); return; } - if (obj is Array) { - writer.WriteArrayStart (); + if (obj is Array) + { + writer.WriteArrayStart(); - foreach (object elem in (Array) obj) - WriteValue (elem, writer, writer_is_private, depth + 1); + foreach (object elem in (Array)obj) + WriteValue(elem, writer, writer_is_private, depth + 1); - writer.WriteArrayEnd (); + writer.WriteArrayEnd(); return; } - if (obj is IList) { - writer.WriteArrayStart (); - foreach (object elem in (IList) obj) - WriteValue (elem, writer, writer_is_private, depth + 1); - writer.WriteArrayEnd (); + if (obj is IList) + { + writer.WriteArrayStart(); + foreach (object elem in (IList)obj) + WriteValue(elem, writer, writer_is_private, depth + 1); + writer.WriteArrayEnd(); return; } - if (obj is IDictionary) { - writer.WriteObjectStart (); - foreach (DictionaryEntry entry in (IDictionary) obj) { - writer.WritePropertyName ((string) entry.Key); - WriteValue (entry.Value, writer, writer_is_private, + if (obj is IDictionary) + { + writer.WriteObjectStart(); + foreach (DictionaryEntry entry in (IDictionary)obj) + { + writer.WritePropertyName((string)entry.Key); + WriteValue(entry.Value, writer, writer_is_private, depth + 1); } - writer.WriteObjectEnd (); + writer.WriteObjectEnd(); return; } - Type obj_type = obj.GetType (); + Type obj_type = obj.GetType(); // See if there's a custom exporter for the object - if (custom_exporters_table.ContainsKey (obj_type)) { + if (custom_exporters_table.ContainsKey(obj_type)) + { ExporterFunc exporter = custom_exporters_table[obj_type]; - exporter (obj, writer); + exporter(obj, writer); return; } // If not, maybe there's a base exporter - if (base_exporters_table.ContainsKey (obj_type)) { + if (base_exporters_table.ContainsKey(obj_type)) + { ExporterFunc exporter = base_exporters_table[obj_type]; - exporter (obj, writer); + exporter(obj, writer); return; } // Last option, let's see if it's an enum - if (obj is Enum) { - Type e_type = Enum.GetUnderlyingType (obj_type); - - if (e_type == typeof (long) - || e_type == typeof (uint) - || e_type == typeof (ulong)) - writer.Write ((ulong) obj); + if (obj is Enum) + { + Type e_type = Enum.GetUnderlyingType(obj_type); + + if (e_type == typeof(long) + || e_type == typeof(uint) + || e_type == typeof(ulong)) + writer.Write((ulong)obj); else - writer.Write ((int) obj); + writer.Write((int)obj); return; } // Okay, so it looks like the input should be exported as an // object - AddTypeProperties (obj_type); + AddTypeProperties(obj_type); IList props = type_properties[obj_type]; - writer.WriteObjectStart (); - foreach (PropertyMetadata p_data in props) { - if (p_data.IsField) { - writer.WritePropertyName (p_data.Info.Name); - WriteValue (((FieldInfo) p_data.Info).GetValue (obj), + writer.WriteObjectStart(); + foreach (PropertyMetadata p_data in props) + { + if (p_data.IsField) + { + writer.WritePropertyName(p_data.Info.Name); + WriteValue(((FieldInfo)p_data.Info).GetValue(obj), writer, writer_is_private, depth + 1); } - else { - PropertyInfo p_info = (PropertyInfo) p_data.Info; + else + { + PropertyInfo p_info = (PropertyInfo)p_data.Info; - if (p_info.CanRead) { - writer.WritePropertyName (p_data.Info.Name); - WriteValue (p_info.GetValue (obj, null), + if (p_info.CanRead) + { + writer.WritePropertyName(p_data.Info.Name); + WriteValue(p_info.GetValue(obj, null), writer, writer_is_private, depth + 1); } } } - writer.WriteObjectEnd (); + writer.WriteObjectEnd(); } #endregion - public static string ToJson (object obj) + public static string ToJson(object obj) { - lock (static_writer_lock) { - static_writer.Reset (); + lock (static_writer_lock) + { + static_writer.Reset(); - WriteValue (obj, static_writer, true, 0); + WriteValue(obj, static_writer, true, 0); - return static_writer.ToString (); + return static_writer.ToString(); } } - public static void ToJson (object obj, JsonWriter writer) + public static void ToJson(object obj, JsonWriter writer) { - WriteValue (obj, writer, false, 0); + WriteValue(obj, writer, false, 0); } - public static JsonData ToObject (JsonReader reader) + public static JsonData ToObject(JsonReader reader) { - return (JsonData) ToWrapper ( - delegate { return new JsonData (); }, reader); + return (JsonData)ToWrapper( + delegate { return new JsonData(); }, reader); } - public static JsonData ToObject (TextReader reader) + public static JsonData ToObject(TextReader reader) { - JsonReader json_reader = new JsonReader (reader); + JsonReader json_reader = new JsonReader(reader); - return (JsonData) ToWrapper ( - delegate { return new JsonData (); }, json_reader); + return (JsonData)ToWrapper( + delegate { return new JsonData(); }, json_reader); } - public static JsonData ToObject (string json) + public static JsonData ToObject(string json) { - return (JsonData) ToWrapper ( - delegate { return new JsonData (); }, json); + return (JsonData)ToWrapper( + delegate { return new JsonData(); }, json); } - public static T ToObject (JsonReader reader) + public static T ToObject(JsonReader reader) { - return (T) ReadValue (typeof (T), reader); + return (T)ReadValue(typeof(T), reader); } - public static T ToObject (TextReader reader) + public static T ToObject(TextReader reader) { - JsonReader json_reader = new JsonReader (reader); + JsonReader json_reader = new JsonReader(reader); - return (T) ReadValue (typeof (T), json_reader); + return (T)ReadValue(typeof(T), json_reader); } - public static T ToObject (string json) + public static T ToObject(string json) { - JsonReader reader = new JsonReader (json); + JsonReader reader = new JsonReader(json); - return (T) ReadValue (typeof (T), reader); + return (T)ReadValue(typeof(T), reader); } - public static IJsonWrapper ToWrapper (WrapperFactory factory, + public static IJsonWrapper ToWrapper(WrapperFactory factory, JsonReader reader) { - return ReadValue (factory, reader); + return ReadValue(factory, reader); } - public static IJsonWrapper ToWrapper (WrapperFactory factory, + public static IJsonWrapper ToWrapper(WrapperFactory factory, string json) { - JsonReader reader = new JsonReader (json); + JsonReader reader = new JsonReader(json); - return ReadValue (factory, reader); + return ReadValue(factory, reader); } - public static void RegisterExporter (ExporterFunc exporter) + public static void RegisterExporter(ExporterFunc exporter) { ExporterFunc exporter_wrapper = - delegate (object obj, JsonWriter writer) { - exporter ((T) obj, writer); + delegate (object obj, JsonWriter writer) + { + exporter((T)obj, writer); }; - custom_exporters_table[typeof (T)] = exporter_wrapper; + custom_exporters_table[typeof(T)] = exporter_wrapper; } - public static void RegisterImporter ( + public static void RegisterImporter( ImporterFunc importer) { ImporterFunc importer_wrapper = - delegate (object input) { - return importer ((TJson) input); + delegate (object input) + { + return importer((TJson)input); }; - RegisterImporter (custom_importers_table, typeof (TJson), - typeof (TValue), importer_wrapper); + RegisterImporter(custom_importers_table, typeof(TJson), + typeof(TValue), importer_wrapper); } - public static void UnregisterExporters () + public static void UnregisterExporters() { - custom_exporters_table.Clear (); + custom_exporters_table.Clear(); } - public static void UnregisterImporters () + public static void UnregisterImporters() { - custom_importers_table.Clear (); + custom_importers_table.Clear(); } } } diff --git a/OpenMetaverse.StructuredData/JSON/OSDJson.cs b/OpenMetaverse.StructuredData/JSON/OSDJson.cs index ceae0938..60442e26 100644 --- a/OpenMetaverse.StructuredData/JSON/OSDJson.cs +++ b/OpenMetaverse.StructuredData/JSON/OSDJson.cs @@ -100,6 +100,8 @@ public static JsonData SerializeJson(OSD osd, bool preserveDefaults) case OSDType.Date: case OSDType.URI: case OSDType.UUID: + case OSDType.OSDUTF8: + case OSDType.LLSDxml: return new JsonData(osd.AsString()); case OSDType.Binary: byte[] binary = osd.AsBinary(); @@ -163,6 +165,8 @@ private static JsonData SerializeJsonNoDefaults(OSD osd) case OSDType.String: case OSDType.Date: case OSDType.URI: + case OSDType.OSDUTF8: + case OSDType.LLSDxml: string str = osd.AsString(); if (String.IsNullOrEmpty(str)) return null; From a4dcb7e86bfe5a3b5bfa9a6fda198d1b9ac26a67 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Fri, 11 Feb 2022 18:04:37 +0000 Subject: [PATCH 031/149] cosmetics --- OpenMetaverse.StructuredData/JSON/JsonData.cs | 759 ++++++++------- .../JSON/JsonException.cs | 31 +- .../JSON/JsonMockWrapper.cs | 108 ++- .../JSON/JsonReader.cs | 381 ++++---- .../JSON/JsonWriter.cs | 409 ++++---- OpenMetaverse.StructuredData/JSON/Lexer.cs | 901 ++++++++++-------- 6 files changed, 1386 insertions(+), 1203 deletions(-) diff --git a/OpenMetaverse.StructuredData/JSON/JsonData.cs b/OpenMetaverse.StructuredData/JSON/JsonData.cs index 0049aa8a..ebd1dcd8 100644 --- a/OpenMetaverse.StructuredData/JSON/JsonData.cs +++ b/OpenMetaverse.StructuredData/JSON/JsonData.cs @@ -22,119 +22,141 @@ namespace LitJson public class JsonData : IJsonWrapper, IEquatable { #region Fields - private IList inst_array; - private bool inst_boolean; - private double inst_double; - private int inst_int; - private long inst_long; + private IList inst_array; + private bool inst_boolean; + private double inst_double; + private int inst_int; + private long inst_long; private IDictionary inst_object; - private string inst_string; - private string json; - private JsonType type; + private string inst_string; + private string json; + private JsonType type; // Used to implement the IOrderedDictionary interface private IList> object_list; #endregion - #region Properties - public int Count { - get { return EnsureCollection ().Count; } + public int Count + { + get { return EnsureCollection().Count; } } - public bool IsArray { + public bool IsArray + { get { return type == JsonType.Array; } } - public bool IsBoolean { + public bool IsBoolean + { get { return type == JsonType.Boolean; } } - public bool IsDouble { + public bool IsDouble + { get { return type == JsonType.Double; } } - public bool IsInt { + public bool IsInt + { get { return type == JsonType.Int; } } - public bool IsLong { + public bool IsLong + { get { return type == JsonType.Long; } } - public bool IsObject { + public bool IsObject + { get { return type == JsonType.Object; } } - public bool IsString { + public bool IsString + { get { return type == JsonType.String; } } - public ICollection Keys { - get { EnsureDictionary (); return inst_object.Keys; } + public ICollection Keys + { + get { EnsureDictionary(); return inst_object.Keys; } } #endregion #region ICollection Properties - int ICollection.Count { - get { + int ICollection.Count + { + get + { return Count; } } - bool ICollection.IsSynchronized { - get { - return EnsureCollection ().IsSynchronized; + bool ICollection.IsSynchronized + { + get + { + return EnsureCollection().IsSynchronized; } } - object ICollection.SyncRoot { - get { - return EnsureCollection ().SyncRoot; + object ICollection.SyncRoot + { + get + { + return EnsureCollection().SyncRoot; } } #endregion #region IDictionary Properties - bool IDictionary.IsFixedSize { - get { - return EnsureDictionary ().IsFixedSize; + bool IDictionary.IsFixedSize + { + get + { + return EnsureDictionary().IsFixedSize; } } - bool IDictionary.IsReadOnly { - get { - return EnsureDictionary ().IsReadOnly; + bool IDictionary.IsReadOnly + { + get + { + return EnsureDictionary().IsReadOnly; } } - ICollection IDictionary.Keys { - get { - EnsureDictionary (); - IList keys = new List (); - - foreach (KeyValuePair entry in - object_list) { - keys.Add (entry.Key); + ICollection IDictionary.Keys + { + get + { + EnsureDictionary(); + IList keys = new List(); + + foreach (KeyValuePair entry in object_list) + { + keys.Add(entry.Key); } - return (ICollection) keys; + return (ICollection)keys; } } - ICollection IDictionary.Values { - get { - EnsureDictionary (); - IList values = new List (); - - foreach (KeyValuePair entry in - object_list) { - values.Add (entry.Value); + ICollection IDictionary.Values + { + get + { + EnsureDictionary(); + IList values = new List(); + + foreach (KeyValuePair entry in object_list) + { + values.Add(entry.Value); } - return (ICollection) values; + return (ICollection)values; } } #endregion @@ -142,87 +164,103 @@ ICollection IDictionary.Values { #region IJsonWrapper Properties - bool IJsonWrapper.IsArray { + bool IJsonWrapper.IsArray + { get { return IsArray; } } - bool IJsonWrapper.IsBoolean { + bool IJsonWrapper.IsBoolean + { get { return IsBoolean; } } - bool IJsonWrapper.IsDouble { + bool IJsonWrapper.IsDouble + { get { return IsDouble; } } - bool IJsonWrapper.IsInt { + bool IJsonWrapper.IsInt + { get { return IsInt; } } - bool IJsonWrapper.IsLong { + bool IJsonWrapper.IsLong + { get { return IsLong; } } - bool IJsonWrapper.IsObject { + bool IJsonWrapper.IsObject + { get { return IsObject; } } - bool IJsonWrapper.IsString { + bool IJsonWrapper.IsString + { get { return IsString; } } #endregion #region IList Properties - bool IList.IsFixedSize { - get { - return EnsureList ().IsFixedSize; + bool IList.IsFixedSize + { + get + { + return EnsureList().IsFixedSize; } } - bool IList.IsReadOnly { - get { - return EnsureList ().IsReadOnly; + bool IList.IsReadOnly + { + get + { + return EnsureList().IsReadOnly; } } #endregion #region IDictionary Indexer - object IDictionary.this[object key] { - get { - return EnsureDictionary ()[key]; + object IDictionary.this[object key] + { + get + { + return EnsureDictionary()[key]; } - set { - if (! (key is String)) - throw new ArgumentException ( + set + { + if (!(key is String)) + throw new ArgumentException( "The key has to be a string"); - JsonData data = ToJsonData (value); + JsonData data = ToJsonData(value); - this[(string) key] = data; + this[(string)key] = data; } } #endregion #region IOrderedDictionary Indexer - object IOrderedDictionary.this[int idx] { - get { - EnsureDictionary (); + object IOrderedDictionary.this[int idx] + { + get + { + EnsureDictionary(); return object_list[idx].Value; } - set { - EnsureDictionary (); - JsonData data = ToJsonData (value); + set + { + EnsureDictionary(); + JsonData data = ToJsonData(value); KeyValuePair old_entry = object_list[idx]; inst_object[old_entry.Key] = data; - KeyValuePair entry = - new KeyValuePair (old_entry.Key, data); + KeyValuePair entry = new KeyValuePair(old_entry.Key, data); object_list[idx] = entry; } @@ -231,14 +269,17 @@ object IOrderedDictionary.this[int idx] { #region IList Indexer - object IList.this[int index] { - get { - return EnsureList ()[index]; + object IList.this[int index] + { + get + { + return EnsureList()[index]; } - set { - EnsureList (); - JsonData data = ToJsonData (value); + set + { + EnsureList(); + JsonData data = ToJsonData(value); this[index] = data; } @@ -247,27 +288,33 @@ object IList.this[int index] { #region Public Indexers - public JsonData this[string prop_name] { - get { - EnsureDictionary (); + public JsonData this[string prop_name] + { + get + { + EnsureDictionary(); return inst_object[prop_name]; } - set { - EnsureDictionary (); + set + { + EnsureDictionary(); - KeyValuePair entry = - new KeyValuePair (prop_name, value); + KeyValuePair entry = new KeyValuePair(prop_name, value); - if (inst_object.ContainsKey (prop_name)) { - for (int i = 0; i < object_list.Count; i++) { - if (object_list[i].Key == prop_name) { + if (inst_object.ContainsKey(prop_name)) + { + for (int i = 0; i < object_list.Count; i++) + { + if (object_list[i].Key == prop_name) + { object_list[i] = entry; break; } } - } else - object_list.Add (entry); + } + else + object_list.Add(entry); inst_object[prop_name] = value; @@ -275,9 +322,11 @@ public JsonData this[string prop_name] { } } - public JsonData this[int index] { - get { - EnsureCollection (); + public JsonData this[int index] + { + get + { + EnsureCollection(); if (type == JsonType.Array) return inst_array[index]; @@ -285,15 +334,16 @@ public JsonData this[int index] { return object_list[index].Value; } - set { - EnsureCollection (); + set + { + EnsureCollection(); if (type == JsonType.Array) inst_array[index] = value; - else { + else + { KeyValuePair entry = object_list[index]; - KeyValuePair new_entry = - new KeyValuePair (entry.Key, value); + KeyValuePair new_entry = new KeyValuePair(entry.Key, value); object_list[index] = new_entry; inst_object[entry.Key] = value; @@ -306,71 +356,76 @@ public JsonData this[int index] { #region Constructors - public JsonData () + public JsonData() { } - public JsonData (bool boolean) + public JsonData(bool boolean) { type = JsonType.Boolean; inst_boolean = boolean; } - public JsonData (double number) + public JsonData(double number) { type = JsonType.Double; inst_double = number; } - public JsonData (int number) + public JsonData(int number) { type = JsonType.Int; inst_int = number; } - public JsonData (long number) + public JsonData(long number) { type = JsonType.Long; inst_long = number; } - public JsonData (object obj) + public JsonData(object obj) { - if (obj is Boolean) { + if (obj is Boolean) + { type = JsonType.Boolean; - inst_boolean = (bool) obj; + inst_boolean = (bool)obj; return; } - if (obj is Double) { + if (obj is Double) + { type = JsonType.Double; - inst_double = (double) obj; + inst_double = (double)obj; return; } - if (obj is Int32) { + if (obj is Int32) + { type = JsonType.Int; - inst_int = (int) obj; + inst_int = (int)obj; return; } - if (obj is Int64) { + if (obj is Int64) + { type = JsonType.Long; - inst_long = (long) obj; + inst_long = (long)obj; return; } - if (obj is String) { + if (obj is String) + { type = JsonType.String; - inst_string = (string) obj; + inst_string = (string)obj; return; } - throw new ArgumentException ( + throw new ArgumentException( "Unable to wrap the given object with JsonData"); } - public JsonData (string str) + public JsonData(string str) { type = JsonType.String; inst_string = str; @@ -379,74 +434,74 @@ public JsonData (string str) #region Implicit Conversions - public static implicit operator JsonData (Boolean data) + public static implicit operator JsonData(Boolean data) { - return new JsonData (data); + return new JsonData(data); } - public static implicit operator JsonData (Double data) + public static implicit operator JsonData(Double data) { - return new JsonData (data); + return new JsonData(data); } - public static implicit operator JsonData (Int32 data) + public static implicit operator JsonData(Int32 data) { - return new JsonData (data); + return new JsonData(data); } - public static implicit operator JsonData (Int64 data) + public static implicit operator JsonData(Int64 data) { - return new JsonData (data); + return new JsonData(data); } - public static implicit operator JsonData (String data) + public static implicit operator JsonData(String data) { - return new JsonData (data); + return new JsonData(data); } #endregion #region Explicit Conversions - public static explicit operator Boolean (JsonData data) + public static explicit operator Boolean(JsonData data) { if (data.type != JsonType.Boolean) - throw new InvalidCastException ( + throw new InvalidCastException( "Instance of JsonData doesn't hold a double"); return data.inst_boolean; } - public static explicit operator Double (JsonData data) + public static explicit operator Double(JsonData data) { if (data.type != JsonType.Double) - throw new InvalidCastException ( + throw new InvalidCastException( "Instance of JsonData doesn't hold a double"); return data.inst_double; } - public static explicit operator Int32 (JsonData data) + public static explicit operator Int32(JsonData data) { if (data.type != JsonType.Int) - throw new InvalidCastException ( + throw new InvalidCastException( "Instance of JsonData doesn't hold an int"); return data.inst_int; } - public static explicit operator Int64 (JsonData data) + public static explicit operator Int64(JsonData data) { if (data.type != JsonType.Long) - throw new InvalidCastException ( + throw new InvalidCastException( "Instance of JsonData doesn't hold an int"); return data.inst_long; } - public static explicit operator String (JsonData data) + public static explicit operator String(JsonData data) { if (data.type != JsonType.String) - throw new InvalidCastException ( + throw new InvalidCastException( "Instance of JsonData doesn't hold a string"); return data.inst_string; @@ -455,51 +510,52 @@ public static explicit operator String (JsonData data) #region ICollection Methods - void ICollection.CopyTo (Array array, int index) + void ICollection.CopyTo(Array array, int index) { - EnsureCollection ().CopyTo (array, index); + EnsureCollection().CopyTo(array, index); } #endregion #region IDictionary Methods - void IDictionary.Add (object key, object value) + void IDictionary.Add(object key, object value) { - JsonData data = ToJsonData (value); + JsonData data = ToJsonData(value); - EnsureDictionary ().Add (key, data); + EnsureDictionary().Add(key, data); - KeyValuePair entry = - new KeyValuePair ((string) key, data); - object_list.Add (entry); + KeyValuePair entry = new KeyValuePair((string)key, data); + object_list.Add(entry); json = null; } - void IDictionary.Clear () + void IDictionary.Clear() { - EnsureDictionary ().Clear (); - object_list.Clear (); + EnsureDictionary().Clear(); + object_list.Clear(); json = null; } - bool IDictionary.Contains (object key) + bool IDictionary.Contains(object key) { - return EnsureDictionary ().Contains (key); + return EnsureDictionary().Contains(key); } - IDictionaryEnumerator IDictionary.GetEnumerator () + IDictionaryEnumerator IDictionary.GetEnumerator() { - return ((IOrderedDictionary) this).GetEnumerator (); + return ((IOrderedDictionary)this).GetEnumerator(); } - void IDictionary.Remove (object key) + void IDictionary.Remove(object key) { - EnsureDictionary ().Remove (key); + EnsureDictionary().Remove(key); - for (int i = 0; i < object_list.Count; i++) { - if (object_list[i].Key == (string) key) { - object_list.RemoveAt (i); + for (int i = 0; i < object_list.Count; i++) + { + if (object_list[i].Key == (string)key) + { + object_list.RemoveAt(i); break; } } @@ -510,284 +566,293 @@ void IDictionary.Remove (object key) #region IEnumerable Methods - IEnumerator IEnumerable.GetEnumerator () + IEnumerator IEnumerable.GetEnumerator() { - return EnsureCollection ().GetEnumerator (); + return EnsureCollection().GetEnumerator(); } #endregion #region IJsonWrapper Methods - bool IJsonWrapper.GetBoolean () + bool IJsonWrapper.GetBoolean() { if (type != JsonType.Boolean) - throw new InvalidOperationException ( + throw new InvalidOperationException( "JsonData instance doesn't hold a boolean"); return inst_boolean; } - double IJsonWrapper.GetDouble () + double IJsonWrapper.GetDouble() { if (type != JsonType.Double) - throw new InvalidOperationException ( + throw new InvalidOperationException( "JsonData instance doesn't hold a double"); return inst_double; } - int IJsonWrapper.GetInt () + int IJsonWrapper.GetInt() { if (type != JsonType.Int) - throw new InvalidOperationException ( + throw new InvalidOperationException( "JsonData instance doesn't hold an int"); return inst_int; } - long IJsonWrapper.GetLong () + long IJsonWrapper.GetLong() { if (type != JsonType.Long) - throw new InvalidOperationException ( + throw new InvalidOperationException( "JsonData instance doesn't hold a long"); return inst_long; } - string IJsonWrapper.GetString () + string IJsonWrapper.GetString() { if (type != JsonType.String) - throw new InvalidOperationException ( + throw new InvalidOperationException( "JsonData instance doesn't hold a string"); return inst_string; } - void IJsonWrapper.SetBoolean (bool val) + void IJsonWrapper.SetBoolean(bool val) { type = JsonType.Boolean; inst_boolean = val; json = null; } - void IJsonWrapper.SetDouble (double val) + void IJsonWrapper.SetDouble(double val) { type = JsonType.Double; inst_double = val; json = null; } - void IJsonWrapper.SetInt (int val) + void IJsonWrapper.SetInt(int val) { type = JsonType.Int; inst_int = val; json = null; } - void IJsonWrapper.SetLong (long val) + void IJsonWrapper.SetLong(long val) { type = JsonType.Long; inst_long = val; json = null; } - void IJsonWrapper.SetString (string val) + void IJsonWrapper.SetString(string val) { type = JsonType.String; inst_string = val; json = null; } - string IJsonWrapper.ToJson () + string IJsonWrapper.ToJson() { - return ToJson (); + return ToJson(); } - void IJsonWrapper.ToJson (JsonWriter writer) + void IJsonWrapper.ToJson(JsonWriter writer) { - ToJson (writer); + ToJson(writer); } #endregion #region IList Methods - int IList.Add (object value) + int IList.Add(object value) { - return Add (value); + return Add(value); } - void IList.Clear () + void IList.Clear() { - EnsureList ().Clear (); + EnsureList().Clear(); json = null; } - bool IList.Contains (object value) + bool IList.Contains(object value) { - return EnsureList ().Contains (value); + return EnsureList().Contains(value); } - int IList.IndexOf (object value) + int IList.IndexOf(object value) { - return EnsureList ().IndexOf (value); + return EnsureList().IndexOf(value); } - void IList.Insert (int index, object value) + void IList.Insert(int index, object value) { - EnsureList ().Insert (index, value); + EnsureList().Insert(index, value); json = null; } - void IList.Remove (object value) + void IList.Remove(object value) { - EnsureList ().Remove (value); + EnsureList().Remove(value); json = null; } - void IList.RemoveAt (int index) + void IList.RemoveAt(int index) { - EnsureList ().RemoveAt (index); + EnsureList().RemoveAt(index); json = null; } #endregion #region IOrderedDictionary Methods - IDictionaryEnumerator IOrderedDictionary.GetEnumerator () + IDictionaryEnumerator IOrderedDictionary.GetEnumerator() { - EnsureDictionary (); + EnsureDictionary(); - return new OrderedDictionaryEnumerator ( - object_list.GetEnumerator ()); + return new OrderedDictionaryEnumerator( + object_list.GetEnumerator()); } - void IOrderedDictionary.Insert (int idx, object key, object value) + void IOrderedDictionary.Insert(int idx, object key, object value) { - string property = (string) key; - JsonData data = ToJsonData (value); + string property = (string)key; + JsonData data = ToJsonData(value); this[property] = data; KeyValuePair entry = - new KeyValuePair (property, data); + new KeyValuePair(property, data); - object_list.Insert (idx, entry); + object_list.Insert(idx, entry); } - void IOrderedDictionary.RemoveAt (int idx) + void IOrderedDictionary.RemoveAt(int idx) { - EnsureDictionary (); + EnsureDictionary(); - inst_object.Remove (object_list[idx].Key); - object_list.RemoveAt (idx); + inst_object.Remove(object_list[idx].Key); + object_list.RemoveAt(idx); } #endregion #region Private Methods - private ICollection EnsureCollection () + private ICollection EnsureCollection() { if (type == JsonType.Array) - return (ICollection) inst_array; + return (ICollection)inst_array; if (type == JsonType.Object) - return (ICollection) inst_object; + return (ICollection)inst_object; - throw new InvalidOperationException ( + throw new InvalidOperationException( "The JsonData instance has to be initialized first"); } - private IDictionary EnsureDictionary () + private IDictionary EnsureDictionary() { if (type == JsonType.Object) - return (IDictionary) inst_object; + return (IDictionary)inst_object; if (type != JsonType.None) - throw new InvalidOperationException ( + throw new InvalidOperationException( "Instance of JsonData is not a dictionary"); type = JsonType.Object; - inst_object = new Dictionary (); - object_list = new List> (); + inst_object = new Dictionary(); + object_list = new List>(); - return (IDictionary) inst_object; + return (IDictionary)inst_object; } - private IList EnsureList () + private IList EnsureList() { if (type == JsonType.Array) - return (IList) inst_array; + return (IList)inst_array; if (type != JsonType.None) - throw new InvalidOperationException ( + throw new InvalidOperationException( "Instance of JsonData is not a list"); type = JsonType.Array; - inst_array = new List (); + inst_array = new List(); - return (IList) inst_array; + return (IList)inst_array; } - private JsonData ToJsonData (object obj) + private JsonData ToJsonData(object obj) { if (obj == null) return null; if (obj is JsonData) - return (JsonData) obj; + return (JsonData)obj; - return new JsonData (obj); + return new JsonData(obj); } - private static void WriteJson (IJsonWrapper obj, JsonWriter writer) + private static void WriteJson(IJsonWrapper obj, JsonWriter writer) { - if (obj == null) { - writer.Write (null); + if (obj == null) + { + writer.Write(null); return; } - if (obj.IsString) { - writer.Write (obj.GetString ()); + if (obj.IsString) + { + writer.Write(obj.GetString()); return; } - if (obj.IsBoolean) { - writer.Write (obj.GetBoolean ()); + if (obj.IsBoolean) + { + writer.Write(obj.GetBoolean()); return; } - if (obj.IsDouble) { - writer.Write (obj.GetDouble ()); + if (obj.IsDouble) + { + writer.Write(obj.GetDouble()); return; } - if (obj.IsInt) { - writer.Write (obj.GetInt ()); + if (obj.IsInt) + { + writer.Write(obj.GetInt()); return; } - if (obj.IsLong) { - writer.Write (obj.GetLong ()); + if (obj.IsLong) + { + writer.Write(obj.GetLong()); return; } - if (obj.IsArray) { - writer.WriteArrayStart (); - foreach (object elem in (IList) obj) - WriteJson ((JsonData) elem, writer); - writer.WriteArrayEnd (); + if (obj.IsArray) + { + writer.WriteArrayStart(); + foreach (object elem in (IList)obj) + WriteJson((JsonData)elem, writer); + writer.WriteArrayEnd(); return; } - if (obj.IsObject) { - writer.WriteObjectStart (); + if (obj.IsObject) + { + writer.WriteObjectStart(); - foreach (DictionaryEntry entry in ((IDictionary) obj)) { - writer.WritePropertyName ((string) entry.Key); - WriteJson ((JsonData) entry.Value, writer); + foreach (DictionaryEntry entry in ((IDictionary)obj)) + { + writer.WritePropertyName((string)entry.Key); + WriteJson((JsonData)entry.Value, writer); } - writer.WriteObjectEnd (); + writer.WriteObjectEnd(); return; } @@ -795,29 +860,31 @@ private static void WriteJson (IJsonWrapper obj, JsonWriter writer) #endregion - public int Add (object value) + public int Add(object value) { - JsonData data = ToJsonData (value); + JsonData data = ToJsonData(value); json = null; - return EnsureList ().Add (data); + return EnsureList().Add(data); } - public void Clear () + public void Clear() { - if (IsObject) { - ((IDictionary) this).Clear (); + if (IsObject) + { + ((IDictionary)this).Clear(); return; } - if (IsArray) { - ((IList) this).Clear (); + if (IsArray) + { + ((IList)this).Clear(); return; } } - public bool Equals (JsonData x) + public bool Equals(JsonData x) { if (x == null) return false; @@ -825,131 +892,134 @@ public bool Equals (JsonData x) if (x.type != this.type) return false; - switch (this.type) { - case JsonType.None: - return true; + switch (this.type) + { + case JsonType.None: + return true; - case JsonType.Object: - return this.inst_object.Equals (x.inst_object); + case JsonType.Object: + return this.inst_object.Equals(x.inst_object); - case JsonType.Array: - return this.inst_array.Equals (x.inst_array); + case JsonType.Array: + return this.inst_array.Equals(x.inst_array); - case JsonType.String: - return this.inst_string.Equals (x.inst_string); + case JsonType.String: + return this.inst_string.Equals(x.inst_string); - case JsonType.Int: - return this.inst_int.Equals (x.inst_int); + case JsonType.Int: + return this.inst_int.Equals(x.inst_int); - case JsonType.Long: - return this.inst_long.Equals (x.inst_long); + case JsonType.Long: + return this.inst_long.Equals(x.inst_long); - case JsonType.Double: - return this.inst_double.Equals (x.inst_double); + case JsonType.Double: + return this.inst_double.Equals(x.inst_double); - case JsonType.Boolean: - return this.inst_boolean.Equals (x.inst_boolean); + case JsonType.Boolean: + return this.inst_boolean.Equals(x.inst_boolean); } return false; } - public JsonType GetJsonType () + public JsonType GetJsonType() { return type; } - public void SetJsonType (JsonType type) + public void SetJsonType(JsonType type) { if (this.type == type) return; - switch (type) { - case JsonType.None: - break; + switch (type) + { + case JsonType.None: + break; - case JsonType.Object: - inst_object = new Dictionary (); - object_list = new List> (); - break; + case JsonType.Object: + inst_object = new Dictionary(); + object_list = new List>(); + break; - case JsonType.Array: - inst_array = new List (); - break; + case JsonType.Array: + inst_array = new List(); + break; - case JsonType.String: - inst_string = default (String); - break; + case JsonType.String: + inst_string = default(String); + break; - case JsonType.Int: - inst_int = default (Int32); - break; + case JsonType.Int: + inst_int = default(Int32); + break; - case JsonType.Long: - inst_long = default (Int64); - break; + case JsonType.Long: + inst_long = default(Int64); + break; - case JsonType.Double: - inst_double = default (Double); - break; + case JsonType.Double: + inst_double = default(Double); + break; - case JsonType.Boolean: - inst_boolean = default (Boolean); - break; + case JsonType.Boolean: + inst_boolean = default(Boolean); + break; } this.type = type; } - public string ToJson () + public string ToJson() { if (json != null) return json; - StringWriter sw = new StringWriter (); - JsonWriter writer = new JsonWriter (sw); + StringWriter sw = new StringWriter(); + JsonWriter writer = new JsonWriter(sw); writer.Validate = false; - WriteJson (this, writer); - json = sw.ToString (); + WriteJson(this, writer); + json = sw.ToString(); return json; } - public void ToJson (JsonWriter writer) + public void ToJson(JsonWriter writer) { bool old_validate = writer.Validate; writer.Validate = false; - WriteJson (this, writer); + WriteJson(this, writer); writer.Validate = old_validate; } - public override string ToString () + public override string ToString() { - switch (type) { - case JsonType.Array: - return "JsonData array"; + switch (type) + { + case JsonType.Array: + return "JsonData array"; - case JsonType.Boolean: - return inst_boolean.ToString (); + case JsonType.Boolean: + return inst_boolean.ToString(); - case JsonType.Double: - return inst_double.ToString (); + case JsonType.Double: + return inst_double.ToString(); - case JsonType.Int: - return inst_int.ToString (); + case JsonType.Int: + return inst_int.ToString(); - case JsonType.Long: - return inst_long.ToString (); + case JsonType.Long: + return inst_long.ToString(); - case JsonType.Object: - return "JsonData object"; + case JsonType.Object: + return "JsonData object"; - case JsonType.String: - return inst_string; + case JsonType.String: + return inst_string; } return "Uninitialized JsonData"; @@ -962,41 +1032,46 @@ internal class OrderedDictionaryEnumerator : IDictionaryEnumerator IEnumerator> list_enumerator; - public object Current { + public object Current + { get { return Entry; } } - public DictionaryEntry Entry { - get { + public DictionaryEntry Entry + { + get + { KeyValuePair curr = list_enumerator.Current; - return new DictionaryEntry (curr.Key, curr.Value); + return new DictionaryEntry(curr.Key, curr.Value); } } - public object Key { + public object Key + { get { return list_enumerator.Current.Key; } } - public object Value { + public object Value + { get { return list_enumerator.Current.Value; } } - public OrderedDictionaryEnumerator ( + public OrderedDictionaryEnumerator( IEnumerator> enumerator) { list_enumerator = enumerator; } - public bool MoveNext () + public bool MoveNext() { - return list_enumerator.MoveNext (); + return list_enumerator.MoveNext(); } - public void Reset () + public void Reset() { - list_enumerator.Reset (); + list_enumerator.Reset(); } } } diff --git a/OpenMetaverse.StructuredData/JSON/JsonException.cs b/OpenMetaverse.StructuredData/JSON/JsonException.cs index a356fd66..cc44377e 100644 --- a/OpenMetaverse.StructuredData/JSON/JsonException.cs +++ b/OpenMetaverse.StructuredData/JSON/JsonException.cs @@ -16,44 +16,37 @@ namespace LitJson { public class JsonException : ApplicationException { - public JsonException () : base () + public JsonException() : base() { } - internal JsonException (ParserToken token) : - base (String.Format ( - "Invalid token '{0}' in input string", token)) + internal JsonException(ParserToken token) : + base(String.Format("Invalid token '{0}' in input string", token)) { } - internal JsonException (ParserToken token, - Exception inner_exception) : - base (String.Format ( - "Invalid token '{0}' in input string", token), - inner_exception) + internal JsonException(ParserToken token, Exception inner_exception) : + base(String.Format("Invalid token '{0}' in input string", token), inner_exception) { } - internal JsonException (int c) : - base (String.Format ( - "Invalid character '{0}' in input string", (char) c)) + internal JsonException(int c) : + base(String.Format("Invalid character '{0}' in input string", (char)c)) { } - internal JsonException (int c, Exception inner_exception) : - base (String.Format ( - "Invalid character '{0}' in input string", (char) c), - inner_exception) + internal JsonException(int c, Exception inner_exception) : + base(String.Format("Invalid character '{0}' in input string", (char)c), inner_exception) { } - public JsonException (string message) : base (message) + public JsonException(string message) : base(message) { } - public JsonException (string message, Exception inner_exception) : - base (message, inner_exception) + public JsonException(string message, Exception inner_exception) : + base(message, inner_exception) { } } diff --git a/OpenMetaverse.StructuredData/JSON/JsonMockWrapper.cs b/OpenMetaverse.StructuredData/JSON/JsonMockWrapper.cs index c39c8d75..fd948ccb 100644 --- a/OpenMetaverse.StructuredData/JSON/JsonMockWrapper.cs +++ b/OpenMetaverse.StructuredData/JSON/JsonMockWrapper.cs @@ -19,87 +19,91 @@ namespace LitJson { public class JsonMockWrapper : IJsonWrapper { - public bool IsArray { get { return false; } } + public bool IsArray { get { return false; } } public bool IsBoolean { get { return false; } } - public bool IsDouble { get { return false; } } - public bool IsInt { get { return false; } } - public bool IsLong { get { return false; } } - public bool IsObject { get { return false; } } - public bool IsString { get { return false; } } - - public bool GetBoolean () { return false; } - public double GetDouble () { return 0.0; } - public int GetInt () { return 0; } - public JsonType GetJsonType () { return JsonType.None; } - public long GetLong () { return 0L; } - public string GetString () { return ""; } - - public void SetBoolean (bool val) {} - public void SetDouble (double val) {} - public void SetInt (int val) {} - public void SetJsonType (JsonType type) {} - public void SetLong (long val) {} - public void SetString (string val) {} - - public string ToJson () { return ""; } - public void ToJson (JsonWriter writer) {} + public bool IsDouble { get { return false; } } + public bool IsInt { get { return false; } } + public bool IsLong { get { return false; } } + public bool IsObject { get { return false; } } + public bool IsString { get { return false; } } + + public bool GetBoolean() { return false; } + public double GetDouble() { return 0.0; } + public int GetInt() { return 0; } + public JsonType GetJsonType() { return JsonType.None; } + public long GetLong() { return 0L; } + public string GetString() { return ""; } + + public void SetBoolean(bool val) { } + public void SetDouble(double val) { } + public void SetInt(int val) { } + public void SetJsonType(JsonType type) { } + public void SetLong(long val) { } + public void SetString(string val) { } + + public string ToJson() { return ""; } + public void ToJson(JsonWriter writer) { } bool IList.IsFixedSize { get { return true; } } - bool IList.IsReadOnly { get { return true; } } + bool IList.IsReadOnly { get { return true; } } - object IList.this[int index] { + object IList.this[int index] + { get { return null; } - set {} + set { } } - int IList.Add (object value) { return 0; } - void IList.Clear () {} - bool IList.Contains (object value) { return false; } - int IList.IndexOf (object value) { return -1; } - void IList.Insert (int i, object v) {} - void IList.Remove (object value) {} - void IList.RemoveAt (int index) {} + int IList.Add(object value) { return 0; } + void IList.Clear() { } + bool IList.Contains(object value) { return false; } + int IList.IndexOf(object value) { return -1; } + void IList.Insert(int i, object v) { } + void IList.Remove(object value) { } + void IList.RemoveAt(int index) { } - int ICollection.Count { get { return 0; } } - bool ICollection.IsSynchronized { get { return false; } } - object ICollection.SyncRoot { get { return null; } } + int ICollection.Count { get { return 0; } } + bool ICollection.IsSynchronized { get { return false; } } + object ICollection.SyncRoot { get { return null; } } - void ICollection.CopyTo (Array array, int index) {} + void ICollection.CopyTo(Array array, int index) { } - IEnumerator IEnumerable.GetEnumerator () { return null; } + IEnumerator IEnumerable.GetEnumerator() { return null; } bool IDictionary.IsFixedSize { get { return true; } } - bool IDictionary.IsReadOnly { get { return true; } } + bool IDictionary.IsReadOnly { get { return true; } } - ICollection IDictionary.Keys { get { return null; } } + ICollection IDictionary.Keys { get { return null; } } ICollection IDictionary.Values { get { return null; } } - object IDictionary.this[object key] { + object IDictionary.this[object key] + { get { return null; } - set {} + set { } } - void IDictionary.Add (object k, object v) {} - void IDictionary.Clear () {} - bool IDictionary.Contains (object key) { return false; } - void IDictionary.Remove (object key) {} + void IDictionary.Add(object k, object v) { } + void IDictionary.Clear() { } + bool IDictionary.Contains(object key) { return false; } + void IDictionary.Remove(object key) { } - IDictionaryEnumerator IDictionary.GetEnumerator () { return null; } + IDictionaryEnumerator IDictionary.GetEnumerator() { return null; } - object IOrderedDictionary.this[int idx] { + object IOrderedDictionary.this[int idx] + { get { return null; } - set {} + set { } } - IDictionaryEnumerator IOrderedDictionary.GetEnumerator () { + IDictionaryEnumerator IOrderedDictionary.GetEnumerator() + { return null; } - void IOrderedDictionary.Insert (int i, object k, object v) {} - void IOrderedDictionary.RemoveAt (int i) {} + void IOrderedDictionary.Insert(int i, object k, object v) { } + void IOrderedDictionary.RemoveAt(int i) { } } } diff --git a/OpenMetaverse.StructuredData/JSON/JsonReader.cs b/OpenMetaverse.StructuredData/JSON/JsonReader.cs index 43ec8f7d..1e8d2dae 100644 --- a/OpenMetaverse.StructuredData/JSON/JsonReader.cs +++ b/OpenMetaverse.StructuredData/JSON/JsonReader.cs @@ -44,90 +44,97 @@ public class JsonReader #region Fields private static IDictionary> parse_table; - private Stack automaton_stack; - private int current_input; - private int current_symbol; - private bool end_of_json; - private bool end_of_input; - private Lexer lexer; - private bool parser_in_string; - private bool parser_return; - private bool read_started; - private TextReader reader; - private bool reader_is_owned; - private bool skip_non_members; - private object token_value; - private JsonToken token; + private Stack automaton_stack; + private int current_input; + private int current_symbol; + private bool end_of_json; + private bool end_of_input; + private Lexer lexer; + private bool parser_in_string; + private bool parser_return; + private bool read_started; + private TextReader reader; + private bool reader_is_owned; + private bool skip_non_members; + private object token_value; + private JsonToken token; #endregion #region Public Properties - public bool AllowComments { + public bool AllowComments + { get { return lexer.AllowComments; } set { lexer.AllowComments = value; } } - public bool AllowSingleQuotedStrings { + public bool AllowSingleQuotedStrings + { get { return lexer.AllowSingleQuotedStrings; } set { lexer.AllowSingleQuotedStrings = value; } } - public bool SkipNonMembers { + public bool SkipNonMembers + { get { return skip_non_members; } set { skip_non_members = value; } } - public bool EndOfInput { + public bool EndOfInput + { get { return end_of_input; } } - public bool EndOfJson { + public bool EndOfJson + { get { return end_of_json; } } - public JsonToken Token { + public JsonToken Token + { get { return token; } } - public object Value { + public object Value + { get { return token_value; } } #endregion #region Constructors - static JsonReader () + static JsonReader() { - PopulateParseTable (); + PopulateParseTable(); } - public JsonReader (string json_text) : - this (new StringReader (json_text), true) + public JsonReader(string json_text) : + this(new StringReader(json_text), true) { } - public JsonReader (TextReader reader) : - this (reader, false) + public JsonReader(TextReader reader) : + this(reader, false) { } - private JsonReader (TextReader reader, bool owned) + private JsonReader(TextReader reader, bool owned) { if (reader == null) - throw new ArgumentNullException ("reader"); + throw new ArgumentNullException("reader"); parser_in_string = false; - parser_return = false; + parser_return = false; read_started = false; - automaton_stack = new Stack (); - automaton_stack.Push ((int) ParserToken.End); - automaton_stack.Push ((int) ParserToken.Text); + automaton_stack = new Stack(); + automaton_stack.Push((int)ParserToken.End); + automaton_stack.Push((int)ParserToken.Text); - lexer = new Lexer (reader); + lexer = new Lexer(reader); end_of_input = false; - end_of_json = false; + end_of_json = false; skip_non_members = true; @@ -138,135 +145,137 @@ private JsonReader (TextReader reader, bool owned) #region Static Methods - private static void PopulateParseTable () + private static void PopulateParseTable() { // See section A.2. of the manual for details - parse_table = new Dictionary> (); + parse_table = new Dictionary>(); - TableAddRow (ParserToken.Array); - TableAddCol (ParserToken.Array, '[', + TableAddRow(ParserToken.Array); + TableAddCol(ParserToken.Array, '[', '[', - (int) ParserToken.ArrayPrime); + (int)ParserToken.ArrayPrime); - TableAddRow (ParserToken.ArrayPrime); - TableAddCol (ParserToken.ArrayPrime, '"', - (int) ParserToken.Value, + TableAddRow(ParserToken.ArrayPrime); + TableAddCol(ParserToken.ArrayPrime, '"', + (int)ParserToken.Value, - (int) ParserToken.ValueRest, + (int)ParserToken.ValueRest, ']'); - TableAddCol (ParserToken.ArrayPrime, '[', - (int) ParserToken.Value, - (int) ParserToken.ValueRest, + TableAddCol(ParserToken.ArrayPrime, '[', + (int)ParserToken.Value, + (int)ParserToken.ValueRest, ']'); - TableAddCol (ParserToken.ArrayPrime, ']', + TableAddCol(ParserToken.ArrayPrime, ']', ']'); - TableAddCol (ParserToken.ArrayPrime, '{', - (int) ParserToken.Value, - (int) ParserToken.ValueRest, + TableAddCol(ParserToken.ArrayPrime, '{', + (int)ParserToken.Value, + (int)ParserToken.ValueRest, ']'); - TableAddCol (ParserToken.ArrayPrime, (int) ParserToken.Number, - (int) ParserToken.Value, - (int) ParserToken.ValueRest, + TableAddCol(ParserToken.ArrayPrime, (int)ParserToken.Number, + (int)ParserToken.Value, + (int)ParserToken.ValueRest, ']'); - TableAddCol (ParserToken.ArrayPrime, (int) ParserToken.True, - (int) ParserToken.Value, - (int) ParserToken.ValueRest, + TableAddCol(ParserToken.ArrayPrime, (int)ParserToken.True, + (int)ParserToken.Value, + (int)ParserToken.ValueRest, ']'); - TableAddCol (ParserToken.ArrayPrime, (int) ParserToken.False, - (int) ParserToken.Value, - (int) ParserToken.ValueRest, + TableAddCol(ParserToken.ArrayPrime, (int)ParserToken.False, + (int)ParserToken.Value, + (int)ParserToken.ValueRest, ']'); - TableAddCol (ParserToken.ArrayPrime, (int) ParserToken.Null, - (int) ParserToken.Value, - (int) ParserToken.ValueRest, + TableAddCol(ParserToken.ArrayPrime, (int)ParserToken.Null, + (int)ParserToken.Value, + (int)ParserToken.ValueRest, ']'); - TableAddRow (ParserToken.Object); - TableAddCol (ParserToken.Object, '{', + TableAddRow(ParserToken.Object); + TableAddCol(ParserToken.Object, '{', '{', - (int) ParserToken.ObjectPrime); + (int)ParserToken.ObjectPrime); - TableAddRow (ParserToken.ObjectPrime); - TableAddCol (ParserToken.ObjectPrime, '"', - (int) ParserToken.Pair, - (int) ParserToken.PairRest, + TableAddRow(ParserToken.ObjectPrime); + TableAddCol(ParserToken.ObjectPrime, '"', + (int)ParserToken.Pair, + (int)ParserToken.PairRest, '}'); - TableAddCol (ParserToken.ObjectPrime, '}', + TableAddCol(ParserToken.ObjectPrime, '}', '}'); - TableAddRow (ParserToken.Pair); - TableAddCol (ParserToken.Pair, '"', - (int) ParserToken.String, + TableAddRow(ParserToken.Pair); + TableAddCol(ParserToken.Pair, '"', + (int)ParserToken.String, ':', - (int) ParserToken.Value); + (int)ParserToken.Value); - TableAddRow (ParserToken.PairRest); - TableAddCol (ParserToken.PairRest, ',', + TableAddRow(ParserToken.PairRest); + TableAddCol(ParserToken.PairRest, ',', ',', - (int) ParserToken.Pair, - (int) ParserToken.PairRest); - TableAddCol (ParserToken.PairRest, '}', - (int) ParserToken.Epsilon); + (int)ParserToken.Pair, + (int)ParserToken.PairRest); + TableAddCol(ParserToken.PairRest, '}', + (int)ParserToken.Epsilon); - TableAddRow (ParserToken.String); - TableAddCol (ParserToken.String, '"', + TableAddRow(ParserToken.String); + TableAddCol(ParserToken.String, '"', '"', - (int) ParserToken.CharSeq, + (int)ParserToken.CharSeq, '"'); - TableAddRow (ParserToken.Text); - TableAddCol (ParserToken.Text, '[', - (int) ParserToken.Array); - TableAddCol (ParserToken.Text, '{', - (int) ParserToken.Object); - - TableAddRow (ParserToken.Value); - TableAddCol (ParserToken.Value, '"', - (int) ParserToken.String); - TableAddCol (ParserToken.Value, '[', - (int) ParserToken.Array); - TableAddCol (ParserToken.Value, '{', - (int) ParserToken.Object); - TableAddCol (ParserToken.Value, (int) ParserToken.Number, - (int) ParserToken.Number); - TableAddCol (ParserToken.Value, (int) ParserToken.True, - (int) ParserToken.True); - TableAddCol (ParserToken.Value, (int) ParserToken.False, - (int) ParserToken.False); - TableAddCol (ParserToken.Value, (int) ParserToken.Null, - (int) ParserToken.Null); - - TableAddRow (ParserToken.ValueRest); - TableAddCol (ParserToken.ValueRest, ',', + TableAddRow(ParserToken.Text); + TableAddCol(ParserToken.Text, '[', + (int)ParserToken.Array); + TableAddCol(ParserToken.Text, '{', + (int)ParserToken.Object); + + TableAddRow(ParserToken.Value); + TableAddCol(ParserToken.Value, '"', + (int)ParserToken.String); + TableAddCol(ParserToken.Value, '[', + (int)ParserToken.Array); + TableAddCol(ParserToken.Value, '{', + (int)ParserToken.Object); + TableAddCol(ParserToken.Value, (int)ParserToken.Number, + (int)ParserToken.Number); + TableAddCol(ParserToken.Value, (int)ParserToken.True, + (int)ParserToken.True); + TableAddCol(ParserToken.Value, (int)ParserToken.False, + (int)ParserToken.False); + TableAddCol(ParserToken.Value, (int)ParserToken.Null, + (int)ParserToken.Null); + + TableAddRow(ParserToken.ValueRest); + TableAddCol(ParserToken.ValueRest, ',', ',', - (int) ParserToken.Value, - (int) ParserToken.ValueRest); - TableAddCol (ParserToken.ValueRest, ']', - (int) ParserToken.Epsilon); + (int)ParserToken.Value, + (int)ParserToken.ValueRest); + TableAddCol(ParserToken.ValueRest, ']', + (int)ParserToken.Epsilon); } - private static void TableAddCol (ParserToken row, int col, + private static void TableAddCol(ParserToken row, int col, params int[] symbols) { - parse_table[(int) row].Add (col, symbols); + parse_table[(int)row].Add(col, symbols); } - private static void TableAddRow (ParserToken rule) + private static void TableAddRow(ParserToken rule) { - parse_table.Add ((int) rule, new Dictionary ()); + parse_table.Add((int)rule, new Dictionary()); } #endregion #region Private Methods - private void ProcessNumber (string number) + private void ProcessNumber(string number) { - if (number.IndexOf ('.') != -1 || - number.IndexOf ('e') != -1 || - number.IndexOf ('E') != -1) { + if (number.IndexOf('.') != -1 || + number.IndexOf('e') != -1 || + number.IndexOf('E') != -1) + { double n_double; - if (Double.TryParse (number, out n_double)) { + if (Double.TryParse(number, out n_double)) + { token = JsonToken.Double; token_value = n_double; @@ -275,7 +284,8 @@ private void ProcessNumber (string number) } int n_int32; - if (Int32.TryParse (number, out n_int32)) { + if (Int32.TryParse(number, out n_int32)) + { token = JsonToken.Int; token_value = n_int32; @@ -283,7 +293,8 @@ private void ProcessNumber (string number) } long n_int64; - if (Int64.TryParse (number, out n_int64)) { + if (Int64.TryParse(number, out n_int64)) + { token = JsonToken.Long; token_value = n_int64; @@ -304,58 +315,82 @@ private void ProcessNumber (string number) token_value = 0; } - private void ProcessSymbol () + private void ProcessSymbol() { - if (current_symbol == '[') { + if (current_symbol == '[') + { token = JsonToken.ArrayStart; parser_return = true; - } else if (current_symbol == ']') { + } + else if (current_symbol == ']') + { token = JsonToken.ArrayEnd; parser_return = true; - } else if (current_symbol == '{') { + } + else if (current_symbol == '{') + { token = JsonToken.ObjectStart; parser_return = true; - } else if (current_symbol == '}') { + } + else if (current_symbol == '}') + { token = JsonToken.ObjectEnd; parser_return = true; - } else if (current_symbol == '"') { - if (parser_in_string) { + } + else if (current_symbol == '"') + { + if (parser_in_string) + { parser_in_string = false; parser_return = true; - } else { + } + else + { if (token == JsonToken.None) token = JsonToken.String; parser_in_string = true; } - } else if (current_symbol == (int) ParserToken.CharSeq) { + } + else if (current_symbol == (int)ParserToken.CharSeq) + { token_value = lexer.StringValue; - } else if (current_symbol == (int) ParserToken.False) { + } + else if (current_symbol == (int)ParserToken.False) + { token = JsonToken.Boolean; token_value = false; parser_return = true; - } else if (current_symbol == (int) ParserToken.Null) { + } + else if (current_symbol == (int)ParserToken.Null) + { token = JsonToken.Null; parser_return = true; - } else if (current_symbol == (int) ParserToken.Number) { - ProcessNumber (lexer.StringValue); + } + else if (current_symbol == (int)ParserToken.Number) + { + ProcessNumber(lexer.StringValue); parser_return = true; - } else if (current_symbol == (int) ParserToken.Pair) { + } + else if (current_symbol == (int)ParserToken.Pair) + { token = JsonToken.PropertyName; - } else if (current_symbol == (int) ParserToken.True) { + } + else if (current_symbol == (int)ParserToken.True) + { token = JsonToken.Boolean; token_value = true; parser_return = true; @@ -363,15 +398,16 @@ private void ProcessSymbol () } } - private bool ReadToken () + private bool ReadToken() { if (end_of_input) return false; - lexer.NextToken (); + lexer.NextToken(); - if (lexer.EndOfInput) { - Close (); + if (lexer.EndOfInput) + { + Close(); return false; } @@ -383,64 +419,70 @@ private bool ReadToken () #endregion - public void Close () + public void Close() { if (end_of_input) return; end_of_input = true; - end_of_json = true; + end_of_json = true; if (reader_is_owned) - reader.Close (); + reader.Close(); reader = null; } - public bool Read () + public bool Read() { if (end_of_input) return false; - if (end_of_json) { + if (end_of_json) + { end_of_json = false; - automaton_stack.Clear (); - automaton_stack.Push ((int) ParserToken.End); - automaton_stack.Push ((int) ParserToken.Text); + automaton_stack.Clear(); + automaton_stack.Push((int)ParserToken.End); + automaton_stack.Push((int)ParserToken.Text); } parser_in_string = false; - parser_return = false; + parser_return = false; - token = JsonToken.None; + token = JsonToken.None; token_value = null; - if (! read_started) { + if (!read_started) + { read_started = true; - if (! ReadToken ()) + if (!ReadToken()) return false; } int[] entry_symbols; - while (true) { - if (parser_return) { - if (automaton_stack.Peek () == (int) ParserToken.End) + while (true) + { + if (parser_return) + { + if (automaton_stack.Peek() == (int)ParserToken.End) end_of_json = true; return true; } - current_symbol = automaton_stack.Pop (); + current_symbol = automaton_stack.Pop(); - ProcessSymbol (); + ProcessSymbol(); - if (current_symbol == current_input) { - if (! ReadToken ()) { - if (automaton_stack.Peek () != (int) ParserToken.End) - throw new JsonException ( + if (current_symbol == current_input) + { + if (!ReadToken()) + { + if (automaton_stack.Peek() != (int)ParserToken.End) + throw new JsonException( "Input doesn't evaluate to proper JSON text"); if (parser_return) @@ -452,20 +494,23 @@ public bool Read () continue; } - try { + try + { entry_symbols = parse_table[current_symbol][current_input]; - } catch (KeyNotFoundException e) { - throw new JsonException ((ParserToken) current_input, e); + } + catch (KeyNotFoundException e) + { + throw new JsonException((ParserToken)current_input, e); } - if (entry_symbols[0] == (int) ParserToken.Epsilon) + if (entry_symbols[0] == (int)ParserToken.Epsilon) continue; for (int i = entry_symbols.Length - 1; i >= 0; i--) - automaton_stack.Push (entry_symbols[i]); + automaton_stack.Push(entry_symbols[i]); } } } diff --git a/OpenMetaverse.StructuredData/JSON/JsonWriter.cs b/OpenMetaverse.StructuredData/JSON/JsonWriter.cs index fffb6797..41036c1a 100644 --- a/OpenMetaverse.StructuredData/JSON/JsonWriter.cs +++ b/OpenMetaverse.StructuredData/JSON/JsonWriter.cs @@ -29,11 +29,11 @@ internal enum Condition internal class WriterContext { - public int Count; + public int Count; public bool InArray; public bool InObject; public bool ExpectingValue; - public int Padding; + public int Padding; } public class JsonWriter @@ -41,38 +41,43 @@ public class JsonWriter #region Fields private static NumberFormatInfo number_format; - private WriterContext context; + private WriterContext context; private Stack ctx_stack; - private bool has_reached_end; - private char[] hex_seq; - private int indentation; - private int indent_value; - private StringBuilder inst_string_builder; - private bool pretty_print; - private bool validate; - private TextWriter writer; + private bool has_reached_end; + private char[] hex_seq; + private int indentation; + private int indent_value; + private StringBuilder inst_string_builder; + private bool pretty_print; + private bool validate; + private TextWriter writer; #endregion #region Properties - public int IndentValue { + public int IndentValue + { get { return indent_value; } - set { + set + { indentation = (indentation / indent_value) * value; indent_value = value; } } - public bool PrettyPrint { + public bool PrettyPrint + { get { return pretty_print; } set { pretty_print = value; } } - public TextWriter TextWriter { + public TextWriter TextWriter + { get { return writer; } } - public bool Validate { + public bool Validate + { get { return validate; } set { validate = value; } } @@ -80,85 +85,80 @@ public bool Validate { #region Constructors - static JsonWriter () + static JsonWriter() { number_format = NumberFormatInfo.InvariantInfo; } - public JsonWriter () + public JsonWriter() { - inst_string_builder = new StringBuilder (); - writer = new StringWriter (inst_string_builder); + inst_string_builder = new StringBuilder(); + writer = new StringWriter(inst_string_builder); - Init (); + Init(); } - public JsonWriter (StringBuilder sb) : - this (new StringWriter (sb)) + public JsonWriter(StringBuilder sb) : + this(new StringWriter(sb)) { } - public JsonWriter (TextWriter writer) + public JsonWriter(TextWriter writer) { if (writer == null) - throw new ArgumentNullException ("writer"); + throw new ArgumentNullException("writer"); this.writer = writer; - Init (); + Init(); } #endregion #region Private Methods - private void DoValidation (Condition cond) + private void DoValidation(Condition cond) { - if (! context.ExpectingValue) + if (!context.ExpectingValue) context.Count++; - if (! validate) + if (!validate) return; if (has_reached_end) - throw new JsonException ( - "A complete JSON symbol has already been written"); - - switch (cond) { - case Condition.InArray: - if (! context.InArray) - throw new JsonException ( - "Can't close an array here"); - break; - - case Condition.InObject: - if (! context.InObject || context.ExpectingValue) - throw new JsonException ( - "Can't close an object here"); - break; - - case Condition.NotAProperty: - if (context.InObject && ! context.ExpectingValue) - throw new JsonException ( - "Expected a property"); - break; - - case Condition.Property: - if (! context.InObject || context.ExpectingValue) - throw new JsonException ( - "Can't add a property here"); - break; - - case Condition.Value: - if (! context.InArray && - (! context.InObject || ! context.ExpectingValue)) - throw new JsonException ( - "Can't add a value here"); - - break; + throw new JsonException("A complete JSON symbol has already been written"); + + switch (cond) + { + case Condition.InArray: + if (!context.InArray) + throw new JsonException("Can't close an array here"); + break; + + case Condition.InObject: + if (!context.InObject || context.ExpectingValue) + throw new JsonException("Can't close an object here"); + break; + + case Condition.NotAProperty: + if (context.InObject && !context.ExpectingValue) + throw new JsonException("Expected a property"); + break; + + case Condition.Property: + if (!context.InObject || context.ExpectingValue) + throw new JsonException("Can't add a property here"); + break; + + case Condition.Value: + if (!context.InArray && + (!context.InObject || !context.ExpectingValue)) + throw new JsonException("Can't add a value here"); + + break; } } - private void Init () + private void Init() { has_reached_end = false; hex_seq = new char[4]; @@ -167,109 +167,112 @@ private void Init () pretty_print = false; validate = true; - ctx_stack = new Stack (); - context = new WriterContext (); - ctx_stack.Push (context); + ctx_stack = new Stack(); + context = new WriterContext(); + ctx_stack.Push(context); } - private static void IntToHex (int n, char[] hex) + private static void IntToHex(int n, char[] hex) { int num; - for (int i = 0; i < 4; i++) { + for (int i = 0; i < 4; i++) + { num = n % 16; if (num < 10) - hex[3 - i] = (char) ('0' + num); + hex[3 - i] = (char)('0' + num); else - hex[3 - i] = (char) ('A' + (num - 10)); + hex[3 - i] = (char)('A' + (num - 10)); n >>= 4; } } - private void Indent () + private void Indent() { if (pretty_print) indentation += indent_value; } - private void Put (string str) + private void Put(string str) { - if (pretty_print && ! context.ExpectingValue) + if (pretty_print && !context.ExpectingValue) for (int i = 0; i < indentation; i++) - writer.Write (' '); + writer.Write(' '); - writer.Write (str); + writer.Write(str); } - private void PutNewline () + private void PutNewline() { - PutNewline (true); + PutNewline(true); } - private void PutNewline (bool add_comma) + private void PutNewline(bool add_comma) { - if (add_comma && ! context.ExpectingValue && - context.Count > 1) - writer.Write (','); + if (add_comma && !context.ExpectingValue && context.Count > 1) + writer.Write(','); - if (pretty_print && ! context.ExpectingValue) - writer.Write ('\n'); + if (pretty_print && !context.ExpectingValue) + writer.Write('\n'); } - private void PutString (string str) + private void PutString(string str) { - Put (String.Empty); + Put(String.Empty); - writer.Write ('"'); + writer.Write('"'); int n = str.Length; - for (int i = 0; i < n; i++) { - switch (str[i]) { - case '\n': - writer.Write ("\\n"); - continue; - - case '\r': - writer.Write ("\\r"); - continue; - - case '\t': - writer.Write ("\\t"); - continue; - - case '"': - case '\\': - writer.Write ('\\'); - writer.Write (str[i]); - continue; - - case '\f': - writer.Write ("\\f"); - continue; - - case '\b': - writer.Write ("\\b"); - continue; + for (int i = 0; i < n; i++) + { + switch (str[i]) + { + case '\n': + writer.Write("\\n"); + continue; + + case '\r': + writer.Write("\\r"); + continue; + + case '\t': + writer.Write("\\t"); + continue; + + case '"': + case '\\': + writer.Write('\\'); + writer.Write(str[i]); + continue; + + case '\f': + writer.Write("\\f"); + continue; + + case '\b': + writer.Write("\\b"); + continue; } - if ((int) str[i] >= 32 && (int) str[i] <= 126) { - writer.Write (str[i]); + if (str[i] >= 32 && str[i] <= 126) + { + writer.Write(str[i]); continue; } // Default, turn into a \uXXXX sequence - IntToHex ((int) str[i], hex_seq); - writer.Write ("\\u"); - writer.Write (hex_seq); + IntToHex((int)str[i], hex_seq); + writer.Write("\\u"); + writer.Write(hex_seq); } - writer.Write ('"'); + writer.Write('"'); } - private void Unindent () + private void Unindent() { if (pretty_print) indentation -= indent_value; @@ -277,184 +280,188 @@ private void Unindent () #endregion - public override string ToString () + public override string ToString() { if (inst_string_builder == null) return String.Empty; - return inst_string_builder.ToString (); + return inst_string_builder.ToString(); } - public void Reset () + public void Reset() { has_reached_end = false; - ctx_stack.Clear (); - context = new WriterContext (); - ctx_stack.Push (context); + ctx_stack.Clear(); + context = new WriterContext(); + ctx_stack.Push(context); if (inst_string_builder != null) - inst_string_builder.Remove (0, inst_string_builder.Length); + inst_string_builder.Clear(); } - public void Write (bool boolean) + public void Write(bool boolean) { - DoValidation (Condition.Value); - PutNewline (); + DoValidation(Condition.Value); + PutNewline(); - Put (boolean ? "true" : "false"); + Put(boolean ? "true" : "false"); context.ExpectingValue = false; } - public void Write (decimal number) + public void Write(decimal number) { - DoValidation (Condition.Value); - PutNewline (); + DoValidation(Condition.Value); + PutNewline(); - Put (Convert.ToString (number, number_format)); + Put(Convert.ToString(number, number_format)); context.ExpectingValue = false; } - public void Write (double number) + public void Write(double number) { - DoValidation (Condition.Value); - PutNewline (); + DoValidation(Condition.Value); + PutNewline(); - string str = Convert.ToString (number, number_format); - Put (str); + string str = Convert.ToString(number, number_format); + Put(str); - if (str.IndexOf ('.') == -1 && - str.IndexOf ('E') == -1) - writer.Write (".0"); + if (str.IndexOf('.') == -1 && + str.IndexOf('E') == -1) + writer.Write(".0"); context.ExpectingValue = false; } - public void Write (int number) + public void Write(int number) { - DoValidation (Condition.Value); - PutNewline (); + DoValidation(Condition.Value); + PutNewline(); - Put (Convert.ToString (number, number_format)); + Put(Convert.ToString(number, number_format)); context.ExpectingValue = false; } - public void Write (long number) + public void Write(long number) { - DoValidation (Condition.Value); - PutNewline (); + DoValidation(Condition.Value); + PutNewline(); - Put (Convert.ToString (number, number_format)); + Put(Convert.ToString(number, number_format)); context.ExpectingValue = false; } - public void Write (string str) + public void Write(string str) { - DoValidation (Condition.Value); - PutNewline (); + DoValidation(Condition.Value); + PutNewline(); if (str == null) - Put ("null"); + Put("null"); else - PutString (str); + PutString(str); context.ExpectingValue = false; } - public void Write (ulong number) + public void Write(ulong number) { - DoValidation (Condition.Value); - PutNewline (); + DoValidation(Condition.Value); + PutNewline(); - Put (Convert.ToString (number, number_format)); + Put(Convert.ToString(number, number_format)); context.ExpectingValue = false; } - public void WriteArrayEnd () + public void WriteArrayEnd() { - DoValidation (Condition.InArray); - PutNewline (false); + DoValidation(Condition.InArray); + PutNewline(false); - ctx_stack.Pop (); + ctx_stack.Pop(); if (ctx_stack.Count == 1) has_reached_end = true; - else { - context = ctx_stack.Peek (); + else + { + context = ctx_stack.Peek(); context.ExpectingValue = false; } - Unindent (); - Put ("]"); + Unindent(); + Put("]"); } - public void WriteArrayStart () + public void WriteArrayStart() { - DoValidation (Condition.NotAProperty); - PutNewline (); + DoValidation(Condition.NotAProperty); + PutNewline(); - Put ("["); + Put("["); - context = new WriterContext (); + context = new WriterContext(); context.InArray = true; - ctx_stack.Push (context); + ctx_stack.Push(context); - Indent (); + Indent(); } - public void WriteObjectEnd () + public void WriteObjectEnd() { - DoValidation (Condition.InObject); - PutNewline (false); + DoValidation(Condition.InObject); + PutNewline(false); - ctx_stack.Pop (); + ctx_stack.Pop(); if (ctx_stack.Count == 1) has_reached_end = true; - else { - context = ctx_stack.Peek (); + else + { + context = ctx_stack.Peek(); context.ExpectingValue = false; } - Unindent (); - Put ("}"); + Unindent(); + Put("}"); } - public void WriteObjectStart () + public void WriteObjectStart() { - DoValidation (Condition.NotAProperty); - PutNewline (); + DoValidation(Condition.NotAProperty); + PutNewline(); - Put ("{"); + Put("{"); - context = new WriterContext (); + context = new WriterContext(); context.InObject = true; - ctx_stack.Push (context); + ctx_stack.Push(context); - Indent (); + Indent(); } - public void WritePropertyName (string property_name) + public void WritePropertyName(string property_name) { - DoValidation (Condition.Property); - PutNewline (); + DoValidation(Condition.Property); + PutNewline(); - PutString (property_name); + PutString(property_name); - if (pretty_print) { + if (pretty_print) + { if (property_name.Length > context.Padding) context.Padding = property_name.Length; for (int i = context.Padding - property_name.Length; i >= 0; i--) - writer.Write (' '); + writer.Write(' '); - writer.Write (": "); - } else - writer.Write (':'); + writer.Write(": "); + } + else + writer.Write(':'); context.ExpectingValue = true; } diff --git a/OpenMetaverse.StructuredData/JSON/Lexer.cs b/OpenMetaverse.StructuredData/JSON/Lexer.cs index 6c388865..97195576 100644 --- a/OpenMetaverse.StructuredData/JSON/Lexer.cs +++ b/OpenMetaverse.StructuredData/JSON/Lexer.cs @@ -19,118 +19,124 @@ namespace LitJson { internal class FsmContext { - public bool Return; - public int NextState; + public bool Return; + public int NextState; public Lexer L; - public int StateStack; + public int StateStack; } internal class Lexer { #region Fields - private delegate bool StateHandler (FsmContext ctx); + private delegate bool StateHandler(FsmContext ctx); - private static int[] fsm_return_table; + private static int[] fsm_return_table; private static StateHandler[] fsm_handler_table; - private bool allow_comments; - private bool allow_single_quoted_strings; - private bool end_of_input; - private FsmContext fsm_context; - private int input_buffer; - private int input_char; - private TextReader reader; - private int state; + private bool allow_comments; + private bool allow_single_quoted_strings; + private bool end_of_input; + private FsmContext fsm_context; + private int input_buffer; + private int input_char; + private TextReader reader; + private int state; private StringBuilder string_buffer; - private string string_value; - private int token; - private int unichar; + private string string_value; + private int token; + private int unichar; #endregion #region Properties - public bool AllowComments { + public bool AllowComments + { get { return allow_comments; } set { allow_comments = value; } } - public bool AllowSingleQuotedStrings { + public bool AllowSingleQuotedStrings + { get { return allow_single_quoted_strings; } set { allow_single_quoted_strings = value; } } - public bool EndOfInput { + public bool EndOfInput + { get { return end_of_input; } } - public int Token { + public int Token + { get { return token; } } - public string StringValue { + public string StringValue + { get { return string_value; } } #endregion #region Constructors - static Lexer () + static Lexer() { - PopulateFsmTables (); + PopulateFsmTables(); } - public Lexer (TextReader reader) + public Lexer(TextReader reader) { allow_comments = true; allow_single_quoted_strings = true; input_buffer = 0; - string_buffer = new StringBuilder (128); + string_buffer = new StringBuilder(128); state = 1; end_of_input = false; this.reader = reader; - fsm_context = new FsmContext (); + fsm_context = new FsmContext(); fsm_context.L = this; } #endregion #region Static Methods - private static int HexValue (int digit) + private static int HexValue(int digit) { - switch (digit) { - case 'a': - case 'A': - return 10; + switch (digit) + { + case 'a': + case 'A': + return 10; - case 'b': - case 'B': - return 11; + case 'b': + case 'B': + return 11; - case 'c': - case 'C': - return 12; + case 'c': + case 'C': + return 12; - case 'd': - case 'D': - return 13; + case 'd': + case 'D': + return 13; - case 'e': - case 'E': - return 14; + case 'e': + case 'E': + return 14; - case 'f': - case 'F': - return 15; + case 'f': + case 'F': + return 15; - default: - return digit - '0'; + default: + return digit - '0'; } } - private static void PopulateFsmTables () + private static void PopulateFsmTables() { // See section A.1. of the manual for details of the finite // state machine. @@ -197,216 +203,229 @@ private static void PopulateFsmTables () }; } - private static char ProcessEscChar (int esc_char) + private static char ProcessEscChar(int esc_char) { - switch (esc_char) { - case '"': - case '\'': - case '\\': - case '/': - return Convert.ToChar (esc_char); + switch (esc_char) + { + case '"': + case '\'': + case '\\': + case '/': + return Convert.ToChar(esc_char); - case 'n': - return '\n'; + case 'n': + return '\n'; - case 't': - return '\t'; + case 't': + return '\t'; - case 'r': - return '\r'; + case 'r': + return '\r'; - case 'b': - return '\b'; + case 'b': + return '\b'; - case 'f': - return '\f'; + case 'f': + return '\f'; - default: - // Unreachable - return '?'; + default: + // Unreachable + return '?'; } } - private static bool State1 (FsmContext ctx) + private static bool State1(FsmContext ctx) { - while (ctx.L.GetChar ()) { + while (ctx.L.GetChar()) + { if (ctx.L.input_char == ' ' || ctx.L.input_char >= '\t' && ctx.L.input_char <= '\r') continue; - if (ctx.L.input_char >= '1' && ctx.L.input_char <= '9') { - ctx.L.string_buffer.Append ((char) ctx.L.input_char); + if (ctx.L.input_char >= '1' && ctx.L.input_char <= '9') + { + ctx.L.string_buffer.Append((char)ctx.L.input_char); ctx.NextState = 3; return true; } - switch (ctx.L.input_char) { - case '"': - ctx.NextState = 19; - ctx.Return = true; - return true; + switch (ctx.L.input_char) + { + case '"': + ctx.NextState = 19; + ctx.Return = true; + return true; - case ',': - case ':': - case '[': - case ']': - case '{': - case '}': - ctx.NextState = 1; - ctx.Return = true; - return true; + case ',': + case ':': + case '[': + case ']': + case '{': + case '}': + ctx.NextState = 1; + ctx.Return = true; + return true; - case '-': - ctx.L.string_buffer.Append ((char) ctx.L.input_char); - ctx.NextState = 2; - return true; + case '-': + ctx.L.string_buffer.Append((char)ctx.L.input_char); + ctx.NextState = 2; + return true; - case '0': - ctx.L.string_buffer.Append ((char) ctx.L.input_char); - ctx.NextState = 4; - return true; + case '0': + ctx.L.string_buffer.Append((char)ctx.L.input_char); + ctx.NextState = 4; + return true; - case 'f': - ctx.NextState = 12; - return true; + case 'f': + ctx.NextState = 12; + return true; - case 'n': - ctx.NextState = 16; - return true; + case 'n': + ctx.NextState = 16; + return true; - case 't': - ctx.NextState = 9; - return true; + case 't': + ctx.NextState = 9; + return true; - case '\'': - if (! ctx.L.allow_single_quoted_strings) - return false; + case '\'': + if (!ctx.L.allow_single_quoted_strings) + return false; - ctx.L.input_char = '"'; - ctx.NextState = 23; - ctx.Return = true; - return true; + ctx.L.input_char = '"'; + ctx.NextState = 23; + ctx.Return = true; + return true; - case '/': - if (! ctx.L.allow_comments) - return false; + case '/': + if (!ctx.L.allow_comments) + return false; - ctx.NextState = 25; - return true; + ctx.NextState = 25; + return true; - default: - return false; + default: + return false; } } return true; } - private static bool State2 (FsmContext ctx) + private static bool State2(FsmContext ctx) { - ctx.L.GetChar (); + ctx.L.GetChar(); - if (ctx.L.input_char >= '1' && ctx.L.input_char<= '9') { - ctx.L.string_buffer.Append ((char) ctx.L.input_char); + if (ctx.L.input_char >= '1' && ctx.L.input_char <= '9') + { + ctx.L.string_buffer.Append((char)ctx.L.input_char); ctx.NextState = 3; return true; } - switch (ctx.L.input_char) { - case '0': - ctx.L.string_buffer.Append ((char) ctx.L.input_char); - ctx.NextState = 4; - return true; + switch (ctx.L.input_char) + { + case '0': + ctx.L.string_buffer.Append((char)ctx.L.input_char); + ctx.NextState = 4; + return true; - default: - return false; + default: + return false; } } - private static bool State3 (FsmContext ctx) + private static bool State3(FsmContext ctx) { - while (ctx.L.GetChar ()) { - if (ctx.L.input_char >= '0' && ctx.L.input_char <= '9') { - ctx.L.string_buffer.Append ((char) ctx.L.input_char); + while (ctx.L.GetChar()) + { + if (ctx.L.input_char >= '0' && ctx.L.input_char <= '9') + { + ctx.L.string_buffer.Append((char)ctx.L.input_char); continue; } if (ctx.L.input_char == ' ' || - ctx.L.input_char >= '\t' && ctx.L.input_char <= '\r') { + ctx.L.input_char >= '\t' && ctx.L.input_char <= '\r') + { ctx.Return = true; ctx.NextState = 1; return true; } - switch (ctx.L.input_char) { - case ',': - case ']': - case '}': - ctx.L.UngetChar (); - ctx.Return = true; - ctx.NextState = 1; - return true; + switch (ctx.L.input_char) + { + case ',': + case ']': + case '}': + ctx.L.UngetChar(); + ctx.Return = true; + ctx.NextState = 1; + return true; - case '.': - ctx.L.string_buffer.Append ((char) ctx.L.input_char); - ctx.NextState = 5; - return true; + case '.': + ctx.L.string_buffer.Append((char)ctx.L.input_char); + ctx.NextState = 5; + return true; - case 'e': - case 'E': - ctx.L.string_buffer.Append ((char) ctx.L.input_char); - ctx.NextState = 7; - return true; + case 'e': + case 'E': + ctx.L.string_buffer.Append((char)ctx.L.input_char); + ctx.NextState = 7; + return true; - default: - return false; + default: + return false; } } return true; } - private static bool State4 (FsmContext ctx) + private static bool State4(FsmContext ctx) { - ctx.L.GetChar (); + ctx.L.GetChar(); if (ctx.L.input_char == ' ' || - ctx.L.input_char >= '\t' && ctx.L.input_char <= '\r') { + ctx.L.input_char >= '\t' && ctx.L.input_char <= '\r') + { ctx.Return = true; ctx.NextState = 1; return true; } - switch (ctx.L.input_char) { - case ',': - case ']': - case '}': - ctx.L.UngetChar (); - ctx.Return = true; - ctx.NextState = 1; - return true; + switch (ctx.L.input_char) + { + case ',': + case ']': + case '}': + ctx.L.UngetChar(); + ctx.Return = true; + ctx.NextState = 1; + return true; - case '.': - ctx.L.string_buffer.Append ((char) ctx.L.input_char); - ctx.NextState = 5; - return true; + case '.': + ctx.L.string_buffer.Append((char)ctx.L.input_char); + ctx.NextState = 5; + return true; - case 'e': - case 'E': - ctx.L.string_buffer.Append ((char) ctx.L.input_char); - ctx.NextState = 7; - return true; + case 'e': + case 'E': + ctx.L.string_buffer.Append((char)ctx.L.input_char); + ctx.NextState = 7; + return true; - default: - return false; + default: + return false; } } - private static bool State5 (FsmContext ctx) + private static bool State5(FsmContext ctx) { - ctx.L.GetChar (); + ctx.L.GetChar(); - if (ctx.L.input_char >= '0' && ctx.L.input_char <= '9') { - ctx.L.string_buffer.Append ((char) ctx.L.input_char); + if (ctx.L.input_char >= '0' && ctx.L.input_char <= '9') + { + ctx.L.string_buffer.Append((char)ctx.L.input_char); ctx.NextState = 6; return true; } @@ -414,329 +433,356 @@ private static bool State5 (FsmContext ctx) return false; } - private static bool State6 (FsmContext ctx) + private static bool State6(FsmContext ctx) { - while (ctx.L.GetChar ()) { - if (ctx.L.input_char >= '0' && ctx.L.input_char <= '9') { - ctx.L.string_buffer.Append ((char) ctx.L.input_char); + while (ctx.L.GetChar()) + { + if (ctx.L.input_char >= '0' && ctx.L.input_char <= '9') + { + ctx.L.string_buffer.Append((char)ctx.L.input_char); continue; } if (ctx.L.input_char == ' ' || - ctx.L.input_char >= '\t' && ctx.L.input_char <= '\r') { + ctx.L.input_char >= '\t' && ctx.L.input_char <= '\r') + { ctx.Return = true; ctx.NextState = 1; return true; } - switch (ctx.L.input_char) { - case ',': - case ']': - case '}': - ctx.L.UngetChar (); - ctx.Return = true; - ctx.NextState = 1; - return true; + switch (ctx.L.input_char) + { + case ',': + case ']': + case '}': + ctx.L.UngetChar(); + ctx.Return = true; + ctx.NextState = 1; + return true; - case 'e': - case 'E': - ctx.L.string_buffer.Append ((char) ctx.L.input_char); - ctx.NextState = 7; - return true; + case 'e': + case 'E': + ctx.L.string_buffer.Append((char)ctx.L.input_char); + ctx.NextState = 7; + return true; - default: - return false; + default: + return false; } } return true; } - private static bool State7 (FsmContext ctx) + private static bool State7(FsmContext ctx) { - ctx.L.GetChar (); + ctx.L.GetChar(); - if (ctx.L.input_char >= '0' && ctx.L.input_char<= '9') { - ctx.L.string_buffer.Append ((char) ctx.L.input_char); + if (ctx.L.input_char >= '0' && ctx.L.input_char <= '9') + { + ctx.L.string_buffer.Append((char)ctx.L.input_char); ctx.NextState = 8; return true; } - switch (ctx.L.input_char) { - case '+': - case '-': - ctx.L.string_buffer.Append ((char) ctx.L.input_char); - ctx.NextState = 8; - return true; + switch (ctx.L.input_char) + { + case '+': + case '-': + ctx.L.string_buffer.Append((char)ctx.L.input_char); + ctx.NextState = 8; + return true; - default: - return false; + default: + return false; } } - private static bool State8 (FsmContext ctx) + private static bool State8(FsmContext ctx) { - while (ctx.L.GetChar ()) { - if (ctx.L.input_char >= '0' && ctx.L.input_char<= '9') { - ctx.L.string_buffer.Append ((char) ctx.L.input_char); + while (ctx.L.GetChar()) + { + if (ctx.L.input_char >= '0' && ctx.L.input_char <= '9') + { + ctx.L.string_buffer.Append((char)ctx.L.input_char); continue; } if (ctx.L.input_char == ' ' || - ctx.L.input_char >= '\t' && ctx.L.input_char<= '\r') { + ctx.L.input_char >= '\t' && ctx.L.input_char <= '\r') + { ctx.Return = true; ctx.NextState = 1; return true; } - switch (ctx.L.input_char) { - case ',': - case ']': - case '}': - ctx.L.UngetChar (); - ctx.Return = true; - ctx.NextState = 1; - return true; + switch (ctx.L.input_char) + { + case ',': + case ']': + case '}': + ctx.L.UngetChar(); + ctx.Return = true; + ctx.NextState = 1; + return true; - default: - return false; + default: + return false; } } return true; } - private static bool State9 (FsmContext ctx) + private static bool State9(FsmContext ctx) { - ctx.L.GetChar (); + ctx.L.GetChar(); - switch (ctx.L.input_char) { - case 'r': - ctx.NextState = 10; - return true; + switch (ctx.L.input_char) + { + case 'r': + ctx.NextState = 10; + return true; - default: - return false; + default: + return false; } } - private static bool State10 (FsmContext ctx) + private static bool State10(FsmContext ctx) { - ctx.L.GetChar (); + ctx.L.GetChar(); - switch (ctx.L.input_char) { - case 'u': - ctx.NextState = 11; - return true; + switch (ctx.L.input_char) + { + case 'u': + ctx.NextState = 11; + return true; - default: - return false; + default: + return false; } } - private static bool State11 (FsmContext ctx) + private static bool State11(FsmContext ctx) { - ctx.L.GetChar (); + ctx.L.GetChar(); - switch (ctx.L.input_char) { - case 'e': - ctx.Return = true; - ctx.NextState = 1; - return true; + switch (ctx.L.input_char) + { + case 'e': + ctx.Return = true; + ctx.NextState = 1; + return true; - default: - return false; + default: + return false; } } - private static bool State12 (FsmContext ctx) + private static bool State12(FsmContext ctx) { - ctx.L.GetChar (); + ctx.L.GetChar(); - switch (ctx.L.input_char) { - case 'a': - ctx.NextState = 13; - return true; + switch (ctx.L.input_char) + { + case 'a': + ctx.NextState = 13; + return true; - default: - return false; + default: + return false; } } - private static bool State13 (FsmContext ctx) + private static bool State13(FsmContext ctx) { - ctx.L.GetChar (); + ctx.L.GetChar(); - switch (ctx.L.input_char) { - case 'l': - ctx.NextState = 14; - return true; + switch (ctx.L.input_char) + { + case 'l': + ctx.NextState = 14; + return true; - default: - return false; + default: + return false; } } - private static bool State14 (FsmContext ctx) + private static bool State14(FsmContext ctx) { - ctx.L.GetChar (); + ctx.L.GetChar(); - switch (ctx.L.input_char) { - case 's': - ctx.NextState = 15; - return true; + switch (ctx.L.input_char) + { + case 's': + ctx.NextState = 15; + return true; - default: - return false; + default: + return false; } } - private static bool State15 (FsmContext ctx) + private static bool State15(FsmContext ctx) { - ctx.L.GetChar (); + ctx.L.GetChar(); - switch (ctx.L.input_char) { - case 'e': - ctx.Return = true; - ctx.NextState = 1; - return true; + switch (ctx.L.input_char) + { + case 'e': + ctx.Return = true; + ctx.NextState = 1; + return true; - default: - return false; + default: + return false; } } - private static bool State16 (FsmContext ctx) + private static bool State16(FsmContext ctx) { - ctx.L.GetChar (); + ctx.L.GetChar(); - switch (ctx.L.input_char) { - case 'u': - ctx.NextState = 17; - return true; + switch (ctx.L.input_char) + { + case 'u': + ctx.NextState = 17; + return true; - default: - return false; + default: + return false; } } - private static bool State17 (FsmContext ctx) + private static bool State17(FsmContext ctx) { - ctx.L.GetChar (); + ctx.L.GetChar(); - switch (ctx.L.input_char) { - case 'l': - ctx.NextState = 18; - return true; + switch (ctx.L.input_char) + { + case 'l': + ctx.NextState = 18; + return true; - default: - return false; + default: + return false; } } - private static bool State18 (FsmContext ctx) + private static bool State18(FsmContext ctx) { - ctx.L.GetChar (); + ctx.L.GetChar(); - switch (ctx.L.input_char) { - case 'l': - ctx.Return = true; - ctx.NextState = 1; - return true; + switch (ctx.L.input_char) + { + case 'l': + ctx.Return = true; + ctx.NextState = 1; + return true; - default: - return false; + default: + return false; } } - private static bool State19 (FsmContext ctx) + private static bool State19(FsmContext ctx) { - while (ctx.L.GetChar ()) { - switch (ctx.L.input_char) { - case '"': - ctx.L.UngetChar (); - ctx.Return = true; - ctx.NextState = 20; - return true; + while (ctx.L.GetChar()) + { + switch (ctx.L.input_char) + { + case '"': + ctx.L.UngetChar(); + ctx.Return = true; + ctx.NextState = 20; + return true; - case '\\': - ctx.StateStack = 19; - ctx.NextState = 21; - return true; + case '\\': + ctx.StateStack = 19; + ctx.NextState = 21; + return true; - default: - ctx.L.string_buffer.Append ((char) ctx.L.input_char); - continue; + default: + ctx.L.string_buffer.Append((char)ctx.L.input_char); + continue; } } return true; } - private static bool State20 (FsmContext ctx) + private static bool State20(FsmContext ctx) { - ctx.L.GetChar (); + ctx.L.GetChar(); - switch (ctx.L.input_char) { - case '"': - ctx.Return = true; - ctx.NextState = 1; - return true; + switch (ctx.L.input_char) + { + case '"': + ctx.Return = true; + ctx.NextState = 1; + return true; - default: - return false; + default: + return false; } } - private static bool State21 (FsmContext ctx) + private static bool State21(FsmContext ctx) { - ctx.L.GetChar (); + ctx.L.GetChar(); - switch (ctx.L.input_char) { - case 'u': - ctx.NextState = 22; - return true; + switch (ctx.L.input_char) + { + case 'u': + ctx.NextState = 22; + return true; - case '"': - case '\'': - case '/': - case '\\': - case 'b': - case 'f': - case 'n': - case 'r': - case 't': - ctx.L.string_buffer.Append ( - ProcessEscChar (ctx.L.input_char)); - ctx.NextState = ctx.StateStack; - return true; + case '"': + case '\'': + case '/': + case '\\': + case 'b': + case 'f': + case 'n': + case 'r': + case 't': + ctx.L.string_buffer.Append( + ProcessEscChar(ctx.L.input_char)); + ctx.NextState = ctx.StateStack; + return true; - default: - return false; + default: + return false; } } - private static bool State22 (FsmContext ctx) + private static bool State22(FsmContext ctx) { int counter = 0; - int mult = 4096; + int mult = 4096; ctx.L.unichar = 0; - while (ctx.L.GetChar ()) { + while (ctx.L.GetChar()) + { if (ctx.L.input_char >= '0' && ctx.L.input_char <= '9' || ctx.L.input_char >= 'A' && ctx.L.input_char <= 'F' || - ctx.L.input_char >= 'a' && ctx.L.input_char <= 'f') { + ctx.L.input_char >= 'a' && ctx.L.input_char <= 'f') + { - ctx.L.unichar += HexValue (ctx.L.input_char) * mult; + ctx.L.unichar += HexValue(ctx.L.input_char) * mult; counter++; mult /= 16; - if (counter == 4) { - ctx.L.string_buffer.Append ( - Convert.ToChar (ctx.L.unichar)); + if (counter == 4) + { + ctx.L.string_buffer.Append( + Convert.ToChar(ctx.L.unichar)); ctx.NextState = ctx.StateStack; return true; } @@ -750,68 +796,74 @@ private static bool State22 (FsmContext ctx) return true; } - private static bool State23 (FsmContext ctx) + private static bool State23(FsmContext ctx) { - while (ctx.L.GetChar ()) { - switch (ctx.L.input_char) { - case '\'': - ctx.L.UngetChar (); - ctx.Return = true; - ctx.NextState = 24; - return true; + while (ctx.L.GetChar()) + { + switch (ctx.L.input_char) + { + case '\'': + ctx.L.UngetChar(); + ctx.Return = true; + ctx.NextState = 24; + return true; - case '\\': - ctx.StateStack = 23; - ctx.NextState = 21; - return true; + case '\\': + ctx.StateStack = 23; + ctx.NextState = 21; + return true; - default: - ctx.L.string_buffer.Append ((char) ctx.L.input_char); - continue; + default: + ctx.L.string_buffer.Append((char)ctx.L.input_char); + continue; } } return true; } - private static bool State24 (FsmContext ctx) + private static bool State24(FsmContext ctx) { - ctx.L.GetChar (); + ctx.L.GetChar(); - switch (ctx.L.input_char) { - case '\'': - ctx.L.input_char = '"'; - ctx.Return = true; - ctx.NextState = 1; - return true; + switch (ctx.L.input_char) + { + case '\'': + ctx.L.input_char = '"'; + ctx.Return = true; + ctx.NextState = 1; + return true; - default: - return false; + default: + return false; } } - private static bool State25 (FsmContext ctx) + private static bool State25(FsmContext ctx) { - ctx.L.GetChar (); + ctx.L.GetChar(); - switch (ctx.L.input_char) { - case '*': - ctx.NextState = 27; - return true; + switch (ctx.L.input_char) + { + case '*': + ctx.NextState = 27; + return true; - case '/': - ctx.NextState = 26; - return true; + case '/': + ctx.NextState = 26; + return true; - default: - return false; + default: + return false; } } - private static bool State26 (FsmContext ctx) + private static bool State26(FsmContext ctx) { - while (ctx.L.GetChar ()) { - if (ctx.L.input_char == '\n') { + while (ctx.L.GetChar()) + { + if (ctx.L.input_char == '\n') + { ctx.NextState = 1; return true; } @@ -820,10 +872,12 @@ private static bool State26 (FsmContext ctx) return true; } - private static bool State27 (FsmContext ctx) + private static bool State27(FsmContext ctx) { - while (ctx.L.GetChar ()) { - if (ctx.L.input_char == '*') { + while (ctx.L.GetChar()) + { + if (ctx.L.input_char == '*') + { ctx.NextState = 28; return true; } @@ -832,13 +886,15 @@ private static bool State27 (FsmContext ctx) return true; } - private static bool State28 (FsmContext ctx) + private static bool State28(FsmContext ctx) { - while (ctx.L.GetChar ()) { + while (ctx.L.GetChar()) + { if (ctx.L.input_char == '*') continue; - if (ctx.L.input_char == '/') { + if (ctx.L.input_char == '/') + { ctx.NextState = 1; return true; } @@ -852,47 +908,50 @@ private static bool State28 (FsmContext ctx) #endregion - private bool GetChar () + private bool GetChar() { - if ((input_char = NextChar ()) != -1) + if ((input_char = NextChar()) != -1) return true; end_of_input = true; return false; } - private int NextChar () + private int NextChar() { - if (input_buffer != 0) { + if (input_buffer != 0) + { int tmp = input_buffer; input_buffer = 0; return tmp; } - return reader.Read (); + return reader.Read(); } - public bool NextToken () + public bool NextToken() { StateHandler handler; fsm_context.Return = false; - while (true) { + while (true) + { handler = fsm_handler_table[state - 1]; - if (! handler (fsm_context)) - throw new JsonException (input_char); + if (!handler(fsm_context)) + throw new JsonException(input_char); if (end_of_input) return false; - if (fsm_context.Return) { - string_value = string_buffer.ToString (); - string_buffer.Remove (0, string_buffer.Length); + if (fsm_context.Return) + { + string_value = string_buffer.ToString(); + string_buffer.Remove(0, string_buffer.Length); token = fsm_return_table[state - 1]; - if (token == (int) ParserToken.Char) + if (token == (int)ParserToken.Char) token = input_char; state = fsm_context.NextState; @@ -904,7 +963,7 @@ public bool NextToken () } } - private void UngetChar () + private void UngetChar() { input_buffer = input_char; } From afa13f1a22197c6190f0c219aeb151aa1b9a6152 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Fri, 11 Feb 2022 19:34:43 +0000 Subject: [PATCH 032/149] a few changes to json writer --- .../JSON/JsonWriter.cs | 79 ++++++++----------- OpenMetaverseTypes/UtilsConversions.cs | 14 ++++ 2 files changed, 46 insertions(+), 47 deletions(-) diff --git a/OpenMetaverse.StructuredData/JSON/JsonWriter.cs b/OpenMetaverse.StructuredData/JSON/JsonWriter.cs index 41036c1a..1592d16f 100644 --- a/OpenMetaverse.StructuredData/JSON/JsonWriter.cs +++ b/OpenMetaverse.StructuredData/JSON/JsonWriter.cs @@ -14,7 +14,7 @@ using System.Globalization; using System.IO; using System.Text; - +using OpenMetaverse; namespace LitJson { @@ -172,23 +172,6 @@ private void Init() ctx_stack.Push(context); } - private static void IntToHex(int n, char[] hex) - { - int num; - - for (int i = 0; i < 4; i++) - { - num = n % 16; - - if (num < 10) - hex[3 - i] = (char)('0' + num); - else - hex[3 - i] = (char)('A' + (num - 10)); - - n >>= 4; - } - } - private void Indent() { if (pretty_print) @@ -221,52 +204,54 @@ private void PutNewline(bool add_comma) private void PutString(string str) { - Put(String.Empty); + Put(string.Empty); writer.Write('"'); - - int n = str.Length; - for (int i = 0; i < n; i++) + for (int i = 0; i < str.Length; i++) { - switch (str[i]) + char c = str[i]; + if (c >= 32 && c <= 126) + { + writer.Write(c); + continue; + } + writer.Write('\\'); + switch (c) { case '\n': - writer.Write("\\n"); - continue; + writer.Write('n'); + break; case '\r': - writer.Write("\\r"); - continue; + writer.Write('r'); + break; case '\t': - writer.Write("\\t"); - continue; + writer.Write('t'); + break; case '"': case '\\': - writer.Write('\\'); - writer.Write(str[i]); - continue; + writer.Write(c); + break; case '\f': - writer.Write("\\f"); - continue; + writer.Write('f'); + break; case '\b': - writer.Write("\\b"); - continue; + writer.Write('b'); + break; + + default: + // Default, turn into a \uXXXX sequence + writer.Write('u'); + writer.Write(Utils.charNibbleToHexUpper((byte)(c >> 12))); + writer.Write(Utils.charNibbleToHexUpper((byte)(c >> 8))); + writer.Write(Utils.charNibbleToHexUpper((byte)(c >> 4))); + writer.Write(Utils.charNibbleToHexUpper((byte)c)); + break; } - - if (str[i] >= 32 && str[i] <= 126) - { - writer.Write(str[i]); - continue; - } - - // Default, turn into a \uXXXX sequence - IntToHex((int)str[i], hex_seq); - writer.Write("\\u"); - writer.Write(hex_seq); } writer.Write('"'); diff --git a/OpenMetaverseTypes/UtilsConversions.cs b/OpenMetaverseTypes/UtilsConversions.cs index f6ea586d..f5797548 100644 --- a/OpenMetaverseTypes/UtilsConversions.cs +++ b/OpenMetaverseTypes/UtilsConversions.cs @@ -2810,6 +2810,13 @@ public static unsafe osUTF8 ULongToosUTF8(ulong v) return ret; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static byte NibbleToHexUpper(byte b) + { + b &= 0x0f; + return (byte)(b > 9 ? b + 0x37 : b + ASCIIzero); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static byte LowNibbleToHexByteChar(byte b) { @@ -2949,6 +2956,13 @@ public static unsafe osUTF8 UUIDToosUTF8(ref UUID v) return ret; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static char charNibbleToHexUpper(byte b) + { + b &= 0x0f; + return (char)(b > 9 ? b + 0x37 : b + ASCIIzero); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static char charLowNibbleToHexChar(byte b) { From f4c65d2bd98d3d1d1dfdf9934a08361b14621f91 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Sat, 12 Feb 2022 10:55:18 +0000 Subject: [PATCH 033/149] bug fix on json --- .../JSON/JsonWriter.cs | 34 ++++++++++--------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/OpenMetaverse.StructuredData/JSON/JsonWriter.cs b/OpenMetaverse.StructuredData/JSON/JsonWriter.cs index 1592d16f..850743b4 100644 --- a/OpenMetaverse.StructuredData/JSON/JsonWriter.cs +++ b/OpenMetaverse.StructuredData/JSON/JsonWriter.cs @@ -210,46 +210,48 @@ private void PutString(string str) for (int i = 0; i < str.Length; i++) { char c = str[i]; - if (c >= 32 && c <= 126) - { - writer.Write(c); - continue; - } - writer.Write('\\'); switch (c) { case '\n': - writer.Write('n'); + writer.Write("\\n"); break; case '\r': - writer.Write('r'); + writer.Write("\\r"); break; case '\t': - writer.Write('t'); + writer.Write("\\t"); break; case '"': case '\\': + writer.Write('\\'); writer.Write(c); break; case '\f': - writer.Write('f'); + writer.Write("\\f"); break; case '\b': - writer.Write('b'); + writer.Write("\\b"); break; default: // Default, turn into a \uXXXX sequence - writer.Write('u'); - writer.Write(Utils.charNibbleToHexUpper((byte)(c >> 12))); - writer.Write(Utils.charNibbleToHexUpper((byte)(c >> 8))); - writer.Write(Utils.charNibbleToHexUpper((byte)(c >> 4))); - writer.Write(Utils.charNibbleToHexUpper((byte)c)); + if (c >= 32 && c <= 126) + { + writer.Write(c); + } + else + { + writer.Write("\\u"); + writer.Write(Utils.charNibbleToHexUpper((byte)(c >> 12))); + writer.Write(Utils.charNibbleToHexUpper((byte)(c >> 8))); + writer.Write(Utils.charNibbleToHexUpper((byte)(c >> 4))); + writer.Write(Utils.charNibbleToHexUpper((byte)c)); + } break; } } From f3f0f33f36ecf090f4b3ba4a3736034f91981974 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Sun, 13 Feb 2022 21:29:57 +0000 Subject: [PATCH 034/149] change OSDjsone serialize --- OpenMetaverse.StructuredData/JSON/JsonWriter.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/OpenMetaverse.StructuredData/JSON/JsonWriter.cs b/OpenMetaverse.StructuredData/JSON/JsonWriter.cs index 850743b4..ff2d785d 100644 --- a/OpenMetaverse.StructuredData/JSON/JsonWriter.cs +++ b/OpenMetaverse.StructuredData/JSON/JsonWriter.cs @@ -315,8 +315,7 @@ public void Write(double number) string str = Convert.ToString(number, number_format); Put(str); - if (str.IndexOf('.') == -1 && - str.IndexOf('E') == -1) + if (str.IndexOfAny(new char[] { '.', 'E' }) == -1) writer.Write(".0"); context.ExpectingValue = false; From be41cf3e3afe6a318287b80a9668bf268bc20607 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Sun, 13 Feb 2022 21:32:09 +0000 Subject: [PATCH 035/149] actually do change OSDjson serialize --- OpenMetaverse.StructuredData/JSON/OSDJson.cs | 307 ++++++++++++++++++- 1 file changed, 299 insertions(+), 8 deletions(-) diff --git a/OpenMetaverse.StructuredData/JSON/OSDJson.cs b/OpenMetaverse.StructuredData/JSON/OSDJson.cs index 60442e26..b66e3355 100644 --- a/OpenMetaverse.StructuredData/JSON/OSDJson.cs +++ b/OpenMetaverse.StructuredData/JSON/OSDJson.cs @@ -2,9 +2,11 @@ using System.Collections; using System.Collections.Generic; using System.Collections.Specialized; +using System.Globalization; using System.IO; using System.Text; using LitJson; +using OpenMetaverse; namespace OpenMetaverse.StructuredData { @@ -66,6 +68,7 @@ public static OSD DeserializeJson(JsonData json) } } + /* public static string SerializeJsonString(OSD osd) { return SerializeJson(osd, false).ToJson(); @@ -80,7 +83,7 @@ public static string SerializeJsonString(OSD osd, bool preserveDefaults) { return SerializeJson(osd, preserveDefaults).ToJson(); } - + */ public static void SerializeJsonString(OSD osd, bool preserveDefaults, ref JsonWriter writer) { SerializeJson(osd, preserveDefaults).ToJson(writer); @@ -123,13 +126,7 @@ public static JsonData SerializeJson(OSD osd, bool preserveDefaults) OSDMap map = (OSDMap)osd; foreach (KeyValuePair kvp in map) { - JsonData data; - - if (preserveDefaults) - data = SerializeJson(kvp.Value, preserveDefaults); - else - data = SerializeJsonNoDefaults(kvp.Value); - + JsonData data = preserveDefaults ? SerializeJson(kvp.Value, true) : SerializeJsonNoDefaults(kvp.Value); if (data != null) jsonmap[kvp.Key] = data; } @@ -211,5 +208,299 @@ private static JsonData SerializeJsonNoDefaults(OSD osd) return null; } } + + public static string SerializeJsonString(OSD osd) + { + osUTF8 sb = OSUTF8Cached.Acquire(); + SerializeJson(osd, sb, false); + return OSUTF8Cached.GetStringAndRelease(sb); + } + + public static byte[] SerializeJsonToBytes(OSD osd) + { + osUTF8 sb = OSUTF8Cached.Acquire(); + SerializeJson(osd, sb, false); + return OSUTF8Cached.GetArrayAndRelease(sb); + } + + public static string SerializeJsonString(OSD osd, bool preserveDefaults) + { + osUTF8 sb = OSUTF8Cached.Acquire(); + SerializeJson(osd, sb, preserveDefaults); + return OSUTF8Cached.GetStringAndRelease(sb); + } + + public static void SerializeJson(OSD osd, osUTF8 sb, bool preserveDefaults) + { + int i; + switch (osd.Type) + { + case OSDType.Boolean: + sb.Append(osd.AsBoolean() ? osUTF8Const.OSUTF8true : osUTF8Const.OSUTF8false); + break; + case OSDType.Integer: + sb.AppendInt(osd.AsInteger()); + break; + case OSDType.Real: + string str = Convert.ToString(osd.AsReal(), NumberFormatInfo.InvariantInfo); + sb.AppendASCII(str); + + if (str.IndexOfAny(new char[]{'.','E' }) == -1) + sb.AppendASCII(".0"); + break; + case OSDType.String: + case OSDType.URI: + case OSDType.OSDUTF8: + case OSDType.LLSDxml: + appendJsonString((OSDString)osd, sb); + break; + case OSDType.UUID: + sb.AppendASCII('"'); + sb.AppendUUID(osd.AsUUID()); + sb.AppendASCII('"'); + break; + case OSDType.Date: + appendJsonString(osd.AsString(), sb); + break; + case OSDType.Binary: + byte[] binary = osd.AsBinary(); + i = 0; + sb.AppendASCII('['); + while (i < binary.Length - 1) + { + sb.AppendInt(binary[i++]); + sb.AppendASCII(','); + } + if (i < binary.Length) + sb.AppendInt(binary[i]); + sb.AppendASCII(']'); + break; + case OSDType.Array: + sb.AppendASCII('['); + OSDArray array = (OSDArray)osd; + i = 0; + while (i < array.Count - 1) + { + SerializeJson(array[i++], sb, preserveDefaults); + sb.AppendASCII(','); + } + if (i < array.Count) + SerializeJson(array[i], sb, preserveDefaults); + sb.AppendASCII(']'); + break; + case OSDType.Map: + sb.AppendASCII('{'); + OSDMap map = (OSDMap)osd; + i = 0; + foreach(KeyValuePair kvp in map) + { + if(preserveDefaults) + { + if (i++ > 0) + sb.AppendASCII(','); + appendJsonString(kvp.Key, sb); + sb.AppendASCII(':'); + SerializeJson(kvp.Value, sb, true); + } + else + SerializeJsonMapNoDefaults(kvp.Key, kvp.Value, ref i, sb); + } + sb.AppendASCII('}'); + break; + case OSDType.Unknown: + default: + sb.Append(osUTF8Const.OSUTF8null); + break; + } + } + + public static void SerializeJsonMapNoDefaults(string name, OSD osd, ref int mapcont, osUTF8 sb) + { + int i; + switch (osd.Type) + { + case OSDType.Boolean: + bool ob = osd.AsBoolean(); + if (ob) + { + if (mapcont++ > 0) + sb.AppendASCII(','); + appendJsonString(name, sb); + sb.AppendASCII(':'); + sb.Append(ob ? osUTF8Const.OSUTF8true : osUTF8Const.OSUTF8false); + } + break; + case OSDType.Integer: + int oi = osd.AsInteger(); + if(oi != 0) + { + if (mapcont++ > 0) + sb.AppendASCII(','); + appendJsonString(name, sb); + sb.AppendASCII(':'); + sb.AppendInt(oi); + } + break; + case OSDType.Real: + double od = osd.AsReal(); + if(od != 0) + { + if (mapcont++ > 0) + sb.AppendASCII(','); + appendJsonString(name, sb); + sb.AppendASCII(':'); + string str = Convert.ToString(od, NumberFormatInfo.InvariantInfo); + sb.AppendASCII(str); + + if (str.IndexOfAny(new char[] { '.', 'E' }) == -1) + sb.AppendASCII(".0"); + } + break; + case OSDType.String: + case OSDType.URI: + case OSDType.OSDUTF8: + case OSDType.LLSDxml: + OSDString ostr = (OSDString)osd; + if (!string.IsNullOrEmpty(ostr.value)) + { + if (mapcont++ > 0) + sb.AppendASCII(','); + appendJsonString(name, sb); + sb.AppendASCII(':'); + appendJsonString(ostr.value, sb); + } + break; + case OSDType.UUID: + UUID ou = osd.AsUUID(); + if(ou.IsNotZero()) + { + if (mapcont++ > 0) + sb.AppendASCII(','); + appendJsonString(name, sb); + sb.AppendASCII(":\""); + sb.AppendUUID(ou); + sb.AppendASCII('"'); + } + break; + + case OSDType.Date: + if (mapcont++ > 0) + sb.AppendASCII(','); + appendJsonString(name, sb); + sb.AppendASCII(':'); + appendJsonString(osd.AsString(), sb); + break; + case OSDType.Binary: + byte[] binary = osd.AsBinary(); + if (mapcont++ > 0) + sb.AppendASCII(','); + appendJsonString(name, sb); + sb.AppendASCII(":["); + if (binary != null && binary.Length > 0) + { + i = 0; + while (i < binary.Length - 1) + { + sb.AppendInt(binary[i++]); + sb.AppendASCII(','); + } + if (i < binary.Length) + sb.AppendInt(binary[i]); + + } + sb.AppendASCII(']'); + break; + case OSDType.Array: + if (mapcont++ > 0) + sb.AppendASCII(","); + appendJsonString(name, sb); + sb.AppendASCII(":["); + + OSDArray array = (OSDArray)osd; + if (array != null && array.Count > 0) + { + i = 0; + while (i < array.Count - 1) + { + SerializeJson(array[i++], sb, false); + sb.AppendASCII(','); + } + if (i < array.Count) + SerializeJson(array[i], sb, false); + } + sb.AppendASCII(']'); + break; + case OSDType.Map: + OSDMap map = (OSDMap)osd; + if (map != null && map.Count > 0) + { + if (mapcont++ > 0) + sb.AppendASCII(','); + appendJsonString(name, sb); + sb.AppendASCII(":{"); + + i = 0; + foreach (KeyValuePair kvp in map) + SerializeJsonMapNoDefaults(kvp.Key, kvp.Value, ref i, sb); + sb.AppendASCII('}'); + } + break; + case OSDType.Unknown: + default: + break; + } + } + + public static void appendJsonString(string str, osUTF8 sb) + { + sb.AppendASCII('"'); + for (int i = 0; i < str.Length; i++) + { + char c = str[i]; + switch (c) + { + case '\n': + sb.AppendASCII("\\n"); + break; + + case '\r': + sb.AppendASCII("\\r"); + break; + + case '\t': + sb.AppendASCII("\\t"); + break; + + case '"': + case '\\': + sb.AppendASCII('\\'); + sb.AppendASCII(c); + break; + + case '\f': + sb.AppendASCII("\\f"); + break; + + case '\b': + sb.AppendASCII("\\b"); + break; + + default: + // Default, turn into a \uXXXX sequence + if (c >= 32 && c <= 126) + sb.AppendASCII(c); + else + { + sb.AppendASCII("\\u"); + sb.Append(Utils.NibbleToHexUpper((byte)(c >> 12))); + sb.Append(Utils.NibbleToHexUpper((byte)(c >> 8))); + sb.Append(Utils.NibbleToHexUpper((byte)(c >> 4))); + sb.Append(Utils.NibbleToHexUpper((byte)c)); + } + break; + } + } + sb.AppendASCII('"'); + } } } From e2e88e2dc509e85cacf35fb5884b5f5d14276b3a Mon Sep 17 00:00:00 2001 From: mdickson Date: Thu, 17 Feb 2022 12:14:10 -0500 Subject: [PATCH 036/149] Bump version string. Upstream changes through 2/17/2022 --- CSJ2K/CSJ2K.csproj | 2 +- Directory.Build.props | 6 +++--- OpenMetaverse.GUI/OpenMetaverse.GUI.csproj | 2 +- OpenMetaverse.PrimMesher/OpenMetaverse.PrimMesher.csproj | 2 +- .../OpenMetaverse.Rendering.Meshmerizer.csproj | 2 +- .../OpenMetaverse.Rendering.Simple.csproj | 2 +- .../OpenMetaverse.StructuredData.csproj | 2 +- OpenMetaverse.Tests/OpenMetaverse.Tests.csproj | 4 ++-- OpenMetaverse.Types/OpenMetaverse.Types.csproj | 2 +- OpenMetaverse.Types/Vector2.cs | 1 + OpenMetaverse.Types/Vector4.cs | 1 + OpenMetaverse/OpenMetaverse.csproj | 4 ++-- Programs/GridProxy/GridProxy.csproj | 2 +- Programs/WinGridProxy/WinGridProxy.csproj | 2 +- 14 files changed, 18 insertions(+), 16 deletions(-) diff --git a/CSJ2K/CSJ2K.csproj b/CSJ2K/CSJ2K.csproj index ee641e1f..19099d30 100644 --- a/CSJ2K/CSJ2K.csproj +++ b/CSJ2K/CSJ2K.csproj @@ -11,6 +11,6 @@ true - + \ No newline at end of file diff --git a/Directory.Build.props b/Directory.Build.props index 7d42142b..2bad5494 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,8 +1,8 @@ - 1.1.6 - 1.1.6 - 1.1.6 + 1.1.7 + 1.1.7 + 1.1.7 $(SolutionDir)\obj\$(Configuration)\$(MSBuildProjectName)\ $(SolutionDir)\obj\$(Configuration)\$(MSBuildProjectName)\ $(SolutionDir)\build\$(Configuration)\$(AssemblyName)\ diff --git a/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj b/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj index 5f61070c..ca293378 100644 --- a/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj +++ b/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj @@ -6,7 +6,7 @@ True - + diff --git a/OpenMetaverse.PrimMesher/OpenMetaverse.PrimMesher.csproj b/OpenMetaverse.PrimMesher/OpenMetaverse.PrimMesher.csproj index b18c3b3a..e5e844ae 100644 --- a/OpenMetaverse.PrimMesher/OpenMetaverse.PrimMesher.csproj +++ b/OpenMetaverse.PrimMesher/OpenMetaverse.PrimMesher.csproj @@ -15,6 +15,6 @@ TRACE;VERTEX_INDEXER - + \ No newline at end of file diff --git a/OpenMetaverse.Rendering.Meshmerizer/OpenMetaverse.Rendering.Meshmerizer.csproj b/OpenMetaverse.Rendering.Meshmerizer/OpenMetaverse.Rendering.Meshmerizer.csproj index f3b90a4c..ef3a8ebe 100644 --- a/OpenMetaverse.Rendering.Meshmerizer/OpenMetaverse.Rendering.Meshmerizer.csproj +++ b/OpenMetaverse.Rendering.Meshmerizer/OpenMetaverse.Rendering.Meshmerizer.csproj @@ -7,7 +7,7 @@ true - + diff --git a/OpenMetaverse.Rendering.Simple/OpenMetaverse.Rendering.Simple.csproj b/OpenMetaverse.Rendering.Simple/OpenMetaverse.Rendering.Simple.csproj index 030e6b5d..690861d8 100644 --- a/OpenMetaverse.Rendering.Simple/OpenMetaverse.Rendering.Simple.csproj +++ b/OpenMetaverse.Rendering.Simple/OpenMetaverse.Rendering.Simple.csproj @@ -7,7 +7,7 @@ true - + diff --git a/OpenMetaverse.StructuredData/OpenMetaverse.StructuredData.csproj b/OpenMetaverse.StructuredData/OpenMetaverse.StructuredData.csproj index a811910d..ceb92dee 100644 --- a/OpenMetaverse.StructuredData/OpenMetaverse.StructuredData.csproj +++ b/OpenMetaverse.StructuredData/OpenMetaverse.StructuredData.csproj @@ -7,7 +7,7 @@ true - + diff --git a/OpenMetaverse.Tests/OpenMetaverse.Tests.csproj b/OpenMetaverse.Tests/OpenMetaverse.Tests.csproj index 90d0b5bf..2b7f7d37 100644 --- a/OpenMetaverse.Tests/OpenMetaverse.Tests.csproj +++ b/OpenMetaverse.Tests/OpenMetaverse.Tests.csproj @@ -6,8 +6,8 @@ 1591,1574,0419,0618 - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/OpenMetaverse.Types/OpenMetaverse.Types.csproj b/OpenMetaverse.Types/OpenMetaverse.Types.csproj index f93afd11..cd2892d1 100644 --- a/OpenMetaverse.Types/OpenMetaverse.Types.csproj +++ b/OpenMetaverse.Types/OpenMetaverse.Types.csproj @@ -11,6 +11,6 @@ - + \ No newline at end of file diff --git a/OpenMetaverse.Types/Vector2.cs b/OpenMetaverse.Types/Vector2.cs index 292e242f..b3dd3229 100644 --- a/OpenMetaverse.Types/Vector2.cs +++ b/OpenMetaverse.Types/Vector2.cs @@ -25,6 +25,7 @@ */ using System; +using System.Globalization; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; diff --git a/OpenMetaverse.Types/Vector4.cs b/OpenMetaverse.Types/Vector4.cs index cc81ae83..f6aa7828 100644 --- a/OpenMetaverse.Types/Vector4.cs +++ b/OpenMetaverse.Types/Vector4.cs @@ -25,6 +25,7 @@ */ using System; +using System.Globalization; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; diff --git a/OpenMetaverse/OpenMetaverse.csproj b/OpenMetaverse/OpenMetaverse.csproj index 5bc2d2f9..ce8212b5 100644 --- a/OpenMetaverse/OpenMetaverse.csproj +++ b/OpenMetaverse/OpenMetaverse.csproj @@ -8,8 +8,8 @@ true - - + + diff --git a/Programs/GridProxy/GridProxy.csproj b/Programs/GridProxy/GridProxy.csproj index 80c3589b..21da9dc5 100644 --- a/Programs/GridProxy/GridProxy.csproj +++ b/Programs/GridProxy/GridProxy.csproj @@ -6,7 +6,7 @@ 1591,1574,0419,0618 - + diff --git a/Programs/WinGridProxy/WinGridProxy.csproj b/Programs/WinGridProxy/WinGridProxy.csproj index 3a0ec4ae..56de6992 100644 --- a/Programs/WinGridProxy/WinGridProxy.csproj +++ b/Programs/WinGridProxy/WinGridProxy.csproj @@ -12,7 +12,7 @@ 1591,1574,0419,0618 - + From 162f46a6f5e2b2ae95cb3e0481a772c725b9741f Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Tue, 15 Mar 2022 16:46:11 +0000 Subject: [PATCH 037/149] update wearables arrays with entries BOM, to avoid null refs. This is only for pcampbot. Clients based on libomv need more work --- .../j2k/codestream/writer/BitOutputBuffer.cs | 534 +++++++++--------- .../StructuredData.cs | 4 +- OpenMetaverse/AgentManager.cs | 2 +- OpenMetaverse/AppearanceManager.cs | 27 +- 4 files changed, 290 insertions(+), 277 deletions(-) diff --git a/CSJ2K/j2k/codestream/writer/BitOutputBuffer.cs b/CSJ2K/j2k/codestream/writer/BitOutputBuffer.cs index 7e67929b..0b367f4a 100644 --- a/CSJ2K/j2k/codestream/writer/BitOutputBuffer.cs +++ b/CSJ2K/j2k/codestream/writer/BitOutputBuffer.cs @@ -44,272 +44,272 @@ using CSJ2K.j2k.util; namespace CSJ2K.j2k.codestream.writer { - - /// This class implements a buffer for writing bits, with the required bit - /// stuffing policy for the packet headers. The bits are stored in a byte array - /// in the order in which they are written. The byte array is automatically - /// reallocated and enlarged whenever necessary. A BitOutputBuffer object may - /// be reused by calling its 'reset()' method. - /// - ///

NOTE: The methods implemented in this class are intended to be used only - /// in writing packet heads, since a special bit stuffing procedure is used, as - /// required for the packet heads. - /// - ///

- public class BitOutputBuffer - { - /// Returns the current length of the buffer, in bytes. - /// - ///

This method is declared final to increase performance. - /// - ///

- /// The currebt length of the buffer in bytes. - /// - /// - virtual public int Length - { - get - { - if (avbits == 8) - { - // A integral number of bytes - return curbyte; - } - else - { - // Some bits in last byte - return curbyte + 1; - } - } - - } - /// Returns the byte buffer. This is the internal byte buffer so it should - /// not be modified. Only the first N elements have valid data, where N is - /// the value returned by 'getLength()' - /// - ///

This method is declared final to increase performance. - /// - ///

- /// The internal byte buffer. - /// - /// - virtual public byte[] Buffer - { - get - { - return buf; - } - - } - - /// The buffer where we store the data - internal byte[] buf; - - /// The position of the current byte to write - internal int curbyte; - - /// The number of available bits in the current byte - internal int avbits = 8; - - /// The increment size for the buffer, 16 bytes. This is the - /// number of bytes that are added to the buffer each time it is - /// needed to enlarge it. - /// - // This must be always 6 or larger. - public const int SZ_INCR = 16; - - /// The initial size for the buffer, 32 bytes. - public const int SZ_INIT = 32; - - /// Creates a new BitOutputBuffer width a buffer of length - /// 'SZ_INIT'. - /// - /// - public BitOutputBuffer() - { - buf = new byte[SZ_INIT]; - } - - /// Resets the buffer. This rewinds the current position to the start of - /// the buffer and sets all tha data to 0. Note that no new buffer is - /// allocated, so this will affect any data that was returned by the - /// 'getBuffer()' method. - /// - /// - public virtual void reset() - { - //int i; - // Reinit pointers - curbyte = 0; - avbits = 8; - ArrayUtil.byteArraySet(buf, (byte) 0); - } - - /// Writes a bit to the buffer at the current position. The value 'bit' - /// must be either 0 or 1, otherwise it corrupts the bits that have been - /// already written. The buffer is enlarged, by 'SZ_INCR' bytes, if - /// necessary. - /// - ///

This method is declared final to increase performance. - /// - ///

- /// The bit to write, 0 or 1. - /// - /// - public void writeBit(int bit) - { - buf[curbyte] |= (byte) (bit << --avbits); - if (avbits > 0) - { - // There is still place in current byte for next bit - return ; - } - else - { - // End of current byte => goto next - if (buf[curbyte] != (byte) SupportClass.Identity(0xFF)) - { - // We don't need bit stuffing - avbits = 8; - } - else - { - // We need to stuff a bit (next MSBit is 0) - avbits = 7; - } - curbyte++; - if (curbyte == buf.Length) - { - // We are at end of 'buf' => extend it - byte[] oldbuf = buf; - buf = new byte[oldbuf.Length + SZ_INCR]; - Array.Copy(oldbuf, 0, buf, 0, oldbuf.Length); - } - } - } - - /// Writes the n least significant bits of 'bits' to the buffer at the - /// current position. The least significant bit is written last. The 32-n - /// most significant bits of 'bits' must be 0, otherwise corruption of the - /// buffer will result. The buffer is enlarged, by 'SZ_INCR' bytes, if - /// necessary. - /// - ///

This method is declared final to increase performance. - /// - ///

- /// The bits to write. - /// - /// - /// The number of LSBs in 'bits' to write. - /// - /// - public void writeBits(int bits, int n) - { - // Check that we have enough place in 'buf' for n bits, and that we do - // not fill last byte, taking into account possibly stuffed bits (max - // 2) - if (((buf.Length - curbyte) << 3) - 8 + avbits <= n + 2) - { - // Not enough place, extend it - byte[] oldbuf = buf; - buf = new byte[oldbuf.Length + SZ_INCR]; - Array.Copy(oldbuf, 0, buf, 0, oldbuf.Length); - // SZ_INCR is always 6 or more, so it is enough to hold all the - // new bits plus the ones to come after - } - // Now write the bits - if (n >= avbits) - { - // Complete the current byte - n -= avbits; - buf[curbyte] |= (byte) (bits >> n); - if (buf[curbyte] != (byte) SupportClass.Identity(0xFF)) - { - // We don't need bit stuffing - avbits = 8; - } - else - { - // We need to stuff a bit (next MSBit is 0) - avbits = 7; - } - curbyte++; - // Write whole bytes - while (n >= avbits) - { - n -= avbits; + + /// This class implements a buffer for writing bits, with the required bit + /// stuffing policy for the packet headers. The bits are stored in a byte array + /// in the order in which they are written. The byte array is automatically + /// reallocated and enlarged whenever necessary. A BitOutputBuffer object may + /// be reused by calling its 'reset()' method. + /// + ///

NOTE: The methods implemented in this class are intended to be used only + /// in writing packet heads, since a special bit stuffing procedure is used, as + /// required for the packet heads. + /// + ///

+ public class BitOutputBuffer + { + /// Returns the current length of the buffer, in bytes. + /// + ///

This method is declared final to increase performance. + /// + ///

+ /// The currebt length of the buffer in bytes. + /// + /// + virtual public int Length + { + get + { + if (avbits == 8) + { + // A integral number of bytes + return curbyte; + } + else + { + // Some bits in last byte + return curbyte + 1; + } + } + + } + /// Returns the byte buffer. This is the internal byte buffer so it should + /// not be modified. Only the first N elements have valid data, where N is + /// the value returned by 'getLength()' + /// + ///

This method is declared final to increase performance. + /// + ///

+ /// The internal byte buffer. + /// + /// + virtual public byte[] Buffer + { + get + { + return buf; + } + + } + + /// The buffer where we store the data + internal byte[] buf; + + /// The position of the current byte to write + internal int curbyte; + + /// The number of available bits in the current byte + internal int avbits = 8; + + /// The increment size for the buffer, 16 bytes. This is the + /// number of bytes that are added to the buffer each time it is + /// needed to enlarge it. + /// + // This must be always 6 or larger. + public const int SZ_INCR = 16; + + /// The initial size for the buffer, 32 bytes. + public const int SZ_INIT = 32; + + /// Creates a new BitOutputBuffer width a buffer of length + /// 'SZ_INIT'. + /// + /// + public BitOutputBuffer() + { + buf = new byte[SZ_INIT]; + } + + /// Resets the buffer. This rewinds the current position to the start of + /// the buffer and sets all tha data to 0. Note that no new buffer is + /// allocated, so this will affect any data that was returned by the + /// 'getBuffer()' method. + /// + /// + public virtual void reset() + { + //int i; + // Reinit pointers + curbyte = 0; + avbits = 8; + ArrayUtil.byteArraySet(buf, (byte)0); + } + + /// Writes a bit to the buffer at the current position. The value 'bit' + /// must be either 0 or 1, otherwise it corrupts the bits that have been + /// already written. The buffer is enlarged, by 'SZ_INCR' bytes, if + /// necessary. + /// + ///

This method is declared final to increase performance. + /// + ///

+ /// The bit to write, 0 or 1. + /// + /// + public void writeBit(int bit) + { + buf[curbyte] |= (byte)(bit << --avbits); + if (avbits > 0) + { + // There is still place in current byte for next bit + return; + } + else + { + // End of current byte => goto next + if (buf[curbyte] != (byte)SupportClass.Identity(0xFF)) + { + // We don't need bit stuffing + avbits = 8; + } + else + { + // We need to stuff a bit (next MSBit is 0) + avbits = 7; + } + curbyte++; + if (curbyte == buf.Length) + { + // We are at end of 'buf' => extend it + byte[] oldbuf = buf; + buf = new byte[oldbuf.Length + SZ_INCR]; + Array.Copy(oldbuf, 0, buf, 0, oldbuf.Length); + } + } + } + + /// Writes the n least significant bits of 'bits' to the buffer at the + /// current position. The least significant bit is written last. The 32-n + /// most significant bits of 'bits' must be 0, otherwise corruption of the + /// buffer will result. The buffer is enlarged, by 'SZ_INCR' bytes, if + /// necessary. + /// + ///

This method is declared final to increase performance. + /// + ///

+ /// The bits to write. + /// + /// + /// The number of LSBs in 'bits' to write. + /// + /// + public void writeBits(int bits, int n) + { + // Check that we have enough place in 'buf' for n bits, and that we do + // not fill last byte, taking into account possibly stuffed bits (max + // 2) + if (((buf.Length - curbyte) << 3) - 8 + avbits <= n + 2) + { + // Not enough place, extend it + byte[] oldbuf = buf; + buf = new byte[oldbuf.Length + SZ_INCR]; + Array.Copy(oldbuf, 0, buf, 0, oldbuf.Length); + // SZ_INCR is always 6 or more, so it is enough to hold all the + // new bits plus the ones to come after + } + // Now write the bits + if (n >= avbits) + { + // Complete the current byte + n -= avbits; + buf[curbyte] |= (byte)(bits >> n); + if (buf[curbyte] != (byte)SupportClass.Identity(0xFF)) + { + // We don't need bit stuffing + avbits = 8; + } + else + { + // We need to stuff a bit (next MSBit is 0) + avbits = 7; + } + curbyte++; + // Write whole bytes + while (n >= avbits) + { + n -= avbits; // CONVERSION PROBLEM? - buf[curbyte] |= (byte)((bits >> n) & (~ (1 << avbits))); - if (buf[curbyte] != (byte) SupportClass.Identity(0xFF)) - { - // We don't need bit - // stuffing - avbits = 8; - } - else - { - // We need to stuff a bit (next MSBit is 0) - avbits = 7; - } - curbyte++; - } - } - // Finish last byte (we know that now n < avbits) - if (n > 0) - { - avbits -= n; - buf[curbyte] |= (byte) ((bits & ((1 << n) - 1)) << avbits); - } - if (avbits == 0) - { - // Last byte is full - if (buf[curbyte] != (byte) SupportClass.Identity(0xFF)) - { - // We don't need bit stuffing - avbits = 8; - } - else - { - // We need to stuff a bit (next MSBit is 0) - avbits = 7; - } - curbyte++; // We already ensured that we have enough place - } - } - - /// Returns the byte buffer data in a new array. This is a copy of the - /// internal byte buffer. If 'data' is non-null it is used to return the - /// data. This array should be large enough to contain all the data, - /// otherwise a IndexOutOfBoundsException is thrown by the Java system. The - /// number of elements returned is what 'getLength()' returns. - /// - /// - /// If non-null this array is used to return the data, which - /// mus be large enough. Otherwise a new one is created and returned. - /// - /// - /// The byte buffer data. - /// - /// - public virtual byte[] toByteArray(byte[] data) - { - if (data == null) - { - data = new byte[(avbits == 8)?curbyte:curbyte + 1]; - } - Array.Copy(buf, 0, data, 0, (avbits == 8)?curbyte:curbyte + 1); - return data; - } - - /// Prints information about this object for debugging purposes - /// - /// - /// Information about the object. - /// - /// - public override System.String ToString() - { - return "bits written = " + (curbyte * 8 + (8 - avbits)) + ", curbyte = " + curbyte + ", avbits = " + avbits; - } - } + buf[curbyte] |= (byte)((bits >> n) & (~(1 << avbits))); + if (buf[curbyte] != (byte)SupportClass.Identity(0xFF)) + { + // We don't need bit + // stuffing + avbits = 8; + } + else + { + // We need to stuff a bit (next MSBit is 0) + avbits = 7; + } + curbyte++; + } + } + // Finish last byte (we know that now n < avbits) + if (n > 0) + { + avbits -= n; + buf[curbyte] |= (byte)((bits & ((1 << n) - 1)) << avbits); + } + if (avbits == 0) + { + // Last byte is full + if (buf[curbyte] != (byte)SupportClass.Identity(0xFF)) + { + // We don't need bit stuffing + avbits = 8; + } + else + { + // We need to stuff a bit (next MSBit is 0) + avbits = 7; + } + curbyte++; // We already ensured that we have enough place + } + } + + /// Returns the byte buffer data in a new array. This is a copy of the + /// internal byte buffer. If 'data' is non-null it is used to return the + /// data. This array should be large enough to contain all the data, + /// otherwise a IndexOutOfBoundsException is thrown by the Java system. The + /// number of elements returned is what 'getLength()' returns. + /// + /// + /// If non-null this array is used to return the data, which + /// mus be large enough. Otherwise a new one is created and returned. + /// + /// + /// The byte buffer data. + /// + /// + public virtual byte[] toByteArray(byte[] data) + { + if (data == null) + { + data = new byte[(avbits == 8) ? curbyte : curbyte + 1]; + } + Array.Copy(buf, 0, data, 0, (avbits == 8) ? curbyte : curbyte + 1); + return data; + } + + /// Prints information about this object for debugging purposes + /// + /// + /// Information about the object. + /// + /// + public override System.String ToString() + { + return "bits written = " + (curbyte * 8 + (8 - avbits)) + ", curbyte = " + curbyte + ", avbits = " + avbits; + } + } } \ No newline at end of file diff --git a/OpenMetaverse.StructuredData/StructuredData.cs b/OpenMetaverse.StructuredData/StructuredData.cs index 49cc136a..7b3b4d9e 100644 --- a/OpenMetaverse.StructuredData/StructuredData.cs +++ b/OpenMetaverse.StructuredData/StructuredData.cs @@ -139,9 +139,9 @@ public virtual int AsInteger() double v = ((OSDReal)this).value; if (Double.IsNaN(v)) return 0; - if (v > Int32.MaxValue) + if (v >= Int32.MaxValue) return Int32.MaxValue; - if (v < Int32.MinValue) + if (v <= Int32.MinValue) return Int32.MinValue; return (int)Math.Round(v); case OSDType.String: diff --git a/OpenMetaverse/AgentManager.cs b/OpenMetaverse/AgentManager.cs index 4b8439c5..d7a3bb04 100644 --- a/OpenMetaverse/AgentManager.cs +++ b/OpenMetaverse/AgentManager.cs @@ -4217,7 +4217,7 @@ private void ChatterBoxSessionAgentListUpdatesEventHandler(string capsKey, IMess { if (msg.Updates[i].Transition.Equals("ENTER")) { - if (fndMbr.AvatarKey == UUID.Zero) + if (fndMbr.AvatarKey.IsZero()) { fndMbr = new ChatSessionMember(); fndMbr.AvatarKey = msg.Updates[i].AgentID; diff --git a/OpenMetaverse/AppearanceManager.cs b/OpenMetaverse/AppearanceManager.cs index 80ee42c2..9d4914d9 100644 --- a/OpenMetaverse/AppearanceManager.cs +++ b/OpenMetaverse/AppearanceManager.cs @@ -164,7 +164,13 @@ public class AppearanceManager new WearableType[] { WearableType.Shape, WearableType.Skin, WearableType.Tattoo, WearableType.Pants, WearableType.Shoes, WearableType.Socks, WearableType.Jacket, WearableType.Underpants, WearableType.Alpha }, new WearableType[] { WearableType.Eyes, WearableType.Invalid, WearableType.Invalid, WearableType.Invalid, WearableType.Invalid, WearableType.Invalid, WearableType.Invalid, WearableType.Invalid, WearableType.Invalid }, new WearableType[] { WearableType.Skirt, WearableType.Invalid, WearableType.Invalid, WearableType.Invalid, WearableType.Invalid, WearableType.Invalid, WearableType.Invalid, WearableType.Invalid, WearableType.Invalid }, - new WearableType[] { WearableType.Hair, WearableType.Invalid, WearableType.Invalid, WearableType.Invalid, WearableType.Invalid, WearableType.Invalid, WearableType.Invalid, WearableType.Invalid, WearableType.Invalid } + new WearableType[] { WearableType.Hair, WearableType.Invalid, WearableType.Invalid, WearableType.Invalid, WearableType.Invalid, WearableType.Invalid, WearableType.Invalid, WearableType.Invalid, WearableType.Invalid }, + + new WearableType[] { WearableType.Invalid, WearableType.Invalid, WearableType.Invalid, WearableType.Invalid, WearableType.Invalid, WearableType.Invalid, WearableType.Invalid, WearableType.Invalid, WearableType.Invalid }, + new WearableType[] { WearableType.Invalid, WearableType.Invalid, WearableType.Invalid, WearableType.Invalid, WearableType.Invalid, WearableType.Invalid, WearableType.Invalid, WearableType.Invalid, WearableType.Invalid }, + new WearableType[] { WearableType.Invalid, WearableType.Invalid, WearableType.Invalid, WearableType.Invalid, WearableType.Invalid, WearableType.Invalid, WearableType.Invalid, WearableType.Invalid, WearableType.Invalid }, + new WearableType[] { WearableType.Invalid, WearableType.Invalid, WearableType.Invalid, WearableType.Invalid, WearableType.Invalid, WearableType.Invalid, WearableType.Invalid, WearableType.Invalid, WearableType.Invalid }, + new WearableType[] { WearableType.Invalid, WearableType.Invalid, WearableType.Invalid, WearableType.Invalid, WearableType.Invalid, WearableType.Invalid, WearableType.Invalid, WearableType.Invalid, WearableType.Invalid } }; /// Magic values to finalize the cache check hashes for each /// bake @@ -175,7 +181,14 @@ public class AppearanceManager new UUID("91b4a2c7-1b1a-ba16-9a16-1f8f8dcc1c3f"), new UUID("b2cf28af-b840-1071-3c6a-78085d8128b5"), new UUID("ea800387-ea1a-14e0-56cb-24f2022f969a"), - new UUID("0af1ef7c-ad24-11dd-8790-001f5bf833e8") + new UUID("0af1ef7c-ad24-11dd-8790-001f5bf833e8"), + + new UUID("e2658fa6-a47b-11ec-b909-0242ac120002"), + new UUID("ea8620e2-a47b-11ec-b909-0242ac120002"), + new UUID("f175510c-a47b-11ec-b909-0242ac120002"), + new UUID("f8011ec0-a47b-11ec-b909-0242ac120002"), + new UUID("ff7b4dce-a47b-11ec-b909-0242ac120002") + }; /// Default avatar texture, used to detect when a custom /// texture is not set for a face @@ -632,7 +645,7 @@ public void RequestCachedBakes() hash ^= wearable.AssetID; } - if (hash != UUID.Zero) + if (hash.IsNotZero()) { // Hash with our secret value for this baked layer hash ^= BAKED_TEXTURE_HASH[bakedIndex]; @@ -1694,7 +1707,7 @@ private bool CreateBakes() { AvatarTextureIndex textureIndex = BakeTypeToAgentTextureIndex((BakeType)bakedIndex); - if (Textures[(int)textureIndex].TextureID == UUID.Zero) + if (Textures[(int)textureIndex].TextureID.IsZero()) { // If this is the skirt layer and we're not wearing a skirt then skip it if (bakedIndex == (int)BakeType.Skirt && !Wearables.ContainsKey(WearableType.Skirt)) @@ -1757,7 +1770,7 @@ private bool CreateBake(BakeType bakeType) UUID newAssetID = UUID.Zero; int retries = UPLOAD_RETRIES; - while (newAssetID == UUID.Zero && retries > 0) + while (newAssetID.IsZero() && retries > 0) { newAssetID = UploadBake(oven.BakedTexture.AssetData); --retries; @@ -1765,7 +1778,7 @@ private bool CreateBake(BakeType bakeType) Textures[(int)BakeTypeToAgentTextureIndex(bakeType)].TextureID = newAssetID; - if (newAssetID == UUID.Zero) + if (newAssetID.IsZero()) { Logger.Log("Failed uploading bake " + bakeType, Helpers.LogLevel.Warning); return false; @@ -2106,7 +2119,7 @@ public AgentSetAppearancePacket MakeAppearancePacket() hash ^= wearable.AssetID; } - if (hash != UUID.Zero) + if (hash.IsNotZero()) { // Hash with our magic value for this baked layer hash ^= BAKED_TEXTURE_HASH[bakedIndex]; From db2ed88df58ea1ab9b4ba5878fed58fd55909130 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Tue, 15 Mar 2022 16:56:16 +0000 Subject: [PATCH 038/149] a few more changes --- OpenMetaverse.StructuredData/JSON/JsonData.cs | 4 +- .../JSON/JsonWriter.cs | 1 + OpenMetaverse.StructuredData/JSON/OSDJson.cs | 133 +++++++++++++++++- .../LLSD/LLSDxmlEncode.cs | 2 +- OpenMetaverse.StructuredData/LLSD/XmlLLSD.cs | 4 +- .../StructuredData.cs | 4 +- OpenMetaverse/AssetManager.cs | 8 +- .../Assets/AssetTypes/AssetNotecard.cs | 2 +- OpenMetaverse/Assets/AssetTypes/AssetPrim.cs | 2 +- OpenMetaverse/GroupManager.cs | 2 +- OpenMetaverse/Inventory.cs | 4 +- OpenMetaverse/InventoryManager.cs | 8 +- OpenMetaverse/Primitives/TextureEntry.cs | 6 +- OpenMetaverse/TerrainCompressor.cs | 2 +- OpenMetaverse/TexturePipeline.cs | 2 +- OpenMetaverse/Voice/VoiceControl.cs | 2 +- OpenMetaverseTypes/OSUTF8Cached.cs | 22 ++- OpenMetaverseTypes/OSUTF8Constants.cs | 4 + OpenMetaverseTypes/Utils.cs | 2 +- OpenMetaverseTypes/UtilsConversions.cs | 18 +-- Programs/PrimWorkshop/frmBrowser.cs | 2 +- Programs/PrimWorkshop/frmPrimWorkshop.cs | 4 +- Programs/examples/TestClient/ClientManager.cs | 2 +- .../Commands/Appearance/WearCommand.cs | 2 +- .../Commands/Groups/JoinGroupCommand.cs | 2 +- .../Commands/Inventory/GiveAllCommand.cs | 2 +- .../Commands/Movement/TurnToCommand.cs | 5 +- Programs/importprimscript/importprimscript.cs | 4 +- 28 files changed, 199 insertions(+), 56 deletions(-) diff --git a/OpenMetaverse.StructuredData/JSON/JsonData.cs b/OpenMetaverse.StructuredData/JSON/JsonData.cs index ebd1dcd8..e2a8446e 100644 --- a/OpenMetaverse.StructuredData/JSON/JsonData.cs +++ b/OpenMetaverse.StructuredData/JSON/JsonData.cs @@ -491,11 +491,11 @@ public static explicit operator Int32(JsonData data) public static explicit operator Int64(JsonData data) { - if (data.type != JsonType.Long) + if (data.type != JsonType.Long && data.type != JsonType.Int) throw new InvalidCastException( "Instance of JsonData doesn't hold an int"); - return data.inst_long; + return (data.type == JsonType.Long) ? data.inst_long : data.inst_int; } public static explicit operator String(JsonData data) diff --git a/OpenMetaverse.StructuredData/JSON/JsonWriter.cs b/OpenMetaverse.StructuredData/JSON/JsonWriter.cs index ff2d785d..66a54200 100644 --- a/OpenMetaverse.StructuredData/JSON/JsonWriter.cs +++ b/OpenMetaverse.StructuredData/JSON/JsonWriter.cs @@ -226,6 +226,7 @@ private void PutString(string str) case '"': case '\\': + //case '/': writer.Write('\\'); writer.Write(c); break; diff --git a/OpenMetaverse.StructuredData/JSON/OSDJson.cs b/OpenMetaverse.StructuredData/JSON/OSDJson.cs index b66e3355..994aa1e28 100644 --- a/OpenMetaverse.StructuredData/JSON/OSDJson.cs +++ b/OpenMetaverse.StructuredData/JSON/OSDJson.cs @@ -177,7 +177,7 @@ private static JsonData SerializeJsonNoDefaults(OSD osd) return new JsonData(uuid.ToString()); case OSDType.Binary: byte[] binary = osd.AsBinary(); - if (binary == Utils.EmptyBytes) + if (binary.Length == 0) return null; JsonData jsonbinarray = new JsonData(); @@ -250,10 +250,13 @@ public static void SerializeJson(OSD osd, osUTF8 sb, bool preserveDefaults) break; case OSDType.String: case OSDType.URI: - case OSDType.OSDUTF8: case OSDType.LLSDxml: appendJsonString((OSDString)osd, sb); break; + case OSDType.OSDUTF8: + osUTF8 ou8 = ((OSDUTF8)osd).value; + appendJsonOSUTF8(ou8, sb); + break; case OSDType.UUID: sb.AppendASCII('"'); sb.AppendUUID(osd.AsUUID()); @@ -358,7 +361,6 @@ public static void SerializeJsonMapNoDefaults(string name, OSD osd, ref int mapc break; case OSDType.String: case OSDType.URI: - case OSDType.OSDUTF8: case OSDType.LLSDxml: OSDString ostr = (OSDString)osd; if (!string.IsNullOrEmpty(ostr.value)) @@ -370,6 +372,17 @@ public static void SerializeJsonMapNoDefaults(string name, OSD osd, ref int mapc appendJsonString(ostr.value, sb); } break; + case OSDType.OSDUTF8: + osUTF8 ou8 = ((OSDUTF8)osd).value; + if (ou8 != null && ou8.Length > 0) + { + if (mapcont++ > 0) + sb.AppendASCII(','); + appendJsonString(name, sb); + sb.AppendASCII(':'); + appendJsonOSUTF8(ou8, sb); + } + break; case OSDType.UUID: UUID ou = osd.AsUUID(); if(ou.IsNotZero()) @@ -382,7 +395,6 @@ public static void SerializeJsonMapNoDefaults(string name, OSD osd, ref int mapc sb.AppendASCII('"'); } break; - case OSDType.Date: if (mapcont++ > 0) sb.AppendASCII(','); @@ -406,7 +418,6 @@ public static void SerializeJsonMapNoDefaults(string name, OSD osd, ref int mapc } if (i < binary.Length) sb.AppendInt(binary[i]); - } sb.AppendASCII(']'); break; @@ -472,6 +483,7 @@ public static void appendJsonString(string str, osUTF8 sb) break; case '"': + //case '/': case '\\': sb.AppendASCII('\\'); sb.AppendASCII(c); @@ -502,5 +514,116 @@ public static void appendJsonString(string str, osUTF8 sb) } sb.AppendASCII('"'); } + + public static void appendJsonOSUTF8(osUTF8 str, osUTF8 sb) + { + int code; + sb.AppendASCII('"'); + for (int i = 0; i < str.Length; i++) + { + byte c = str[i]; + if (c < 0x80) + { + switch (c) + { + case (byte)'\n': + sb.AppendASCII("\\n"); + break; + + case (byte)'\r': + sb.AppendASCII("\\r"); + break; + + case (byte)'\t': + sb.AppendASCII("\\t"); + break; + + case (byte)'"': + case (byte)'/': + case (byte)'\\': + sb.AppendASCII('\\'); + sb.Append(c); + break; + + case (byte)'\f': + sb.AppendASCII("\\f"); + break; + + case (byte)'\b': + sb.AppendASCII("\\b"); + break; + + default: + // Default, turn into a \uXXXX sequence + if (c >= 32 && c <= 126) + sb.Append(c); + else + { + sb.AppendASCII("\\u00"); + sb.Append(Utils.NibbleToHexUpper((byte)(c >> 4))); + sb.Append(Utils.NibbleToHexUpper((byte)c)); + } + break; + } + } + if(c < 0xc0) + continue; // invalid + if (c < 0xe0) + { + // 2 bytes + if (i + 1 >= str.Length) + return; + + code = (c & 0x1f) << 6; + code |= str[++i] & 0x3f; + + sb.AppendASCII("\\u0"); + sb.Append(Utils.NibbleToHexUpper((byte)(code >> 8))); + sb.Append(Utils.NibbleToHexUpper((byte)(code >> 4))); + sb.Append(Utils.NibbleToHexUpper((byte)code)); + } + else if (c < 0xF0) + { + // 3 bytes + if (i + 2 >= str.Length) + return; + + // 1110aaaa 10bbbbcc 10ccdddd + sb.AppendASCII("\\u"); + sb.Append(Utils.NibbleToHexUpper(c)); + c = str[++i]; + sb.Append(Utils.NibbleToHexUpper((byte)(c >> 2))); + code = (c & 3) << 2; + c = str[++i]; + code |= (c & 0x30) >> 4; + sb.Append(Utils.NibbleToHexUpper((byte)code)); + sb.Append(Utils.NibbleToHexUpper(c)); + } + else if (c < 0xf8 ) + { + if (i + 3 >= str.Length) + return; + + code = (c & 0x07) << 18; + code |= (str[++i] & 0x3f) << 6; + code |= (str[++i] & 0x3f) << 6; + code |= str[++i] & 0x3f; + int a = (code >> 10) + 0xd7c0; + code &= (code & 0x3ff) + 0xdc00; + + sb.AppendASCII("\\u"); + sb.Append(Utils.NibbleToHexUpper((byte)(a >> 12))); + sb.Append(Utils.NibbleToHexUpper((byte)(a >> 8))); + sb.Append(Utils.NibbleToHexUpper((byte)(a >> 4))); + sb.Append(Utils.NibbleToHexUpper((byte)a)); + sb.AppendASCII("\\u"); + sb.Append(Utils.NibbleToHexUpper((byte)(code >> 12))); + sb.Append(Utils.NibbleToHexUpper((byte)(code >> 8))); + sb.Append(Utils.NibbleToHexUpper((byte)(code >> 4))); + sb.Append(Utils.NibbleToHexUpper((byte)code)); + } + } + sb.AppendASCII('"'); + } } } diff --git a/OpenMetaverse.StructuredData/LLSD/LLSDxmlEncode.cs b/OpenMetaverse.StructuredData/LLSD/LLSDxmlEncode.cs index 122c7480..d46bce14 100644 --- a/OpenMetaverse.StructuredData/LLSD/LLSDxmlEncode.cs +++ b/OpenMetaverse.StructuredData/LLSD/LLSDxmlEncode.cs @@ -49,7 +49,7 @@ public static void AddStart(osUTF8 sb, bool addxmlversion = false) sb.Append(osUTF8Const.XMLllsdStart); } - public static osUTF8 Start(int size = 4096, bool addxmlversion = false) + public static osUTF8 Start(int size = OSUTF8Cached.MAXDATASIZE, bool addxmlversion = false) { osUTF8 sb = OSUTF8Cached.Acquire(size); if(addxmlversion) diff --git a/OpenMetaverse.StructuredData/LLSD/XmlLLSD.cs b/OpenMetaverse.StructuredData/LLSD/XmlLLSD.cs index 8f7853e8..2942cb3d 100644 --- a/OpenMetaverse.StructuredData/LLSD/XmlLLSD.cs +++ b/OpenMetaverse.StructuredData/LLSD/XmlLLSD.cs @@ -720,7 +720,7 @@ private static OSD ParseLLSDXmlElement(XmlTextReader reader) if (reader.IsEmptyElement) { reader.Read(); - return OSD.FromBinary(Utils.EmptyBytes); + return OSD.FromBinary(Array.Empty()); } if (reader.GetAttribute("encoding") != null && reader.GetAttribute("encoding") != "base64") @@ -739,7 +739,7 @@ private static OSD ParseLLSDXmlElement(XmlTextReader reader) } } - ret = OSD.FromBinary(Utils.EmptyBytes); + ret = OSD.FromBinary(Array.Empty()); break; case "uri": if (reader.IsEmptyElement) diff --git a/OpenMetaverse.StructuredData/StructuredData.cs b/OpenMetaverse.StructuredData/StructuredData.cs index 7b3b4d9e..4cb55eef 100644 --- a/OpenMetaverse.StructuredData/StructuredData.cs +++ b/OpenMetaverse.StructuredData/StructuredData.cs @@ -546,7 +546,7 @@ public virtual byte[] AsBinary() case OSDType.LLSDxml: return Encoding.UTF8.GetBytes(((OSDllsdxml)this).value); default: - return Utils.EmptyBytes; + return Array.Empty(); } } @@ -1558,7 +1558,7 @@ public OSDBinary(byte[] value) if (value != null) this.value = value; else - this.value = Utils.EmptyBytes; + this.value = Array.Empty(); } public OSDBinary(uint value) diff --git a/OpenMetaverse/AssetManager.cs b/OpenMetaverse/AssetManager.cs index e7c62656..2d101b50 100644 --- a/OpenMetaverse/AssetManager.cs +++ b/OpenMetaverse/AssetManager.cs @@ -584,7 +584,7 @@ public void RequestAsset(UUID assetID, UUID itemID, UUID taskID, AssetType type, request.TransferInfo.SourceType = (int)transfer.Source; request.TransferInfo.TransferID = transfer.ID; - byte[] paramField = taskID == UUID.Zero ? new byte[20] : new byte[96]; + byte[] paramField = taskID.IsZero() ? new byte[20] : new byte[96]; Buffer.BlockCopy(assetID.GetBytes(), 0, paramField, 0, 16); Buffer.BlockCopy(Utils.IntToBytes((int)type), 0, paramField, 16, 4); @@ -1108,7 +1108,7 @@ public void RequestImageCancel(UUID textureID) /// Callback when the request completes public void RequestMesh(UUID meshID, MeshDownloadCallback callback) { - if (meshID == UUID.Zero || callback == null) + if (meshID.IsZero() || callback == null) return; if (Client.Network.CurrentSim.Caps != null && @@ -1165,7 +1165,7 @@ public void RequestMesh(UUID meshID, MeshDownloadCallback callback) /// Callback invoked on operation completion public void RequestServerBakedImage(UUID avatarID, UUID textureID, string bakeName, TextureDownloadCallback callback) { - if (avatarID == UUID.Zero || textureID == UUID.Zero || callback == null) + if (avatarID.IsZero() || textureID.IsZero() || callback == null) return; if (string.IsNullOrEmpty(Client.Network.AgentAppearanceServiceURL)) @@ -1256,7 +1256,7 @@ internal void FireImageProgressEvent(UUID texureID, int transferredBytes, int to private void HttpRequestTexture(UUID textureID, ImageType imageType, float priority, int discardLevel, uint packetStart, TextureDownloadCallback callback, bool progress) { - if (textureID == UUID.Zero || callback == null) + if (textureID.IsZero() || callback == null) return; byte[] assetData; diff --git a/OpenMetaverse/Assets/AssetTypes/AssetNotecard.cs b/OpenMetaverse/Assets/AssetTypes/AssetNotecard.cs index 5beb991d..7bd77c79 100644 --- a/OpenMetaverse/Assets/AssetTypes/AssetNotecard.cs +++ b/OpenMetaverse/Assets/AssetTypes/AssetNotecard.cs @@ -112,7 +112,7 @@ public override void Encode() output.Append("\t}\n"); if (Permissions.HasPermissions(item.Permissions.BaseMask, PermissionMask.Modify | PermissionMask.Copy | PermissionMask.Transfer) || - item.AssetUUID == UUID.Zero) + item.AssetUUID.IsZero()) { output.Append("\t\tasset_id\t" + item.AssetUUID + "\n"); } diff --git a/OpenMetaverse/Assets/AssetTypes/AssetPrim.cs b/OpenMetaverse/Assets/AssetTypes/AssetPrim.cs index 98bc2596..21eec9c0 100644 --- a/OpenMetaverse/Assets/AssetTypes/AssetPrim.cs +++ b/OpenMetaverse/Assets/AssetTypes/AssetPrim.cs @@ -131,7 +131,7 @@ public bool DecodeXml(string xmlData) if (Parent != null) { - if (this.AssetID == UUID.Zero) + if (this.AssetID.IsZero()) this.AssetID = Parent.ID; List children = new List(); diff --git a/OpenMetaverse/GroupManager.cs b/OpenMetaverse/GroupManager.cs index 571d4a58..edfe6fde 100644 --- a/OpenMetaverse/GroupManager.cs +++ b/OpenMetaverse/GroupManager.cs @@ -247,7 +247,7 @@ public struct GroupNotice /// public byte[] SerializeAttachment() { - if (OwnerID == UUID.Zero || AttachmentID == UUID.Zero) + if (OwnerID.IsZero() || AttachmentID.IsZero()) return Utils.EmptyBytes; OpenMetaverse.StructuredData.OSDMap att = new OpenMetaverse.StructuredData.OSDMap(); diff --git a/OpenMetaverse/Inventory.cs b/OpenMetaverse/Inventory.cs index ac3cdc88..ac408636 100644 --- a/OpenMetaverse/Inventory.cs +++ b/OpenMetaverse/Inventory.cs @@ -187,7 +187,7 @@ public Inventory(GridClient client, InventoryManager manager, UUID owner) Client = client; //Manager = manager; _Owner = owner; - if (owner == UUID.Zero) + if (owner.IsZero()) Logger.Log("Inventory owned by nobody!", Helpers.LogLevel.Warning, Client); Items = new Dictionary(); } @@ -423,7 +423,7 @@ public int RestoreFromDisk(string filename) foreach (InventoryNode node in nodes) { InventoryNode pnode; - if (node.ParentID == UUID.Zero) + if (node.ParentID.IsZero()) { //We don't need the root nodes "My Inventory" etc as they will already exist for the correct // user of this cache. diff --git a/OpenMetaverse/InventoryManager.cs b/OpenMetaverse/InventoryManager.cs index 5135cd49..972be61e 100644 --- a/OpenMetaverse/InventoryManager.cs +++ b/OpenMetaverse/InventoryManager.cs @@ -141,7 +141,7 @@ public abstract class InventoryBase : ISerializable /// The of the item public InventoryBase(UUID itemID) { - if (itemID == UUID.Zero) + if (itemID.IsZero()) Logger.Log("Initializing an InventoryBase with UUID.Zero", Helpers.LogLevel.Warning); UUID = itemID; } @@ -4597,7 +4597,7 @@ protected void UpdateCreateInventoryItemHandler(object sender, PacketReceivedEve * to the client to make sure that the item gets a good folder, otherwise * it will end up inaccesible in inventory. */ - if (item.ParentUUID == UUID.Zero) + if (item.ParentUUID.IsZero()) { // assign default folder for type item.ParentUUID = FindFolderForType(item.AssetType); @@ -4669,7 +4669,7 @@ protected void BulkUpdateInventoryCapHandler(string capsKey, Interfaces.IMessage foreach (BulkUpdateInventoryMessage.FolderDataInfo newFolder in msg.FolderData) { - if (newFolder.FolderID == UUID.Zero) continue; + if (newFolder.FolderID.IsZero()) continue; InventoryFolder folder; if (!_Store.Contains(newFolder.FolderID)) @@ -4689,7 +4689,7 @@ protected void BulkUpdateInventoryCapHandler(string capsKey, Interfaces.IMessage foreach (BulkUpdateInventoryMessage.ItemDataInfo newItem in msg.ItemData) { - if (newItem.ItemID == UUID.Zero) continue; + if (newItem.ItemID.IsZero()) continue; InventoryType invType = newItem.InvType; lock (_ItemInventoryTypeRequest) diff --git a/OpenMetaverse/Primitives/TextureEntry.cs b/OpenMetaverse/Primitives/TextureEntry.cs index ef741981..1d4ce9d7 100644 --- a/OpenMetaverse/Primitives/TextureEntry.cs +++ b/OpenMetaverse/Primitives/TextureEntry.cs @@ -1138,7 +1138,7 @@ private void FromBytes(byte[] data, int pos, int length) public byte[] GetBytes(int maxfaces = MAX_FACES) { if (DefaultTexture == null) - return Utils.EmptyBytes; + return Array.Empty(); using (MemoryStream ms = new MemoryStream(4096)) { @@ -1623,9 +1623,9 @@ public byte[] GetBytes(int maxfaces = MAX_FACES) public byte[] GetBakesBytes(int maxfaces = MAX_FACES) { if (DefaultTexture == null) - return Utils.EmptyBytes; + return Array.Empty(); - if(maxfaces > FaceTextures.Length) + if (maxfaces > FaceTextures.Length) maxfaces = FaceTextures.Length; int[] bakedIndexes = (maxfaces > 21) ? AllBakedIndexes : LegacyBakedIndexes; diff --git a/OpenMetaverse/TerrainCompressor.cs b/OpenMetaverse/TerrainCompressor.cs index 13d50bff..e9f98598 100644 --- a/OpenMetaverse/TerrainCompressor.cs +++ b/OpenMetaverse/TerrainCompressor.cs @@ -39,7 +39,7 @@ public enum LayerType : byte Land = 0x4C, // 'L' LandExtended = 0x4D, // 'M' Water = 0x57, // 'W' - WaterExtended = 0x57, // 'X' + WaterExtended = 0x58, // 'X' Wind = 0x37, // '7' WindExtended = 0x39, // '9' Cloud = 0x38, // '8' diff --git a/OpenMetaverse/TexturePipeline.cs b/OpenMetaverse/TexturePipeline.cs index e11c2af7..62d68a33 100644 --- a/OpenMetaverse/TexturePipeline.cs +++ b/OpenMetaverse/TexturePipeline.cs @@ -291,7 +291,7 @@ private void RefreshDownloadsTimer_Elapsed(object sender, System.Timers.ElapsedE /// from the beginning of the request public void RequestTexture(UUID textureID, ImageType imageType, float priority, int discardLevel, uint packetStart, TextureDownloadCallback callback, bool progressive) { - if (textureID == UUID.Zero) + if (textureID.IsZero()) return; if (callback != null) diff --git a/OpenMetaverse/Voice/VoiceControl.cs b/OpenMetaverse/Voice/VoiceControl.cs index 492eb37c..6ffd5e78 100644 --- a/OpenMetaverse/Voice/VoiceControl.cs +++ b/OpenMetaverse/Voice/VoiceControl.cs @@ -412,7 +412,7 @@ private static string nameFromID(UUID id) { string result = null; - if (id == UUID.Zero) + if (id.IsZero()) return result; // Prepending this apparently prevents conflicts with reserved names inside the vivox and diamondware code. diff --git a/OpenMetaverseTypes/OSUTF8Cached.cs b/OpenMetaverseTypes/OSUTF8Cached.cs index 4b8cb436..25207f1e 100644 --- a/OpenMetaverseTypes/OSUTF8Cached.cs +++ b/OpenMetaverseTypes/OSUTF8Cached.cs @@ -39,9 +39,9 @@ namespace OpenMetaverse { public static class OSUTF8Cached { - const int MAXSIZE = 128; // 8MB + const int MAXSIZE = 128; // 16MB const int PREALLOC = 128; - const int MAXDATASIZE = 64 * 1024; + public const int MAXDATASIZE = 128 * 1024; private static readonly osUTF8[] m_pool = new osUTF8[MAXSIZE]; private static readonly object m_poollock = new object(); @@ -123,5 +123,23 @@ public static byte[] GetArrayAndRelease(osUTF8 os) } return result; } + + public static string GetStringAndRelease(osUTF8 os) + { + string ret = os.ToString(); + if (os.m_data.Length == MAXDATASIZE) + { + lock (m_poollock) + { + if (m_poolPtr < MAXSIZE - 1) + { + os.Clear(); + m_poolPtr++; + m_pool[m_poolPtr] = os; + } + } + } + return ret; + } } } diff --git a/OpenMetaverseTypes/OSUTF8Constants.cs b/OpenMetaverseTypes/OSUTF8Constants.cs index 7b4a0f57..5840a8f8 100644 --- a/OpenMetaverseTypes/OSUTF8Constants.cs +++ b/OpenMetaverseTypes/OSUTF8Constants.cs @@ -130,6 +130,10 @@ public static class osUTF8Const public static readonly byte[] XMLelement_sale_info_Mid = osUTF8.GetASCIIBytes("sale_type"); public static readonly byte[] XMLelement_sale_info_End = osUTF8.GetASCIIBytes(""); + public static readonly byte[] OSUTF8null = osUTF8.GetASCIIBytes("null"); + public static readonly byte[] OSUTF8true = osUTF8.GetASCIIBytes("true"); + public static readonly byte[] OSUTF8false = osUTF8.GetASCIIBytes("false"); + public static readonly byte[] base64Bytes = {(byte)'A',(byte)'B',(byte)'C',(byte)'D',(byte)'E',(byte)'F',(byte)'G',(byte)'H',(byte)'I',(byte)'J',(byte)'K',(byte)'L',(byte)'M',(byte)'N',(byte)'O', (byte)'P',(byte)'Q',(byte)'R',(byte)'S',(byte)'T',(byte)'U',(byte)'V',(byte)'W',(byte)'X',(byte)'Y',(byte)'Z',(byte)'a',(byte)'b',(byte)'c',(byte)'d', (byte)'e',(byte)'f',(byte)'g',(byte)'h',(byte)'i',(byte)'j',(byte)'k',(byte)'l',(byte)'m',(byte)'n',(byte)'o',(byte)'p',(byte)'q',(byte)'r',(byte)'s', diff --git a/OpenMetaverseTypes/Utils.cs b/OpenMetaverseTypes/Utils.cs index 8ebb141e..e1dbcdf6 100644 --- a/OpenMetaverseTypes/Utils.cs +++ b/OpenMetaverseTypes/Utils.cs @@ -83,7 +83,7 @@ public enum Runtime /// UNIX epoch in DateTime format public static readonly DateTime Epoch = new DateTime(1970, 1, 1); - public static readonly byte[] EmptyBytes = new byte[0]; + public static readonly byte[] EmptyBytes = Array.Empty(); /// Provide a single instance of the MD5 class to avoid making /// duplicate copies and handle thread safety diff --git a/OpenMetaverseTypes/UtilsConversions.cs b/OpenMetaverseTypes/UtilsConversions.cs index f5797548..dfd73f75 100644 --- a/OpenMetaverseTypes/UtilsConversions.cs +++ b/OpenMetaverseTypes/UtilsConversions.cs @@ -1495,11 +1495,11 @@ public static string BytesToHexString(byte[] bytes, int length, string fieldName public static byte[] StringToBytes(string str) { if (string.IsNullOrEmpty(str)) - return EmptyBytes; + return Array.Empty(); int nbytes = osUTF8GetBytesCount(str, out int sourcelen); if (nbytes == 0) - return EmptyBytes; + return Array.Empty(); ; byte[] dstarray = new byte[nbytes + 1]; osUTF8Getbytes(str, sourcelen, dstarray, nbytes); dstarray[nbytes] = 0; @@ -1509,11 +1509,11 @@ public static byte[] StringToBytes(string str) public static byte[] StringToBytes(string str, int maxlen) { if (string.IsNullOrEmpty(str)) - return EmptyBytes; + return Array.Empty(); int nbytes = osUTF8GetBytesCount(str, maxlen -1, out int sourcelen); if (nbytes == 0) - return EmptyBytes; + return Array.Empty(); byte[] dstarray = new byte[nbytes + 1]; osUTF8Getbytes(str, sourcelen, dstarray, nbytes); dstarray[nbytes] = 0; @@ -1523,11 +1523,11 @@ public static byte[] StringToBytes(string str, int maxlen) public static byte[] StringToBytesNoTerm(string str) { if (string.IsNullOrEmpty(str)) - return EmptyBytes; + return Array.Empty(); int nbytes = osUTF8GetBytesCount(str, out int sourcelen); if (nbytes == 0) - return EmptyBytes; + return Array.Empty(); byte[] dstarray = new byte[nbytes]; osUTF8Getbytes(str, sourcelen, dstarray, nbytes); return dstarray; @@ -1536,11 +1536,11 @@ public static byte[] StringToBytesNoTerm(string str) public static byte[] StringToBytesNoTerm(string str, int maxlen) { if (string.IsNullOrEmpty(str)) - return EmptyBytes; + return Array.Empty(); int nbytes = osUTF8GetBytesCount(str, maxlen, out int sourcelen); if (nbytes == 0) - return EmptyBytes; + return Array.Empty(); byte[] dstarray = new byte[nbytes]; osUTF8Getbytes(str, sourcelen, dstarray, nbytes); return dstarray; @@ -1830,7 +1830,7 @@ public static byte[] HexStringToBytes(string hexString, bool handleDirty) if (handleDirty) { if (String.IsNullOrEmpty(hexString)) - return Utils.EmptyBytes; + return Array.Empty(); StringBuilder stripped = new StringBuilder(hexString.Length); char c; diff --git a/Programs/PrimWorkshop/frmBrowser.cs b/Programs/PrimWorkshop/frmBrowser.cs index 5218707f..12fc4ac7 100644 --- a/Programs/PrimWorkshop/frmBrowser.cs +++ b/Programs/PrimWorkshop/frmBrowser.cs @@ -1327,7 +1327,7 @@ private void RenderPrims() else { if (face.TextureFace.TextureID == Primitive.TextureEntry.WHITE_TEXTURE || - face.TextureFace.TextureID == UUID.Zero) + face.TextureFace.TextureID.IsZero()) { Gl.glPolygonMode(Gl.GL_FRONT, Gl.GL_FILL); } diff --git a/Programs/PrimWorkshop/frmPrimWorkshop.cs b/Programs/PrimWorkshop/frmPrimWorkshop.cs index 33107d82..39b32f7e 100644 --- a/Programs/PrimWorkshop/frmPrimWorkshop.cs +++ b/Programs/PrimWorkshop/frmPrimWorkshop.cs @@ -277,7 +277,7 @@ private void XmlObjectLoadedHandler(OpenMetaverse.Assets.AssetPrim linkset, long { FacetedMesh mesh = null; - if (parent.Sculpt == null || parent.Sculpt.SculptTexture == UUID.Zero) + if (parent.Sculpt == null || parent.Sculpt.SculptTexture.IsZero()) mesh = Render.Plugin.GenerateFacetedMesh(parent, DetailLevel.Highest); if (mesh != null) LoadMesh(mesh, null); @@ -288,7 +288,7 @@ private void XmlObjectLoadedHandler(OpenMetaverse.Assets.AssetPrim linkset, long Primitive child = linkset.Children[i].ToPrimitive(); FacetedMesh mesh = null; - if (parent.Sculpt == null || child.Sculpt.SculptTexture == UUID.Zero) + if (parent.Sculpt == null || child.Sculpt.SculptTexture.IsZero()) mesh = Render.Plugin.GenerateFacetedMesh(child, DetailLevel.Highest); if (mesh != null) LoadMesh(mesh, null); diff --git a/Programs/examples/TestClient/ClientManager.cs b/Programs/examples/TestClient/ClientManager.cs index 6382cf17..d4688b69 100644 --- a/Programs/examples/TestClient/ClientManager.cs +++ b/Programs/examples/TestClient/ClientManager.cs @@ -137,7 +137,7 @@ public TestClient Login(LoginDetails account) { Clients[client.Self.AgentID] = client; - if (client.MasterKey == UUID.Zero) + if (client.MasterKey.IsZero()) { UUID query = UUID.Zero; EventHandler peopleDirCallback = diff --git a/Programs/examples/TestClient/Commands/Appearance/WearCommand.cs b/Programs/examples/TestClient/Commands/Appearance/WearCommand.cs index 604340e1..b565d9e3 100644 --- a/Programs/examples/TestClient/Commands/Appearance/WearCommand.cs +++ b/Programs/examples/TestClient/Commands/Appearance/WearCommand.cs @@ -30,7 +30,7 @@ public override string Execute(string[] args, UUID fromAgentID) UUID folder = Client.Inventory.FindObjectByPath(Client.Inventory.Store.RootFolder.UUID, Client.Self.AgentID, target, 20 * 1000); - if (folder == UUID.Zero) + if (folder.IsZero()) { return "Outfit path " + target + " not found"; } diff --git a/Programs/examples/TestClient/Commands/Groups/JoinGroupCommand.cs b/Programs/examples/TestClient/Commands/Groups/JoinGroupCommand.cs index b83e2fd8..510e5a02 100644 --- a/Programs/examples/TestClient/Commands/Groups/JoinGroupCommand.cs +++ b/Programs/examples/TestClient/Commands/Groups/JoinGroupCommand.cs @@ -57,7 +57,7 @@ public override string Execute(string[] args, UUID fromAgentID) GetGroupsSearchEvent.Reset(); } - if (resolvedGroupID == UUID.Zero) + if (resolvedGroupID.IsZero()) { if (string.IsNullOrEmpty(resolvedGroupName)) return "Unable to obtain UUID for group " + groupName; diff --git a/Programs/examples/TestClient/Commands/Inventory/GiveAllCommand.cs b/Programs/examples/TestClient/Commands/Inventory/GiveAllCommand.cs index f930eee3..a9c35ec0 100644 --- a/Programs/examples/TestClient/Commands/Inventory/GiveAllCommand.cs +++ b/Programs/examples/TestClient/Commands/Inventory/GiveAllCommand.cs @@ -17,7 +17,7 @@ public GiveAllCommand(TestClient testClient) public override string Execute(string[] args, UUID fromAgentID) { - if (fromAgentID == UUID.Zero) + if (fromAgentID.IsZero()) return "Unable to send money to console. This command only works when IMed."; int amount = Client.Self.Balance; diff --git a/Programs/examples/TestClient/Commands/Movement/TurnToCommand.cs b/Programs/examples/TestClient/Commands/Movement/TurnToCommand.cs index f6bead5f..6c9d3add 100644 --- a/Programs/examples/TestClient/Commands/Movement/TurnToCommand.cs +++ b/Programs/examples/TestClient/Commands/Movement/TurnToCommand.cs @@ -46,10 +46,7 @@ public override string Execute(string[] args, UUID fromAgentID) return "Usage: turnto x y z"; } - Vector3 newDirection; - newDirection.X = (float)x; - newDirection.Y = (float)y; - newDirection.Z = (float)z; + Vector3 newDirection = new Vector3((float)x, (float)y, (float)z); Client.Self.Movement.TurnToward(newDirection); Client.Self.Movement.SendUpdate(false); return "Turned to "; diff --git a/Programs/importprimscript/importprimscript.cs b/Programs/importprimscript/importprimscript.cs index b7d34391..5f2f6bbb 100644 --- a/Programs/importprimscript/importprimscript.cs +++ b/Programs/importprimscript/importprimscript.cs @@ -143,12 +143,12 @@ static void Main(string[] args) sculpties[i].TextureID = UploadImage(sculpties[i].TextureFile, false); // Check for failed uploads - if (sculpties[i].SculptID == UUID.Zero) + if (sculpties[i].SculptID.IsZero()) { Console.WriteLine("Sculpt map " + sculpties[i].SculptFile + " failed to upload, skipping " + sculpties[i].Name); continue; } - else if (sculpties[i].TextureID == UUID.Zero) + else if (sculpties[i].TextureID.IsZero()) { Console.WriteLine("Texture " + sculpties[i].TextureFile + " failed to upload, skipping " + sculpties[i].Name); continue; From 0f13ab6a87b2241eec222e68372d261d27284a3d Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Sat, 19 Mar 2022 13:53:41 +0000 Subject: [PATCH 039/149] add missing reference to prebuild.xml --- prebuild.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/prebuild.xml b/prebuild.xml index 46f6caf8..5860f74e 100644 --- a/prebuild.xml +++ b/prebuild.xml @@ -74,6 +74,8 @@ ../bin/ + + From 20ccc6b584849e2c320aa079bfa8ea51541e3d2a Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Sun, 20 Mar 2022 16:16:16 +0000 Subject: [PATCH 040/149] change UUID parsing from osUTF8 and string --- OpenMetaverseTypes/OSUTF8.cs | 104 +++++++- OpenMetaverseTypes/OSUTF8Slice.cs | 158 ++++++------ OpenMetaverseTypes/UUID.cs | 323 ++++++++++++++++++++++++- OpenMetaverseTypes/Utils.cs | 6 +- OpenMetaverseTypes/UtilsConversions.cs | 192 +++++++++------ OpenMetaverseTypes/Vector2.cs | 8 + OpenMetaverseTypes/Vector3.cs | 17 ++ OpenMetaverseTypes/Vector3d.cs | 8 + OpenMetaverseTypes/Vector4.cs | 9 + 9 files changed, 663 insertions(+), 162 deletions(-) diff --git a/OpenMetaverseTypes/OSUTF8.cs b/OpenMetaverseTypes/OSUTF8.cs index cf1427af..e5e6f19c 100644 --- a/OpenMetaverseTypes/OSUTF8.cs +++ b/OpenMetaverseTypes/OSUTF8.cs @@ -959,10 +959,108 @@ public static bool TryParseInt(osUTF8 t, out int res) return osUTF8Slice.TryParseInt(new osUTF8Slice(t), out res); } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool TryParseUUID(osUTF8 inp, out UUID res, bool dashs = true) + public unsafe static bool TryParseUUID(osUTF8 inp, out UUID result) { - return osUTF8Slice.TryParseUUID(new osUTF8Slice(inp), out res, dashs); + result = new UUID(); + if (inp.m_len == 0) + return false; + + try + { + fixed (byte* bval = inp.m_data) + { + byte* val = bval; + + while (*val == ' ') ++val; + if (val[8] == '-') + { + if (val[13] != '-' || val[18] != '-' || val[23] != '-') + return false; + + if (BitConverter.IsLittleEndian) + { + result.bytea3 = (byte)Utils.HexToByte(val, 0); + result.bytea2 = (byte)Utils.HexToByte(val, 2); + result.bytea1 = (byte)Utils.HexToByte(val, 4); + result.bytea0 = (byte)Utils.HexToByte(val, 6); + + result.byteb1 = (byte)Utils.HexToByte(val, 9); + result.byteb0 = (byte)Utils.HexToByte(val, 11); + + result.bytec1 = (byte)Utils.HexToByte(val, 14); + result.bytec0 = (byte)Utils.HexToByte(val, 16); + } + else + { + result.bytea0 = (byte)Utils.HexToByte(val, 0); + result.bytea1 = (byte)Utils.HexToByte(val, 2); + result.bytea2 = (byte)Utils.HexToByte(val, 4); + result.bytea3 = (byte)Utils.HexToByte(val, 6); + + result.byteb0 = (byte)Utils.HexToByte(val, 9); + result.byteb1 = (byte)Utils.HexToByte(val, 11); + + result.bytec0 = (byte)Utils.HexToByte(val, 14); + result.bytec1 = (byte)Utils.HexToByte(val, 16); + } + + result.d = (byte)Utils.HexToByte(val, 19); + result.e = (byte)Utils.HexToByte(val, 21); + + + result.f = (byte)Utils.HexToByte(val, 24); + result.g = (byte)Utils.HexToByte(val, 26); + result.h = (byte)Utils.HexToByte(val, 28); + result.i = (byte)Utils.HexToByte(val, 30); + result.j = (byte)Utils.HexToByte(val, 32); + result.k = (byte)Utils.HexToByte(val, 34); + return true; + } + else + { + if (BitConverter.IsLittleEndian) + { + result.bytea3 = Utils.HexToByte(val, 0); + result.bytea2 = Utils.HexToByte(val, 2); + result.bytea1 = Utils.HexToByte(val, 4); + result.bytea0 = Utils.HexToByte(val, 6); + + result.byteb1 = Utils.HexToByte(val, 8); + result.byteb0 = Utils.HexToByte(val, 10); + + result.bytec1 = Utils.HexToByte(val, 12); + result.bytec0 = Utils.HexToByte(val, 14); + } + else + { + result.bytea0 = Utils.HexToByte(val, 0); + result.bytea1 = Utils.HexToByte(val, 2); + result.bytea2 = Utils.HexToByte(val, 4); + result.bytea3 = Utils.HexToByte(val, 6); + + result.byteb0 = Utils.HexToByte(val, 8); + result.byteb1 = Utils.HexToByte(val, 10); + + result.bytec0 = Utils.HexToByte(val, 12); + result.bytec1 = Utils.HexToByte(val, 14); + } + + result.d = Utils.HexToByte(val, 16); + result.e = Utils.HexToByte(val, 18); + + result.f = Utils.HexToByte(val, 20); + result.g = Utils.HexToByte(val, 22); + result.h = Utils.HexToByte(val, 24); + result.i = Utils.HexToByte(val, 26); + result.j = Utils.HexToByte(val, 28); + result.k = Utils.HexToByte(val, 30); + return true; + } + } + } + catch { } + result = new UUID(); + return false; } [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/OpenMetaverseTypes/OSUTF8Slice.cs b/OpenMetaverseTypes/OSUTF8Slice.cs index af9473e3..f29dfeef 100644 --- a/OpenMetaverseTypes/OSUTF8Slice.cs +++ b/OpenMetaverseTypes/OSUTF8Slice.cs @@ -1655,96 +1655,108 @@ public static bool TryParseInt(osUTF8Slice t, out int res) return false; } - public static bool TryParseUUID(osUTF8Slice inp, out UUID res, bool dashs = true) + public unsafe static bool TryParseUUID(osUTF8Slice inp, out UUID result) { - res = new UUID(); - osUTF8Slice t = new osUTF8Slice(inp); - - t.SelfTrim(); - int len = t.m_len; - if (len == 0) + result = new UUID(); + if (inp.m_len == 0) return false; - if (dashs) - { - if (len < 36) - return false; - } - else + try { - if (len < 32) - return false; - } + fixed (byte* bval = &inp.m_data[inp.m_offset]) + { + byte* val = bval; - byte[] data = t.m_data; - int dataoffset = t.m_offset; + while (*val == ' ') ++val; + if (val[8] == '-') + { + if (val[13] != '-' || val[18] != '-' || val[23] != '-') + return false; - UUID utmp = new UUID(); - if (!Utils.TryHexToInt(data, dataoffset, 8, out utmp.a)) - return false; - dataoffset += 8; + if (BitConverter.IsLittleEndian) + { + result.bytea3 = (byte)Utils.HexToByte(val, 0); + result.bytea2 = (byte)Utils.HexToByte(val, 2); + result.bytea1 = (byte)Utils.HexToByte(val, 4); + result.bytea0 = (byte)Utils.HexToByte(val, 6); - if (dashs) - { - if (data[dataoffset] != (byte)'-') - return false; - ++dataoffset; - } + result.byteb1 = (byte)Utils.HexToByte(val, 9); + result.byteb0 = (byte)Utils.HexToByte(val, 11); - int n; - if (!Utils.TryHexToInt(data, dataoffset, 4, out n)) - return false; - utmp.b = (short)n; - dataoffset += 4; + result.bytec1 = (byte)Utils.HexToByte(val, 14); + result.bytec0 = (byte)Utils.HexToByte(val, 16); + } + else + { + result.bytea0 = (byte)Utils.HexToByte(val, 0); + result.bytea1 = (byte)Utils.HexToByte(val, 2); + result.bytea2 = (byte)Utils.HexToByte(val, 4); + result.bytea3 = (byte)Utils.HexToByte(val, 6); - if (dashs) - { - if (data[dataoffset] != (byte)'-') - return false; - ++dataoffset; - } + result.byteb0 = (byte)Utils.HexToByte(val, 9); + result.byteb1 = (byte)Utils.HexToByte(val, 11); - if (!Utils.TryHexToInt(data, dataoffset, 4, out n)) - return false; - utmp.c = (short)n; - dataoffset += 4; + result.bytec0 = (byte)Utils.HexToByte(val, 14); + result.bytec1 = (byte)Utils.HexToByte(val, 16); + } - if (dashs) - { - if (data[dataoffset] != (byte)'-') - return false; - ++dataoffset; - } + result.d = (byte)Utils.HexToByte(val, 19); + result.e = (byte)Utils.HexToByte(val, 21); - if (!Utils.TryHexToInt(data, dataoffset, 4, out n)) - return false; - utmp.d = (byte)(n >> 8); - utmp.e = (byte)n; - dataoffset += 4; + result.f = (byte)Utils.HexToByte(val, 24); + result.g = (byte)Utils.HexToByte(val, 26); + result.h = (byte)Utils.HexToByte(val, 28); + result.i = (byte)Utils.HexToByte(val, 30); + result.j = (byte)Utils.HexToByte(val, 32); + result.k = (byte)Utils.HexToByte(val, 34); + return true; + } + else + { + if (BitConverter.IsLittleEndian) + { + result.bytea3 = Utils.HexToByte(val, 0); + result.bytea2 = Utils.HexToByte(val, 2); + result.bytea1 = Utils.HexToByte(val, 4); + result.bytea0 = Utils.HexToByte(val, 6); - if (dashs) - { - if (data[dataoffset] != (byte)'-') - return false; - ++dataoffset; - } + result.byteb1 = Utils.HexToByte(val, 8); + result.byteb0 = Utils.HexToByte(val, 10); - if (!Utils.TryHexToInt(data, dataoffset, 8, out n)) - return false; - utmp.f = (byte)(n >> 24); - utmp.g = (byte)(n >> 16); - utmp.h = (byte)(n >> 8); - utmp.i = (byte)n; - dataoffset += 8; + result.bytec1 = Utils.HexToByte(val, 12); + result.bytec0 = Utils.HexToByte(val, 14); + } + else + { + result.bytea0 = Utils.HexToByte(val, 0); + result.bytea1 = Utils.HexToByte(val, 2); + result.bytea2 = Utils.HexToByte(val, 4); + result.bytea3 = Utils.HexToByte(val, 6); - if (!Utils.TryHexToInt(data, dataoffset, 4, out n)) - return false; - utmp.j = (byte)(n >> 8); - utmp.k = (byte)n; + result.byteb0 = Utils.HexToByte(val, 8); + result.byteb1 = Utils.HexToByte(val, 10); - res = utmp; - return true; + result.bytec0 = Utils.HexToByte(val, 12); + result.bytec1 = Utils.HexToByte(val, 14); + } + + result.d = Utils.HexToByte(val, 16); + result.e = Utils.HexToByte(val, 18); + + result.f = Utils.HexToByte(val, 20); + result.g = Utils.HexToByte(val, 22); + result.h = Utils.HexToByte(val, 24); + result.i = Utils.HexToByte(val, 26); + result.j = Utils.HexToByte(val, 28); + result.k = Utils.HexToByte(val, 30); + return true; + } + } + } + catch { } + result = new UUID(); + return false; } } } diff --git a/OpenMetaverseTypes/UUID.cs b/OpenMetaverseTypes/UUID.cs index 26de61b9..6fe7d367 100644 --- a/OpenMetaverseTypes/UUID.cs +++ b/OpenMetaverseTypes/UUID.cs @@ -83,6 +83,7 @@ public struct UUID : IComparable,IComparable, IEquatable /// A string representation of a UUID, case /// insensitive and can either be hyphenated or non-hyphenated /// UUID("11f8aa9c-b071-4242-836b-13b7abe0d489") + /* [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe UUID(string val) { @@ -92,7 +93,7 @@ public unsafe UUID(string val) { if (Guid.TryParse(val, out Guid gg)) { - this = *(UUID *) ≫ + this = *(UUID*)≫ return; } } @@ -100,6 +101,112 @@ public unsafe UUID(string val) } this = new UUID(); } + */ + + public unsafe UUID(string sval) + { + this = new UUID(); + if (string.IsNullOrEmpty(sval)) + throw new System.FormatException("Invalid UUID"); + + try + { + fixed (char* bval = sval) + { + char *val = bval; + while (*val == ' ') ++val; + + if (val[8] == '-') + { + if (val[13] != '-' || val[18] != '-' || val[23] != '-') + throw new Exception(); + + if (BitConverter.IsLittleEndian) + { + bytea3 = (byte)Utils.HexToByte(val, 0); + bytea2 = (byte)Utils.HexToByte(val, 2); + bytea1 = (byte)Utils.HexToByte(val, 4); + bytea0 = (byte)Utils.HexToByte(val, 6); + + byteb1 = (byte)Utils.HexToByte(val, 9); + byteb0 = (byte)Utils.HexToByte(val, 11); + + bytec1 = (byte)Utils.HexToByte(val, 14); + bytec0 = (byte)Utils.HexToByte(val, 16); + } + else + { + bytea0 = (byte)Utils.HexToByte(val, 0); + bytea1 = (byte)Utils.HexToByte(val, 2); + bytea2 = (byte)Utils.HexToByte(val, 4); + bytea3 = (byte)Utils.HexToByte(val, 6); + + byteb0 = (byte)Utils.HexToByte(val, 9); + byteb1 = (byte)Utils.HexToByte(val, 11); + + bytec0 = (byte)Utils.HexToByte(val, 14); + bytec1 = (byte)Utils.HexToByte(val, 16); + } + + + d = (byte)Utils.HexToByte(val, 19); + e = (byte)Utils.HexToByte(val, 21); + + + f = (byte)Utils.HexToByte(val, 24); + g = (byte)Utils.HexToByte(val, 26); + h = (byte)Utils.HexToByte(val, 28); + i = (byte)Utils.HexToByte(val, 30); + j = (byte)Utils.HexToByte(val, 32); + k = (byte)Utils.HexToByte(val, 34); + return; + } + else + { + if (BitConverter.IsLittleEndian) + { + bytea3 = Utils.HexToByte(val, 0); + bytea2 = Utils.HexToByte(val, 2); + bytea1 = Utils.HexToByte(val, 4); + bytea0 = Utils.HexToByte(val, 6); + + byteb1 = Utils.HexToByte(val, 8); + byteb0 = Utils.HexToByte(val, 10); + + bytec1 = Utils.HexToByte(val, 12); + bytec0 = Utils.HexToByte(val, 14); + } + else + { + bytea0 = Utils.HexToByte(val, 0); + bytea1 = Utils.HexToByte(val, 2); + bytea2 = Utils.HexToByte(val, 4); + bytea3 = Utils.HexToByte(val, 6); + + byteb0 = Utils.HexToByte(val, 8); + byteb1 = Utils.HexToByte(val, 10); + + bytec0 = Utils.HexToByte(val, 12); + bytec1 = Utils.HexToByte(val, 14); + } + + d = Utils.HexToByte(val, 16); + e = Utils.HexToByte(val, 18); + + f = Utils.HexToByte(val, 20); + g = Utils.HexToByte(val, 22); + h = Utils.HexToByte(val, 24); + i = Utils.HexToByte(val, 26); + j = Utils.HexToByte(val, 28); + k = Utils.HexToByte(val, 30); + return; + } + } + } + catch { } + this = new UUID(); + throw new System.FormatException("Invalid UUID"); + } /// /// Constructor that takes a System.Guid object @@ -168,7 +275,7 @@ public unsafe UUID(byte[] source, int pos) : this() [MethodImpl(MethodImplOptions.AggressiveInlining)] public UUID(ulong val) : this() { - if(BitConverter.IsLittleEndian) + if (BitConverter.IsLittleEndian) ulongb = val; else { @@ -201,7 +308,7 @@ public UUID(UUID val) /// public int CompareTo(object val) { - if(val == null) + if (val == null) return 1; UUID id = (UUID)val; @@ -346,7 +453,7 @@ public unsafe byte[] GetBytes() [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe void ToBytes(byte[] dest, int pos) { - fixed(byte* ptr = &dest[pos]) + fixed (byte* ptr = &dest[pos]) { if (BitConverter.IsLittleEndian) { @@ -391,7 +498,7 @@ public uint CRC() /// An integer created from the last eight bytes of this UUID public ulong GetULong() { - if(BitConverter.IsLittleEndian) + if (BitConverter.IsLittleEndian) return ulongb; else return d + @@ -414,11 +521,116 @@ public ulong GetULong() /// A string representation of a UUID, case /// insensitive and can either be hyphenated or non-hyphenated /// UUID.Parse("11f8aa9c-b071-4242-836b-13b7abe0d489") + /* public static UUID Parse(string val) { Guid gg = Guid.Parse(val); return new UUID(gg); } + */ + + public unsafe static UUID Parse(string sval) + { + UUID result = new UUID(); + if (string.IsNullOrEmpty(sval)) + throw new System.FormatException("Invalid UUID"); + try + { + fixed (char* bval = sval) + { + char* val = bval; + + while (*val == ' ') ++val; + if (val[8] == '-') + { + if (val[13] != '-' || val[18] != '-' || val[23] != '-') + throw new Exception(); + + if (BitConverter.IsLittleEndian) + { + result.bytea3 = (byte)Utils.HexToByte(val, 0); + result.bytea2 = (byte)Utils.HexToByte(val, 2); + result.bytea1 = (byte)Utils.HexToByte(val, 4); + result.bytea0 = (byte)Utils.HexToByte(val, 6); + + result.byteb1 = (byte)Utils.HexToByte(val, 9); + result.byteb0 = (byte)Utils.HexToByte(val, 11); + + result.bytec1 = (byte)Utils.HexToByte(val, 14); + result.bytec0 = (byte)Utils.HexToByte(val, 16); + } + else + { + result.bytea0 = (byte)Utils.HexToByte(val, 0); + result.bytea1 = (byte)Utils.HexToByte(val, 2); + result.bytea2 = (byte)Utils.HexToByte(val, 4); + result.bytea3 = (byte)Utils.HexToByte(val, 6); + + result.byteb0 = (byte)Utils.HexToByte(val, 9); + result.byteb1 = (byte)Utils.HexToByte(val, 11); + + result.bytec0 = (byte)Utils.HexToByte(val, 14); + result.bytec1 = (byte)Utils.HexToByte(val, 16); + } + + result.d = (byte)Utils.HexToByte(val, 19); + result.e = (byte)Utils.HexToByte(val, 21); + + + result.f = (byte)Utils.HexToByte(val, 24); + result.g = (byte)Utils.HexToByte(val, 26); + result.h = (byte)Utils.HexToByte(val, 28); + result.i = (byte)Utils.HexToByte(val, 30); + result.j = (byte)Utils.HexToByte(val, 32); + result.k = (byte)Utils.HexToByte(val, 34); + return result; + } + else + { + if (BitConverter.IsLittleEndian) + { + result.bytea3 = Utils.HexToByte(val, 0); + result.bytea2 = Utils.HexToByte(val, 2); + result.bytea1 = Utils.HexToByte(val, 4); + result.bytea0 = Utils.HexToByte(val, 6); + + result.byteb1 = Utils.HexToByte(val, 8); + result.byteb0 = Utils.HexToByte(val, 10); + + result.bytec1 = Utils.HexToByte(val, 12); + result.bytec0 = Utils.HexToByte(val, 14); + } + else + { + result.bytea0 = Utils.HexToByte(val, 0); + result.bytea1 = Utils.HexToByte(val, 2); + result.bytea2 = Utils.HexToByte(val, 4); + result.bytea3 = Utils.HexToByte(val, 6); + + result.byteb0 = Utils.HexToByte(val, 8); + result.byteb1 = Utils.HexToByte(val, 10); + + result.bytec0 = Utils.HexToByte(val, 12); + result.bytec1 = Utils.HexToByte(val, 14); + } + + result.d = Utils.HexToByte(val, 16); + result.e = Utils.HexToByte(val, 18); + + result.f = Utils.HexToByte(val, 20); + result.g = Utils.HexToByte(val, 22); + result.h = Utils.HexToByte(val, 24); + result.i = Utils.HexToByte(val, 26); + result.j = Utils.HexToByte(val, 28); + result.k = Utils.HexToByte(val, 30); + return result; + } + } + } + catch { } + result = new UUID(); + throw new System.FormatException("Invalid UUID"); + } /// /// Generate a UUID from a string @@ -429,20 +641,107 @@ public static UUID Parse(string val) /// otherwise null /// True if the string was successfully parse, otherwise false /// UUID.TryParse("11f8aa9c-b071-4242-836b-13b7abe0d489", result) - public static bool TryParse(string val, out UUID result) + + public unsafe static bool TryParse(string sval, out UUID result) { - if (!string.IsNullOrEmpty(val)) + result = new UUID(); + if (string.IsNullOrEmpty(sval)) + return false; + + try { - try + fixed (char* bval = sval) { - if (Guid.TryParse(val, out Guid gg)) + char* val = bval; + + while (*val == ' ') ++val; + if (val[8] == '-') { - result = new UUID(gg); + if (val[13] != '-' || val[18] != '-' || val[23] != '-') + return false; + + if (BitConverter.IsLittleEndian) + { + result.bytea3 = (byte)Utils.HexToByte(val, 0); + result.bytea2 = (byte)Utils.HexToByte(val, 2); + result.bytea1 = (byte)Utils.HexToByte(val, 4); + result.bytea0 = (byte)Utils.HexToByte(val, 6); + + result.byteb1 = (byte)Utils.HexToByte(val, 9); + result.byteb0 = (byte)Utils.HexToByte(val, 11); + + result.bytec1 = (byte)Utils.HexToByte(val, 14); + result.bytec0 = (byte)Utils.HexToByte(val, 16); + } + else + { + result.bytea0 = (byte)Utils.HexToByte(val, 0); + result.bytea1 = (byte)Utils.HexToByte(val, 2); + result.bytea2 = (byte)Utils.HexToByte(val, 4); + result.bytea3 = (byte)Utils.HexToByte(val, 6); + + result.byteb0 = (byte)Utils.HexToByte(val, 9); + result.byteb1 = (byte)Utils.HexToByte(val, 11); + + result.bytec0 = (byte)Utils.HexToByte(val, 14); + result.bytec1 = (byte)Utils.HexToByte(val, 16); + } + + result.d = (byte)Utils.HexToByte(val, 19); + result.e = (byte)Utils.HexToByte(val, 21); + + + result.f = (byte)Utils.HexToByte(val, 24); + result.g = (byte)Utils.HexToByte(val, 26); + result.h = (byte)Utils.HexToByte(val, 28); + result.i = (byte)Utils.HexToByte(val, 30); + result.j = (byte)Utils.HexToByte(val, 32); + result.k = (byte)Utils.HexToByte(val, 34); + return true; + } + else + { + if (BitConverter.IsLittleEndian) + { + result.bytea3 = Utils.HexToByte(val, 0); + result.bytea2 = Utils.HexToByte(val, 2); + result.bytea1 = Utils.HexToByte(val, 4); + result.bytea0 = Utils.HexToByte(val, 6); + + result.byteb1 = Utils.HexToByte(val, 8); + result.byteb0 = Utils.HexToByte(val, 10); + + result.bytec1 = Utils.HexToByte(val, 12); + result.bytec0 = Utils.HexToByte(val, 14); + } + else + { + result.bytea0 = Utils.HexToByte(val, 0); + result.bytea1 = Utils.HexToByte(val, 2); + result.bytea2 = Utils.HexToByte(val, 4); + result.bytea3 = Utils.HexToByte(val, 6); + + result.byteb0 = Utils.HexToByte(val, 8); + result.byteb1 = Utils.HexToByte(val, 10); + + result.bytec0 = Utils.HexToByte(val, 12); + result.bytec1 = Utils.HexToByte(val, 14); + } + + result.d = Utils.HexToByte(val, 16); + result.e = Utils.HexToByte(val, 18); + + result.f = Utils.HexToByte(val, 20); + result.g = Utils.HexToByte(val, 22); + result.h = Utils.HexToByte(val, 24); + result.i = Utils.HexToByte(val, 26); + result.j = Utils.HexToByte(val, 28); + result.k = Utils.HexToByte(val, 30); return true; } } - catch { } } + catch { } result = new UUID(); return false; } @@ -471,7 +770,7 @@ public static UUID Combine(UUID first, UUID second) [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static UUID Random() { - Guid g = Guid.NewGuid(); + Guid g = Guid.NewGuid(); return *(UUID*)&g; } diff --git a/OpenMetaverseTypes/Utils.cs b/OpenMetaverseTypes/Utils.cs index e1dbcdf6..534d29d3 100644 --- a/OpenMetaverseTypes/Utils.cs +++ b/OpenMetaverseTypes/Utils.cs @@ -115,7 +115,7 @@ public enum Runtime public static float Clamp(float value, float min, float max) { // First we check to see if we're greater than the max - if (value > max) + if (value >= max) return max; // Then we check to see if we're less than the min. @@ -137,7 +137,7 @@ public static float Clamp(float value, float min, float max) public static double Clamp(double value, double min, double max) { // First we check to see if we're greater than the max - if (value > max) + if (value >= max) return max; // Then we check to see if we're less than the min. @@ -159,7 +159,7 @@ public static double Clamp(double value, double min, double max) public static int Clamp(int value, int min, int max) { // First we check to see if we're greater than the max - if (value > max) + if (value >= max) return max; // Then we check to see if we're less than the min. diff --git a/OpenMetaverseTypes/UtilsConversions.cs b/OpenMetaverseTypes/UtilsConversions.cs index dfd73f75..68fcaa86 100644 --- a/OpenMetaverseTypes/UtilsConversions.cs +++ b/OpenMetaverseTypes/UtilsConversions.cs @@ -1818,53 +1818,6 @@ public static int osUTF8GetBytesCount(string str, int maxnbytes, out int maxsour return nbytes; } - /// - /// Converts a string containing hexadecimal characters to a byte array - /// - /// String containing hexadecimal characters - /// If true, gracefully handles null, empty and - /// uneven strings as well as stripping unconvertable characters - /// The converted byte array - public static byte[] HexStringToBytes(string hexString, bool handleDirty) - { - if (handleDirty) - { - if (String.IsNullOrEmpty(hexString)) - return Array.Empty(); - - StringBuilder stripped = new StringBuilder(hexString.Length); - char c; - - // remove all non A-F, 0-9, characters - for (int i = 0; i < hexString.Length; i++) - { - c = hexString[i]; - if (IsHexDigit(c)) - stripped.Append(c); - } - - hexString = stripped.ToString(); - - // if odd number of characters, discard last character - if (hexString.Length % 2 != 0) - { - hexString = hexString.Substring(0, hexString.Length - 1); - } - } - - int byteLength = hexString.Length / 2; - byte[] bytes = new byte[byteLength]; - int j = 0; - - for (int i = 0; i < bytes.Length; i++) - { - bytes[i] = HexToByte(hexString.Substring(j, 2)); - j += 2; - } - - return bytes; - } - /// /// Returns true is c is a hexadecimal digit (A-F, a-f, 0-9) /// @@ -1877,13 +1830,13 @@ public static bool IsHexDigit(Char c) const int numa = 97; const int num0 = 48; - if(c > numa + 5) - return false; if (c < num0) return false; if (c < (num0 + 10)) return true; + if (c > numa + 5) + return false; if (c >= numa) return true; @@ -1899,13 +1852,13 @@ public static int HexNibbleWithChk(Char c) const int numa = 97; const int num0 = 48; - if (c > numa + 5) - return -1; if (c < num0) return -1; if (c < (num0 + 10)) return c - num0; + if (c > numa + 5) + return -1; if (c >= numa) return c - numa + 10; @@ -1921,13 +1874,13 @@ public static int HexNibbleWithChk(byte c) const int numa = 97; const int num0 = 48; - if (c > numa + 5) - return -1; if (c < num0) return -1; if (c < (num0 + 10)) return c - num0; + if (c > numa + 5) + return -1; if (c >= numa) return c - numa + 10; @@ -1940,24 +1893,52 @@ public static int HexNibbleWithChk(byte c) public static int HexNibble(Char c) { - const int numA = 65; - const int numa = 97; - const int num0 = 48; + const char numA = 'A'; + const char numF = 'F'; + const char numa = 'a'; + const char numf = 'f'; + const char num0 = '0'; + const char num9 = '9'; - if (c > numa + 5) - return 0; if (c < num0) - return 0; - if (c < (num0 + 10)) + throw new Exception("invalid hex char"); + if (c <= num9) return c - num0; + if (c > numf) + throw new Exception("invalid hex char"); if (c >= numa) return c - numa + 10; - if (c >= numA && c < numA + 6) + if (c >= numA && c <= numF) + return c - numA + 10; + + throw new Exception("invalid hex char"); + } + + public static int HexNibble(byte c) + { + const byte numA = (byte)'A'; + const byte numF = (byte)'F'; + const byte numa = (byte)'a'; + const byte numf = (byte)'f'; + const byte num0 = (byte)'0'; + const byte num9 = (byte)'9'; + + if (c < num0) + throw new Exception("invalid hex char"); + if (c <= num9) + return c - num0; + + if (c > numf) + throw new Exception("invalid hex char"); + if (c >= numa) + return c - numa + 10; + + if (c >= numA && c <= numF) return c - numA + 10; - return 0; + throw new Exception("invalid hex char"); } public static bool TryHexToInt(byte[] data, int start, int len, out int res) @@ -1975,17 +1956,86 @@ public static bool TryHexToInt(byte[] data, int start, int len, out int res) } return true; } + + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public static bool TryHexToByte(byte[] data, int pos, out byte res) + { + int a,b; + if ((a = HexNibbleWithChk(data[pos])) < 0) + { + res = 0; + return false; + } + if ((b = HexNibbleWithChk(data[pos + 1])) < 0) + { + res = 0; + return false; + } + res = (byte)(a << 4 | b); + return true; + } + + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public static byte HexToByte(byte[] data, int pos) + { + return (byte)(HexNibble(data[pos]) << 4 | HexNibble(data[pos + 1])); + } + + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public unsafe static byte HexToByte(byte* data, int pos) + { + return (byte)(HexNibble(data[pos]) << 4 | HexNibble(data[pos + 1])); + } + + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public unsafe static byte HexToByte(char* hex, int pos) + { + return (byte)(HexNibble(hex[pos]) << 4 | HexNibble(hex[pos + 1])); + } + /// - /// Converts 1 or 2 character string into equivalant byte value + /// Converts a string containing hexadecimal characters to a byte array /// - /// 1 or 2 character string - /// byte - private static byte HexToByte(string hex) - { - if (hex.Length > 2 || hex.Length <= 0) - throw new ArgumentException("hex must be 1 or 2 characters in length"); - byte newByte = Byte.Parse(hex, System.Globalization.NumberStyles.HexNumber); - return newByte; + /// String containing hexadecimal characters + /// If true, gracefully handles null, empty and + /// uneven strings as well as stripping unconvertable characters + /// The converted byte array + public unsafe static byte[] HexStringToBytes(string hexString, bool handleDirty) + { + if (String.IsNullOrEmpty(hexString)) + return EmptyBytes; + if (handleDirty) + { + StringBuilder stripped = new StringBuilder(hexString.Length); + // remove all non A-F, 0-9, characters + foreach (char c in hexString) + { + if (IsHexDigit(c)) + stripped.Append(c); + } + hexString = stripped.ToString(); + + // if odd number of characters, discard last character + if (hexString.Length % 2 != 0) + { + hexString = hexString.Substring(0, hexString.Length - 1); + } + } + + int byteLength = hexString.Length / 2; + byte[] bytes = new byte[byteLength]; + int j = 0; + + fixed(char* c = hexString) + { + for (int i = 0; i < bytes.Length; i++) + { + bytes[i] = HexToByte(c, j); + j += 2; + } + } + + return bytes; } #endregion Strings diff --git a/OpenMetaverseTypes/Vector2.cs b/OpenMetaverseTypes/Vector2.cs index ab4187d8..34ab536f 100644 --- a/OpenMetaverseTypes/Vector2.cs +++ b/OpenMetaverseTypes/Vector2.cs @@ -235,6 +235,14 @@ public static Vector2 Add(Vector2 value1, Vector2 value2) return new Vector2(value1.X + value2.X, value1.Y + value2.Y); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector2 Clamp(Vector3 value1, float min, float max) + { + return new Vector2( + Utils.Clamp(value1.X, min, max), + Utils.Clamp(value1.Y, min, max)); + } + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public static Vector2 Clamp(Vector2 value1, Vector2 min, Vector2 max) { diff --git a/OpenMetaverseTypes/Vector3.cs b/OpenMetaverseTypes/Vector3.cs index 8f95a3a3..a0e6d843 100644 --- a/OpenMetaverseTypes/Vector3.cs +++ b/OpenMetaverseTypes/Vector3.cs @@ -130,6 +130,14 @@ public void Max(Vector3 v) if (v.Z > Z) Z = v.Z; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Clamp(float min, float max) + { + X = Utils.Clamp(X, min, max); + Y = Utils.Clamp(Y, min, max); + Z = Utils.Clamp(Z, min, max); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public float Length() { @@ -291,6 +299,15 @@ public static Vector3 Add(Vector3 value1, Vector3 value2) return new Vector3(value1.X + value2.X, value1.Y + value2.Y, value1.Z + value2.Z); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector3 Clamp(Vector3 value1, float min, float max) + { + return new Vector3( + Utils.Clamp(value1.X, min, max), + Utils.Clamp(value1.Y, min, max), + Utils.Clamp(value1.Z, min, max)); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 Clamp(Vector3 value1, Vector3 min, Vector3 max) { diff --git a/OpenMetaverseTypes/Vector3d.cs b/OpenMetaverseTypes/Vector3d.cs index f8a588bd..cd238957 100644 --- a/OpenMetaverseTypes/Vector3d.cs +++ b/OpenMetaverseTypes/Vector3d.cs @@ -185,6 +185,14 @@ public static Vector3d Add(Vector3d value1, Vector3d value2) return value1; } + public static Vector3d Clamp(Vector3 value1, double min, double max) + { + return new Vector3d( + Utils.Clamp(value1.X, min, max), + Utils.Clamp(value1.Y, min, max), + Utils.Clamp(value1.Z, min, max)); + } + public static Vector3d Clamp(Vector3d value1, Vector3d min, Vector3d max) { return new Vector3d( diff --git a/OpenMetaverseTypes/Vector4.cs b/OpenMetaverseTypes/Vector4.cs index c4e54e2a..a525f416 100644 --- a/OpenMetaverseTypes/Vector4.cs +++ b/OpenMetaverseTypes/Vector4.cs @@ -267,6 +267,15 @@ public static Vector4 Add(Vector4 value1, Vector4 value2) ); } + public static Vector4 Clamp(Vector4 value1, float min, float max) + { + return new Vector4( + Utils.Clamp(value1.X, min, max), + Utils.Clamp(value1.Y, min, max), + Utils.Clamp(value1.Z, min, max), + Utils.Clamp(value1.W, min, max)); + } + public static Vector4 Clamp(Vector4 value1, Vector4 min, Vector4 max) { return new Vector4( From f84e8fd9539cfbc7b8a473755fec460dbd7e8d6c Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Sun, 27 Mar 2022 23:44:25 +0100 Subject: [PATCH 041/149] make uuid from string parsing also look to end of string only acceptions spaces, like guid does. This needed waste for opensim bad HG UUI detection code code, all over the place --- OpenMetaverseTypes/UUID.cs | 77 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 73 insertions(+), 4 deletions(-) diff --git a/OpenMetaverseTypes/UUID.cs b/OpenMetaverseTypes/UUID.cs index 6fe7d367..9f82f223 100644 --- a/OpenMetaverseTypes/UUID.cs +++ b/OpenMetaverseTypes/UUID.cs @@ -26,6 +26,7 @@ using System; using System.Runtime.CompilerServices; +using System.Collections.Generic; using System.Runtime.InteropServices; using System.Xml.Serialization; @@ -38,7 +39,7 @@ namespace OpenMetaverse [StructLayout(LayoutKind.Explicit)] [Serializable()] - public struct UUID : IComparable,IComparable, IEquatable + public struct UUID : IComparable,IComparable, IEquatable, IEqualityComparer { // still a big piece of *** because how stupid .net structs are. // .net5 unsafe may remove the need for this union @@ -109,15 +110,26 @@ public unsafe UUID(string sval) if (string.IsNullOrEmpty(sval)) throw new System.FormatException("Invalid UUID"); + int len = sval.Length; try { fixed (char* bval = sval) { char *val = bval; - while (*val == ' ') ++val; + while (*val == ' ') + { + ++val; + --len; + } if (val[8] == '-') { + while (--len > 35) + { + if (val[len] != ' ') + throw new Exception(); + } + if (val[13] != '-' || val[18] != '-' || val[23] != '-') throw new Exception(); @@ -163,6 +175,12 @@ public unsafe UUID(string sval) } else { + while (--len > 31) + { + if (val[len] != ' ') + throw new Exception(); + } + if (BitConverter.IsLittleEndian) { bytea3 = Utils.HexToByte(val, 0); @@ -534,15 +552,27 @@ public unsafe static UUID Parse(string sval) UUID result = new UUID(); if (string.IsNullOrEmpty(sval)) throw new System.FormatException("Invalid UUID"); + int len = sval.Length; + try { fixed (char* bval = sval) { char* val = bval; + while (*val == ' ') + { + ++val; + --len; + } - while (*val == ' ') ++val; if (val[8] == '-') { + while (--len > 35) + { + if (val[len] != ' ') + throw new Exception(); + } + if (val[13] != '-' || val[18] != '-' || val[23] != '-') throw new Exception(); @@ -587,6 +617,12 @@ public unsafe static UUID Parse(string sval) } else { + while (--len > 31) + { + if (val[len] != ' ') + throw new Exception(); + } + if (BitConverter.IsLittleEndian) { result.bytea3 = Utils.HexToByte(val, 0); @@ -648,15 +684,27 @@ public unsafe static bool TryParse(string sval, out UUID result) if (string.IsNullOrEmpty(sval)) return false; + int len = sval.Length; try { fixed (char* bval = sval) { char* val = bval; - while (*val == ' ') ++val; + while (*val == ' ') + { + ++val; + --len; + } + if (val[8] == '-') { + while (--len > 35) + { + if (val[len] != ' ') + return false; + } + if (val[13] != '-' || val[18] != '-' || val[23] != '-') return false; @@ -701,6 +749,11 @@ public unsafe static bool TryParse(string sval, out UUID result) } else { + while (--len > 31) + { + if (val[len] != ' ') + return false; + } if (BitConverter.IsLittleEndian) { result.bytea3 = Utils.HexToByte(val, 0); @@ -788,6 +841,12 @@ public override int GetHashCode() return a ^ intb ^ intc ^ intd; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public int GetHashCode(UUID u) + { + return u.a ^ u.intb ^ u.intc ^ u.intd; + } + /// /// Comparison function /// @@ -822,6 +881,16 @@ public bool Equals(UUID uuid) return true; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool Equals(UUID a, UUID b) + { + if (a.ulonga != b.ulonga) + return false; + if (a.ulongb != b.ulongb) + return false; + return true; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool IsZero() { From d7b3e6309074bf9163e650977d0c9e0f614f05ee Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Thu, 14 Apr 2022 00:18:11 +0100 Subject: [PATCH 042/149] add a few more methods to vectors and quat --- OpenMetaverseTypes/OSUTF8.cs | 2 +- OpenMetaverseTypes/OSUTF8Slice.cs | 2 +- OpenMetaverseTypes/Quaternion.cs | 45 +++++++++++++++++++++++++++++++ OpenMetaverseTypes/Vector2.cs | 32 ++++++++++++++++++++++ OpenMetaverseTypes/Vector3.cs | 35 ++++++++++++++++++++++++ 5 files changed, 114 insertions(+), 2 deletions(-) diff --git a/OpenMetaverseTypes/OSUTF8.cs b/OpenMetaverseTypes/OSUTF8.cs index e5e6f19c..7df4b9e8 100644 --- a/OpenMetaverseTypes/OSUTF8.cs +++ b/OpenMetaverseTypes/OSUTF8.cs @@ -962,7 +962,7 @@ public static bool TryParseInt(osUTF8 t, out int res) public unsafe static bool TryParseUUID(osUTF8 inp, out UUID result) { result = new UUID(); - if (inp.m_len == 0) + if (inp.m_len < 32) return false; try diff --git a/OpenMetaverseTypes/OSUTF8Slice.cs b/OpenMetaverseTypes/OSUTF8Slice.cs index f29dfeef..6d20f864 100644 --- a/OpenMetaverseTypes/OSUTF8Slice.cs +++ b/OpenMetaverseTypes/OSUTF8Slice.cs @@ -1658,7 +1658,7 @@ public static bool TryParseInt(osUTF8Slice t, out int res) public unsafe static bool TryParseUUID(osUTF8Slice inp, out UUID result) { result = new UUID(); - if (inp.m_len == 0) + if (inp.m_len < 32) return false; try diff --git a/OpenMetaverseTypes/Quaternion.cs b/OpenMetaverseTypes/Quaternion.cs index 91af0a02..88efdc54 100644 --- a/OpenMetaverseTypes/Quaternion.cs +++ b/OpenMetaverseTypes/Quaternion.cs @@ -216,6 +216,36 @@ public void Invert() } } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public float Dot(Quaternion q2) + { + return (X * q2.X) + (Y * q2.Y) + (Z * q2.Z) + (W * q2.W); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public float Dot(ref Quaternion q2) + { + return (X * q2.X) + (Y * q2.Y) + (Z * q2.Z) + (W * q2.W); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Add(Quaternion quaternion2) + { + X += quaternion2.X; + Y += quaternion2.Y; + Z += quaternion2.Z; + W += quaternion2.W; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Sub(Quaternion quaternion2) + { + X -= quaternion2.X; + Y -= quaternion2.Y; + Z -= quaternion2.Z; + W -= quaternion2.W; + } + /// /// Builds a quaternion object from a byte array /// @@ -801,6 +831,21 @@ public bool Equals(Quaternion other) return true; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool NotEqual(Quaternion other) + { + if (X != other.X) + return true; + if (Y != other.Y) + return true; + if (Z != other.Z) + return true; + if (W != other.W) + return true; + return false; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] public override int GetHashCode() { int hash = X.GetHashCode(); diff --git a/OpenMetaverseTypes/Vector2.cs b/OpenMetaverseTypes/Vector2.cs index 34ab536f..2febaa9a 100644 --- a/OpenMetaverseTypes/Vector2.cs +++ b/OpenMetaverseTypes/Vector2.cs @@ -89,6 +89,20 @@ public void Max(Vector2 v) if (v.Y > Y) Y = v.Y; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Add(Vector3 v) + { + X += v.X; + Y += v.Y; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Sub(Vector3 v) + { + X -= v.X; + Y -= v.Y; + } + /// /// Test if this vector is equal to another vector, within a given /// tolerance range @@ -158,6 +172,12 @@ public int CompareTo(Vector2 vector) return LengthSquared().CompareTo(vector.LengthSquared()); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public float Dot(Vector3 value2) + { + return (X * value2.X) + (Y * value2.Y); + } + /// /// Builds a vector from a byte array /// @@ -412,6 +432,7 @@ public override bool Equals(object obj) return true; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool Equals(Vector2 other) { if (X != other.X) @@ -421,6 +442,17 @@ public bool Equals(Vector2 other) return true; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool NotEqual(Vector3 other) + { + if (X != other.X) + return true; + if (Y != other.Y) + return true; + return false; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] public override int GetHashCode() { int hash = X.GetHashCode(); diff --git a/OpenMetaverseTypes/Vector3.cs b/OpenMetaverseTypes/Vector3.cs index a0e6d843..ba6b05d1 100644 --- a/OpenMetaverseTypes/Vector3.cs +++ b/OpenMetaverseTypes/Vector3.cs @@ -130,6 +130,22 @@ public void Max(Vector3 v) if (v.Z > Z) Z = v.Z; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Add(Vector3 v) + { + X += v.X; + Y += v.Y; + Z += v.Z; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Sub(Vector3 v) + { + X -= v.X; + Y -= v.Y; + Z -= v.Z; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Clamp(float min, float max) { @@ -240,6 +256,12 @@ public int CompareTo(Vector3 vector) return LengthSquared().CompareTo(vector.LengthSquared()); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public float Dot(Vector3 value2) + { + return (X * value2.X) + (Y * value2.Y) + (Z * value2.Z); + } + /// /// Test if this vector is composed of all finite numbers /// @@ -563,6 +585,7 @@ public override bool Equals(object obj) return true; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool Equals(Vector3 other) { if (X != other.X) @@ -574,6 +597,18 @@ public bool Equals(Vector3 other) return true; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool NotEqual(Vector3 other) + { + if (X != other.X) + return true; + if (Y != other.Y) + return true; + if (Z != other.Z) + return true; + return false; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public override int GetHashCode() { From d1428d49d3836f49d4d9d51673432a5204dfebfe Mon Sep 17 00:00:00 2001 From: Mike Dickson Date: Tue, 26 Apr 2022 17:01:20 -0400 Subject: [PATCH 043/149] Missed some commits on merge. --- OpenMetaverse.StructuredData/JSON/JsonData.cs | 30 ------------------- 1 file changed, 30 deletions(-) diff --git a/OpenMetaverse.StructuredData/JSON/JsonData.cs b/OpenMetaverse.StructuredData/JSON/JsonData.cs index a792491c..e2a8446e 100644 --- a/OpenMetaverse.StructuredData/JSON/JsonData.cs +++ b/OpenMetaverse.StructuredData/JSON/JsonData.cs @@ -135,12 +135,7 @@ ICollection IDictionary.Keys EnsureDictionary(); IList keys = new List(); -<<<<<<< HEAD - foreach (KeyValuePair entry in - object_list) -======= foreach (KeyValuePair entry in object_list) ->>>>>>> upstream/master { keys.Add(entry.Key); } @@ -156,12 +151,7 @@ ICollection IDictionary.Values EnsureDictionary(); IList values = new List(); -<<<<<<< HEAD - foreach (KeyValuePair entry in - object_list) -======= foreach (KeyValuePair entry in object_list) ->>>>>>> upstream/master { values.Add(entry.Value); } @@ -270,12 +260,7 @@ object IOrderedDictionary.this[int idx] inst_object[old_entry.Key] = data; -<<<<<<< HEAD - KeyValuePair entry = - new KeyValuePair(old_entry.Key, data); -======= KeyValuePair entry = new KeyValuePair(old_entry.Key, data); ->>>>>>> upstream/master object_list[idx] = entry; } @@ -315,12 +300,7 @@ public JsonData this[string prop_name] { EnsureDictionary(); -<<<<<<< HEAD - KeyValuePair entry = - new KeyValuePair(prop_name, value); -======= KeyValuePair entry = new KeyValuePair(prop_name, value); ->>>>>>> upstream/master if (inst_object.ContainsKey(prop_name)) { @@ -363,12 +343,7 @@ public JsonData this[int index] else { KeyValuePair entry = object_list[index]; -<<<<<<< HEAD - KeyValuePair new_entry = - new KeyValuePair(entry.Key, value); -======= KeyValuePair new_entry = new KeyValuePair(entry.Key, value); ->>>>>>> upstream/master object_list[index] = new_entry; inst_object[entry.Key] = value; @@ -549,12 +524,7 @@ void IDictionary.Add(object key, object value) EnsureDictionary().Add(key, data); -<<<<<<< HEAD - KeyValuePair entry = - new KeyValuePair((string)key, data); -======= KeyValuePair entry = new KeyValuePair((string)key, data); ->>>>>>> upstream/master object_list.Add(entry); json = null; From bc04e72df6fd15084874b1cf768c85eccdb2b5cc Mon Sep 17 00:00:00 2001 From: Mike Dickson Date: Wed, 27 Apr 2022 00:49:17 -0400 Subject: [PATCH 044/149] Add properties for exes to correctly handle embedded resource files. --- Directory.Build.props | 28 +++++++++++++------ .../OpenMetaverse.Tests.csproj | 2 +- OpenMetaverse.sln | 14 +++++++--- Programs/WinGridProxy/WinGridProxy.csproj | 2 ++ .../GridAccountant/GridAccountant.csproj | 4 +++ 5 files changed, 36 insertions(+), 14 deletions(-) diff --git a/Directory.Build.props b/Directory.Build.props index 2bad5494..5614607e 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,11 +1,21 @@ - - 1.1.7 - 1.1.7 - 1.1.7 - $(SolutionDir)\obj\$(Configuration)\$(MSBuildProjectName)\ - $(SolutionDir)\obj\$(Configuration)\$(MSBuildProjectName)\ - $(SolutionDir)\build\$(Configuration)\$(AssemblyName)\ - $(OutputPath) - + + 0.10.0.0 + OpenMetaverse + Utopa Skye LLC, OpenMetaverse Developers + Utopia Skye LLC + + + 1.1.8 + 1.1.7 + 1.1.7 + 1.1.7 + BSD-3-Clause + https://github.com/OpenSim-NGC/libopenmetaverse + false + OMV OpenMetaverse OpenSim Halcyon OpenMetaverseFoundation VirtualWorld VirtualReality 3D SecondLife + https://github.com/OpenSim-NGC/libopenmetaverse.git + git + master + diff --git a/OpenMetaverse.Tests/OpenMetaverse.Tests.csproj b/OpenMetaverse.Tests/OpenMetaverse.Tests.csproj index 2b7f7d37..1ec7eb15 100644 --- a/OpenMetaverse.Tests/OpenMetaverse.Tests.csproj +++ b/OpenMetaverse.Tests/OpenMetaverse.Tests.csproj @@ -6,7 +6,7 @@ 1591,1574,0419,0618 - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/OpenMetaverse.sln b/OpenMetaverse.sln index 330027ea..03e57126 100644 --- a/OpenMetaverse.sln +++ b/OpenMetaverse.sln @@ -1,6 +1,7 @@ -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.28803.352 + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.1.32414.318 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AvatarPreview", "Programs\AvatarPreview\AvatarPreview.csproj", "{93CEA633-0000-0000-0000-000000000000}" EndProject @@ -56,7 +57,12 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "VoiceTest", "Programs\Voice EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WinGridProxy", "Programs\WinGridProxy\WinGridProxy.csproj", "{455B06F4-0000-0000-0000-000000000000}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenMetaverse.PrimMesher", "OpenMetaverse.PrimMesher\OpenMetaverse.PrimMesher.csproj", "{2E2B643F-F18B-4791-BA4B-6E82D0E794B6}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenMetaverse.PrimMesher", "OpenMetaverse.PrimMesher\OpenMetaverse.PrimMesher.csproj", "{2E2B643F-F18B-4791-BA4B-6E82D0E794B6}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{49AFD80D-D399-43FC-A9EE-9F15BC6D49E7}" + ProjectSection(SolutionItems) = preProject + README.md = README.md + EndProjectSection EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/Programs/WinGridProxy/WinGridProxy.csproj b/Programs/WinGridProxy/WinGridProxy.csproj index 56de6992..d8a2ca26 100644 --- a/Programs/WinGridProxy/WinGridProxy.csproj +++ b/Programs/WinGridProxy/WinGridProxy.csproj @@ -10,9 +10,11 @@ Copyright © 2015 OpenMetaverse Ninjas True 1591,1574,0419,0618 + True + diff --git a/Programs/examples/GridAccountant/GridAccountant.csproj b/Programs/examples/GridAccountant/GridAccountant.csproj index 86eb17c4..d8ffd302 100644 --- a/Programs/examples/GridAccountant/GridAccountant.csproj +++ b/Programs/examples/GridAccountant/GridAccountant.csproj @@ -5,7 +5,11 @@ WinExe 1591,1574,0419,0618 True + True + + + False From d6aa68207f5073ae86831ffeaeaff8ea255102b9 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Sun, 8 May 2022 02:55:32 +0100 Subject: [PATCH 045/149] cosmetics --- .../StructuredData.cs | 81 +++++++++---------- OpenMetaverseTypes/Quaternion.cs | 1 + OpenMetaverseTypes/UUID.cs | 4 +- OpenMetaverseTypes/UtilsConversions.cs | 3 +- OpenMetaverseTypes/Vector4.cs | 44 ++++++++++ 5 files changed, 86 insertions(+), 47 deletions(-) diff --git a/OpenMetaverse.StructuredData/StructuredData.cs b/OpenMetaverse.StructuredData/StructuredData.cs index 4cb55eef..bca87d4e 100644 --- a/OpenMetaverse.StructuredData/StructuredData.cs +++ b/OpenMetaverse.StructuredData/StructuredData.cs @@ -1566,10 +1566,10 @@ public OSDBinary(uint value) Type = OSDType.Binary; this.value = new byte[] { - (byte)((value >> 24) % 256), - (byte)((value >> 16) % 256), - (byte)((value >> 8) % 256), - (byte)(value % 256) + (byte)((value >> 24) & 0xFF), + (byte)((value >> 16) & 0xFF), + (byte)((value >> 8) & 0xFF), + (byte)(value& 0xFF) }; } @@ -1578,14 +1578,14 @@ public OSDBinary(long value) Type = OSDType.Binary; this.value = new byte[] { - (byte)((value >> 56) % 256), - (byte)((value >> 48) % 256), - (byte)((value >> 40) % 256), - (byte)((value >> 32) % 256), - (byte)((value >> 24) % 256), - (byte)((value >> 16) % 256), - (byte)((value >> 8) % 256), - (byte)(value % 256) + (byte)((value >> 56) & 0xFF), + (byte)((value >> 48) & 0xFF), + (byte)((value >> 40) & 0xFF), + (byte)((value >> 32) & 0xFF), + (byte)((value >> 24) & 0xFF), + (byte)((value >> 16) & 0xFF), + (byte)((value >> 8) & 0xFF), + (byte)(value& 0xFF) }; } @@ -1594,14 +1594,14 @@ public OSDBinary(ulong value) Type = OSDType.Binary; this.value = new byte[] { - (byte)((value >> 56) % 256), - (byte)((value >> 48) % 256), - (byte)((value >> 40) % 256), - (byte)((value >> 32) % 256), - (byte)((value >> 24) % 256), - (byte)((value >> 16) % 256), - (byte)((value >> 8) % 256), - (byte)(value % 256) + (byte)((value >> 56) & 0xFF), + (byte)((value >> 48) & 0xFF), + (byte)((value >> 40) & 0xFF), + (byte)((value >> 32) & 0xFF), + (byte)((value >> 24) & 0xFF), + (byte)((value >> 16) & 0xFF), + (byte)((value >> 8) & 0xFF), + (byte)(value& 0xFF) }; } @@ -1611,45 +1611,36 @@ public OSDBinary(ulong value) public override int AsInteger() { - return ( - (value[0] << 24) + - (value[1] << 16) + - (value[2] << 8) + - (value[3] << 0)); + return ((value[0] << 24) | (value[1] << 16) | (value[2] << 8) | (value[3] << 0)); } public override uint AsUInteger() { - return (uint)( - (value[0] << 24) + - (value[1] << 16) + - (value[2] << 8) + - (value[3] << 0)); - } + return (uint)((value[0] << 24) | (value[1] << 16) | (value[2] << 8) | (value[3] << 0));} public override long AsLong() { return (long)( - ((long)value[0] << 56) + - ((long)value[1] << 48) + - ((long)value[2] << 40) + - ((long)value[3] << 32) + - ((long)value[4] << 24) + - ((long)value[5] << 16) + - ((long)value[6] << 8) + + ((long)value[0] << 56) | + ((long)value[1] << 48) | + ((long)value[2] << 40) | + ((long)value[3] << 32) | + ((long)value[4] << 24) | + ((long)value[5] << 16) | + ((long)value[6] << 8) | ((long)value[7] << 0)); } public override ulong AsULong() { return (ulong)( - ((ulong)value[0] << 56) + - ((ulong)value[1] << 48) + - ((ulong)value[2] << 40) + - ((ulong)value[3] << 32) + - ((ulong)value[4] << 24) + - ((ulong)value[5] << 16) + - ((ulong)value[6] << 8) + + ((ulong)value[0] << 56) | + ((ulong)value[1] << 48) | + ((ulong)value[2] << 40) | + ((ulong)value[3] << 32) | + ((ulong)value[4] << 24) | + ((ulong)value[5] << 16) | + ((ulong)value[6] << 8) | ((ulong)value[7] << 0)); } diff --git a/OpenMetaverseTypes/Quaternion.cs b/OpenMetaverseTypes/Quaternion.cs index 88efdc54..3c66aa3e 100644 --- a/OpenMetaverseTypes/Quaternion.cs +++ b/OpenMetaverseTypes/Quaternion.cs @@ -818,6 +818,7 @@ public override bool Equals(object obj) return true; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool Equals(Quaternion other) { if (X != other.X) diff --git a/OpenMetaverseTypes/UUID.cs b/OpenMetaverseTypes/UUID.cs index 9f82f223..2a767402 100644 --- a/OpenMetaverseTypes/UUID.cs +++ b/OpenMetaverseTypes/UUID.cs @@ -838,7 +838,9 @@ public unsafe static UUID Random() [MethodImpl(MethodImplOptions.AggressiveInlining)] public override int GetHashCode() { - return a ^ intb ^ intc ^ intd; + int h = Utils.CombineHash(intd, intc); + h = Utils.CombineHash(h, intb); + return Utils.CombineHash(h, a); } [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/OpenMetaverseTypes/UtilsConversions.cs b/OpenMetaverseTypes/UtilsConversions.cs index 68fcaa86..ede05147 100644 --- a/OpenMetaverseTypes/UtilsConversions.cs +++ b/OpenMetaverseTypes/UtilsConversions.cs @@ -367,7 +367,8 @@ public static bool ApproxEqual(float a, float b) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int CombineHash(int a, int b) { - return ((a << 5) + a) ^ b; + //return ((a << 5) + a) ^ b; + return 65599 * a + b; } /// diff --git a/OpenMetaverseTypes/Vector4.cs b/OpenMetaverseTypes/Vector4.cs index a525f416..2a63caee 100644 --- a/OpenMetaverseTypes/Vector4.cs +++ b/OpenMetaverseTypes/Vector4.cs @@ -111,6 +111,32 @@ public void Abs() W = Math.Abs(W); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Add(Vector4 v) + { + X += v.X; + Y += v.Y; + Z += v.Z; + W += v.W; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Sub(Vector4 v) + { + X -= v.X; + Y -= v.Y; + Z -= v.Z; + W -= v.W; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Clamp(float min, float max) + { + X = Utils.Clamp(X, min, max); + Y = Utils.Clamp(Y, min, max); + Z = Utils.Clamp(Z, min, max); + W = Utils.Clamp(W, min, max); + } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Min(Vector4 v) { @@ -204,6 +230,11 @@ public int CompareTo(Vector4 vector) return Length().CompareTo(vector.Length()); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public float Dot(Vector4 value2) + { + return (X * value2.X) + (Y * value2.Y) + (Z * value2.Z) + (W * value2.W); + } /// /// Test if this vector is composed of all finite numbers /// @@ -498,6 +529,19 @@ public bool Equals(Vector4 other) return true; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool NotEqual(Vector4 other) + { + if (X != other.X) + return true; + if (Y != other.Y) + return true; + if (Z != other.Z) + return true; + if (W != other.W) + return true; + return false; + } public override int GetHashCode() { return X.GetHashCode() ^ Y.GetHashCode() ^ Z.GetHashCode() ^ W.GetHashCode(); From 00f472d0dbf7cd4eeff8456709cb38758494fa4c Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Sat, 14 May 2022 23:23:26 +0100 Subject: [PATCH 046/149] fix osdjson uri serialize --- OpenMetaverse.StructuredData/JSON/OSDJson.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/OpenMetaverse.StructuredData/JSON/OSDJson.cs b/OpenMetaverse.StructuredData/JSON/OSDJson.cs index 994aa1e28..a7846150 100644 --- a/OpenMetaverse.StructuredData/JSON/OSDJson.cs +++ b/OpenMetaverse.StructuredData/JSON/OSDJson.cs @@ -251,7 +251,7 @@ public static void SerializeJson(OSD osd, osUTF8 sb, bool preserveDefaults) case OSDType.String: case OSDType.URI: case OSDType.LLSDxml: - appendJsonString((OSDString)osd, sb); + appendJsonString(osd.AsString(), sb); break; case OSDType.OSDUTF8: osUTF8 ou8 = ((OSDUTF8)osd).value; @@ -362,14 +362,14 @@ public static void SerializeJsonMapNoDefaults(string name, OSD osd, ref int mapc case OSDType.String: case OSDType.URI: case OSDType.LLSDxml: - OSDString ostr = (OSDString)osd; - if (!string.IsNullOrEmpty(ostr.value)) + string ostr = osd.AsString(); + if (!string.IsNullOrEmpty(ostr)) { if (mapcont++ > 0) sb.AppendASCII(','); appendJsonString(name, sb); sb.AppendASCII(':'); - appendJsonString(ostr.value, sb); + appendJsonString(ostr, sb); } break; case OSDType.OSDUTF8: From abf29b444b7fc2d1f54f45dd38db86c37ad54703 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Tue, 5 Jul 2022 20:39:01 +0100 Subject: [PATCH 047/149] user FormatException on uuid (try)parse --- .../LLSD/NotationLLSD.cs | 4 ++-- OpenMetaverse.StructuredData/LLSD/XmlLLSD.cs | 2 +- OpenMetaverse/AppearanceManager.cs | 2 +- OpenMetaverse/Messages/LindenMessages.cs | 1 + OpenMetaverseTypes/UUID.cs | 17 +++++++++++------ OpenMetaverseTypes/UtilsConversions.cs | 12 ++++++------ 6 files changed, 22 insertions(+), 16 deletions(-) diff --git a/OpenMetaverse.StructuredData/LLSD/NotationLLSD.cs b/OpenMetaverse.StructuredData/LLSD/NotationLLSD.cs index 75232601..0918ef0f 100644 --- a/OpenMetaverse.StructuredData/LLSD/NotationLLSD.cs +++ b/OpenMetaverse.StructuredData/LLSD/NotationLLSD.cs @@ -880,7 +880,7 @@ public static int BufferCharactersEqual(TextReader reader, char[] buffer, int of /// /// /// - /// + /// /// public static string UnescapeCharacter(String s, char d) { @@ -959,7 +959,7 @@ public static string UnescapeCharacter(String s, char d) /// /// /// - /// + /// /// public static string EscapeCharacter(String s, char d) { diff --git a/OpenMetaverse.StructuredData/LLSD/XmlLLSD.cs b/OpenMetaverse.StructuredData/LLSD/XmlLLSD.cs index 2942cb3d..bd802946 100644 --- a/OpenMetaverse.StructuredData/LLSD/XmlLLSD.cs +++ b/OpenMetaverse.StructuredData/LLSD/XmlLLSD.cs @@ -162,7 +162,7 @@ public static string SerializeLLSDInnerXmlString(OSD data, bool formal = false) /// /// /// - /// + /// /// public static void SerializeLLSDXmlElement(StringBuilder sb, OSD data, bool formal) { diff --git a/OpenMetaverse/AppearanceManager.cs b/OpenMetaverse/AppearanceManager.cs index 9d4914d9..c3fb42a2 100644 --- a/OpenMetaverse/AppearanceManager.cs +++ b/OpenMetaverse/AppearanceManager.cs @@ -1367,7 +1367,7 @@ bool GetCachedBakes() /// /// Populates textures and visual params from a decoded asset /// - /// Wearable to decode + /// textures to decode public static void DecodeWearableParams(WearableData wearable, ref TextureData[] textures) { Dictionary alphaMasks = new Dictionary(); diff --git a/OpenMetaverse/Messages/LindenMessages.cs b/OpenMetaverse/Messages/LindenMessages.cs index 762d3d29..2a80be1b 100644 --- a/OpenMetaverse/Messages/LindenMessages.cs +++ b/OpenMetaverse/Messages/LindenMessages.cs @@ -4469,6 +4469,7 @@ public OSDMap Serialize() public class GetObjectCostRequest : IMessage { /// Object IDs for which to request cost information + /// public UUID[] ObjectIDs; /// diff --git a/OpenMetaverseTypes/UUID.cs b/OpenMetaverseTypes/UUID.cs index 2a767402..df64e175 100644 --- a/OpenMetaverseTypes/UUID.cs +++ b/OpenMetaverseTypes/UUID.cs @@ -81,7 +81,7 @@ public struct UUID : IComparable,IComparable, IEquatable, IEqualityC /// /// Constructor that takes a string UUID representation /// - /// A string representation of a UUID, case + /// A string representation of a UUID, case /// insensitive and can either be hyphenated or non-hyphenated /// UUID("11f8aa9c-b071-4242-836b-13b7abe0d489") /* @@ -536,7 +536,7 @@ public ulong GetULong() /// /// Generate a UUID from a string /// - /// A string representation of a UUID, case + /// A string representation of a UUID, case /// insensitive and can either be hyphenated or non-hyphenated /// UUID.Parse("11f8aa9c-b071-4242-836b-13b7abe0d489") /* @@ -551,7 +551,7 @@ public unsafe static UUID Parse(string sval) { UUID result = new UUID(); if (string.IsNullOrEmpty(sval)) - throw new System.FormatException("Invalid UUID"); + throw new FormatException("Invalid UUID"); int len = sval.Length; try @@ -665,13 +665,13 @@ public unsafe static UUID Parse(string sval) } catch { } result = new UUID(); - throw new System.FormatException("Invalid UUID"); + throw new FormatException("Invalid UUID"); } /// /// Generate a UUID from a string /// - /// A string representation of a UUID, case + /// A string representation of a UUID, case /// insensitive and can either be hyphenated or non-hyphenated /// Will contain the parsed UUID if successful, /// otherwise null @@ -681,10 +681,13 @@ public unsafe static UUID Parse(string sval) public unsafe static bool TryParse(string sval, out UUID result) { result = new UUID(); - if (string.IsNullOrEmpty(sval)) + if (sval is null) return false; int len = sval.Length; + if (len < 32) + return false; + try { fixed (char* bval = sval) @@ -699,6 +702,8 @@ public unsafe static bool TryParse(string sval, out UUID result) if (val[8] == '-') { + if (len < 36) + return false; while (--len > 35) { if (val[len] != ' ') diff --git a/OpenMetaverseTypes/UtilsConversions.cs b/OpenMetaverseTypes/UtilsConversions.cs index ede05147..b956868f 100644 --- a/OpenMetaverseTypes/UtilsConversions.cs +++ b/OpenMetaverseTypes/UtilsConversions.cs @@ -1902,19 +1902,19 @@ public static int HexNibble(Char c) const char num9 = '9'; if (c < num0) - throw new Exception("invalid hex char"); + throw new FormatException("invalid hex char"); if (c <= num9) return c - num0; if (c > numf) - throw new Exception("invalid hex char"); + throw new FormatException("invalid hex char"); if (c >= numa) return c - numa + 10; if (c >= numA && c <= numF) return c - numA + 10; - throw new Exception("invalid hex char"); + throw new FormatException("invalid hex char"); } public static int HexNibble(byte c) @@ -1927,19 +1927,19 @@ public static int HexNibble(byte c) const byte num9 = (byte)'9'; if (c < num0) - throw new Exception("invalid hex char"); + throw new FormatException("invalid hex char"); if (c <= num9) return c - num0; if (c > numf) - throw new Exception("invalid hex char"); + throw new FormatException("invalid hex char"); if (c >= numa) return c - numa + 10; if (c >= numA && c <= numF) return c - numA + 10; - throw new Exception("invalid hex char"); + throw new FormatException("invalid hex char"); } public static bool TryHexToInt(byte[] data, int start, int len, out int res) From 6aa80fc8f220d40aea2fecfae194b1cae0df514b Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Tue, 19 Jul 2022 10:01:54 +0100 Subject: [PATCH 048/149] mantis 9012: add extra a few more buffer len checks on uuid parsing, a waste since jit adds bound checks even on unsafe, but who knows mono... --- OpenMetaverseTypes/OSUTF8.cs | 14 ++++++++++++-- OpenMetaverseTypes/OSUTF8Slice.cs | 15 +++++++++++++-- OpenMetaverseTypes/UUID.cs | 24 ++++++++++++++++++++---- 3 files changed, 45 insertions(+), 8 deletions(-) diff --git a/OpenMetaverseTypes/OSUTF8.cs b/OpenMetaverseTypes/OSUTF8.cs index 7df4b9e8..02cdf759 100644 --- a/OpenMetaverseTypes/OSUTF8.cs +++ b/OpenMetaverseTypes/OSUTF8.cs @@ -962,7 +962,8 @@ public static bool TryParseInt(osUTF8 t, out int res) public unsafe static bool TryParseUUID(osUTF8 inp, out UUID result) { result = new UUID(); - if (inp.m_len < 32) + int len = inp.m_len; + if (len < 32) return false; try @@ -971,9 +972,18 @@ public unsafe static bool TryParseUUID(osUTF8 inp, out UUID result) { byte* val = bval; - while (*val == ' ') ++val; + while (*val == ' ') + { + ++val; + --len; + if (len < 32) + return false; + } + if (val[8] == '-') { + if (len < 36) + return false; if (val[13] != '-' || val[18] != '-' || val[23] != '-') return false; diff --git a/OpenMetaverseTypes/OSUTF8Slice.cs b/OpenMetaverseTypes/OSUTF8Slice.cs index 6d20f864..c9b42b7f 100644 --- a/OpenMetaverseTypes/OSUTF8Slice.cs +++ b/OpenMetaverseTypes/OSUTF8Slice.cs @@ -1658,7 +1658,8 @@ public static bool TryParseInt(osUTF8Slice t, out int res) public unsafe static bool TryParseUUID(osUTF8Slice inp, out UUID result) { result = new UUID(); - if (inp.m_len < 32) + int len = inp.m_len; + if (len < 32) return false; try @@ -1667,9 +1668,19 @@ public unsafe static bool TryParseUUID(osUTF8Slice inp, out UUID result) { byte* val = bval; - while (*val == ' ') ++val; + while (*val == ' ') + { + ++val; + --len; + if (len < 32) + return false; + } + if (val[8] == '-') { + if (len < 36) + return false; + if (val[13] != '-' || val[18] != '-' || val[23] != '-') return false; diff --git a/OpenMetaverseTypes/UUID.cs b/OpenMetaverseTypes/UUID.cs index df64e175..82709bf9 100644 --- a/OpenMetaverseTypes/UUID.cs +++ b/OpenMetaverseTypes/UUID.cs @@ -107,10 +107,13 @@ public unsafe UUID(string val) public unsafe UUID(string sval) { this = new UUID(); - if (string.IsNullOrEmpty(sval)) - throw new System.FormatException("Invalid UUID"); + if (sval == null) + throw new FormatException("Invalid UUID"); int len = sval.Length; + if (len < 32) + throw new FormatException("Invalid UUID"); + try { fixed (char* bval = sval) @@ -120,10 +123,15 @@ public unsafe UUID(string sval) { ++val; --len; + if (len < 32) + throw new Exception(); } if (val[8] == '-') { + if (len < 36) + throw new Exception(); + while (--len > 35) { if (val[len] != ' ') @@ -550,10 +558,12 @@ public static UUID Parse(string val) public unsafe static UUID Parse(string sval) { UUID result = new UUID(); - if (string.IsNullOrEmpty(sval)) + if (sval == null) throw new FormatException("Invalid UUID"); - int len = sval.Length; + int len = sval.Length; + if (len < 32) + throw new FormatException("Invalid UUID"); try { fixed (char* bval = sval) @@ -563,10 +573,14 @@ public unsafe static UUID Parse(string sval) { ++val; --len; + if (len < 32) + throw new Exception(); } if (val[8] == '-') { + if (len < 36) + throw new Exception(); while (--len > 35) { if (val[len] != ' ') @@ -698,6 +712,8 @@ public unsafe static bool TryParse(string sval, out UUID result) { ++val; --len; + if (len < 32) + return false; } if (val[8] == '-') From 607c8f063cb7bc8c4c822e9078d33bf54029b4c0 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Wed, 17 Aug 2022 19:41:42 +0100 Subject: [PATCH 049/149] add == and != overloads to osutf8 and osutf8slice --- OpenMetaverseTypes/OSUTF8.cs | 30 +++++++++++++++++++++++------- OpenMetaverseTypes/OSUTF8Slice.cs | 28 ++++++++++++++++++++++------ 2 files changed, 45 insertions(+), 13 deletions(-) diff --git a/OpenMetaverseTypes/OSUTF8.cs b/OpenMetaverseTypes/OSUTF8.cs index 02cdf759..95d730de 100644 --- a/OpenMetaverseTypes/OSUTF8.cs +++ b/OpenMetaverseTypes/OSUTF8.cs @@ -182,7 +182,7 @@ public override bool Equals(object obj) public unsafe bool Equals(osUTF8Slice o) { - if (o == null || m_len != o.m_len) + if (o is null || m_len != o.m_len) return false; byte[] otherdata = o.m_data; @@ -237,7 +237,7 @@ public unsafe bool Equals(byte[] o) public unsafe bool Equals(osUTF8 o) { - if (o == null || m_len != o.m_len) + if (o is null || m_len != o.m_len) return false; byte[] otherdata = o.m_data; @@ -266,6 +266,22 @@ public bool Equals(string s) return Equals(o); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool operator ==(osUTF8 value1, osUTF8 value2) + { + if (value1 is null) + return value2 is null; + return value1.Equals(value2); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool operator !=(osUTF8 value1, osUTF8 value2) + { + if (value1 is null) + return !(value2 is null); + return !value1.Equals(value2); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool Equals(char c) { @@ -274,7 +290,7 @@ public bool Equals(char c) public unsafe bool ACSIILowerEquals(osUTF8 o) { - if (o == null || m_len != o.m_len) + if (o is null || m_len != o.m_len) return false; fixed (byte* a = m_data, b = o.m_data) @@ -299,7 +315,7 @@ public unsafe bool ACSIILowerEquals(osUTF8 o) public unsafe bool ACSIILowerEquals(osUTF8Slice o) { - if (o == null || m_len != o.m_len) + if (o is null || m_len != o.m_len) return false; fixed (byte* a = m_data, b = o.m_data) @@ -1128,17 +1144,17 @@ public static byte[] GetASCIIBytes(string s) public static bool IsNullOrEmpty(osUTF8 u) { - return (u == null || u.m_len == 0); + return (u is null || u.m_len == 0); } public static bool IsEmpty(osUTF8 u) { - return (u == null || u.m_len == 0); + return (u is null || u.m_len == 0); } public static unsafe bool IsNullOrWhitespace(osUTF8 u) { - if(u == null || u.m_len == 0) + if(u is null || u.m_len == 0) return true; byte[] data = u.m_data; for (int i = 0; i < u.m_len; ++i) diff --git a/OpenMetaverseTypes/OSUTF8Slice.cs b/OpenMetaverseTypes/OSUTF8Slice.cs index c9b42b7f..ef472594 100644 --- a/OpenMetaverseTypes/OSUTF8Slice.cs +++ b/OpenMetaverseTypes/OSUTF8Slice.cs @@ -202,17 +202,17 @@ public void FromBytes(byte[] source, int offset, int len) public static bool IsNullOrEmpty(osUTF8Slice u) { - return (u == null || u.m_len == 0); + return (u is null || u.m_len == 0); } public static bool IsEmpty(osUTF8Slice u) { - return (u == null || u.m_len == 0); + return (u is null || u.m_len == 0); } public static unsafe bool IsNullOrWhitespace(osUTF8Slice u) { - if (u == null || u.m_len == 0) + if (u is null || u.m_len == 0) return true; byte[] data = u.m_data; for (int i = u.m_offset; i < u.m_offset + u.m_len; ++i) @@ -280,7 +280,7 @@ public override bool Equals(object obj) public unsafe bool Equals(osUTF8Slice o) { - if (o == null || m_len != o.m_len) + if (o is null || m_len != o.m_len) return false; byte[] otherdata = o.m_data; @@ -309,7 +309,7 @@ public unsafe bool Equals(osUTF8Slice o) public unsafe bool Equals(osUTF8 o) { - if (o == null || m_len != o.m_len) + if (o is null || m_len != o.m_len) return false; byte[] otherdata = o.m_data; @@ -369,6 +369,22 @@ public bool Equals(string s) return Equals(o); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool operator ==(osUTF8Slice value1, osUTF8Slice value2) + { + if (value1 is null) + return value2 is null; + return value1.Equals(value2); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool operator !=(osUTF8Slice value1, osUTF8Slice value2) + { + if (value1 is null) + return !(value2 is null); + return !value1.Equals(value2); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool Equals(char c) { @@ -377,7 +393,7 @@ public bool Equals(char c) public unsafe bool ACSIILowerEquals(osUTF8 o) { - if (o == null || m_len != o.m_len) + if (o is null || m_len != o.m_len) return false; fixed (byte* a = &m_data[m_offset], b = o.m_data) From 233b46789ad235372393789354025c91555bd50b Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Wed, 17 Aug 2022 19:45:49 +0100 Subject: [PATCH 050/149] add a few things we may need --- OpenMetaverse/PacketDecoder.cs | 29 +++- OpenMetaverse/Primitives/Primitive.cs | 212 +++++++++++++++++++++++++- OpenMetaverseTypes/Enums.cs | 8 +- OpenMetaverseTypes/EnumsPrimitive.cs | 3 + 4 files changed, 247 insertions(+), 5 deletions(-) diff --git a/OpenMetaverse/PacketDecoder.cs b/OpenMetaverse/PacketDecoder.cs index 8c77a9bf..64af8936 100644 --- a/OpenMetaverse/PacketDecoder.cs +++ b/OpenMetaverse/PacketDecoder.cs @@ -864,6 +864,8 @@ private static string DecodeObjectExtraParams(string fieldName, object fieldData Primitive.LightData Light = null; Primitive.SculptData Sculpt = null; Primitive.SculptData Mesh = null; + Primitive.ReflectionProbe rprobe = null; + Primitive.RenderMaterials RenderMaterials = null; uint meshFlags = 0; bool hasmeshFlags = false; @@ -874,7 +876,7 @@ private static string DecodeObjectExtraParams(string fieldName, object fieldData ExtraParamType type = (ExtraParamType)Utils.BytesToUInt16(data, i); i += 2; - uint paramLength = Utils.BytesToUInt(data, i); + int paramLength = (int)Utils.BytesToUInt(data, i); i += 4; if (type == ExtraParamType.Flexible) @@ -885,12 +887,21 @@ private static string DecodeObjectExtraParams(string fieldName, object fieldData Sculpt = new Primitive.SculptData(data, i); else if (type == ExtraParamType.Mesh) Mesh = new Primitive.SculptData(data, i); - else if ((byte)type == 0x70) + else if (type == ExtraParamType.MeshFlag) { hasmeshFlags = true; meshFlags = Utils.BytesToUInt(data, i); } - i += (int)paramLength; + else if (type == ExtraParamType.RenderMaterial) + { + RenderMaterials = new Primitive.RenderMaterials(data, i, paramLength); + } + else if (type == ExtraParamType.ReflectionProbe) + { + rprobe = new Primitive.ReflectionProbe(data, i); + } + + i += paramLength; //totalLength += (int)paramLength + 6; } @@ -930,6 +941,18 @@ private static string DecodeObjectExtraParams(string fieldName, object fieldData result.AppendFormat("{0,30}", meshFlags.ToString() + Environment.NewLine); result.AppendFormat("{0,30}", "" + Environment.NewLine); } + if (rprobe != null) + { + result.AppendFormat("{0,30}", "" + Environment.NewLine); + GenericTypeDecoder(rprobe, ref result); + result.AppendFormat("{0,30}", "" + Environment.NewLine); + } + if (RenderMaterials != null) + { + result.AppendFormat("{0,30}", "" + Environment.NewLine); + GenericTypeDecoder(RenderMaterials, ref result); + result.AppendFormat("{0,30}", "" + Environment.NewLine); + } result.AppendFormat("{0,30}", ""); return result.ToString(); diff --git a/OpenMetaverse/Primitives/Primitive.cs b/OpenMetaverse/Primitives/Primitive.cs index 13cfcea9..10f8cbf1 100644 --- a/OpenMetaverse/Primitives/Primitive.cs +++ b/OpenMetaverse/Primitives/Primitive.cs @@ -520,7 +520,7 @@ public override int GetHashCode() /// public override string ToString() { - return String.Format("LightTexture: {0} Params; {1]", LightTexture, Params); + return String.Format("LightTexture: {0} Params; {1}", LightTexture, Params); } } @@ -621,6 +621,216 @@ public override int GetHashCode() } } + /// + /// Information on the ReflectionProbe properties of a primitive + /// + public class ReflectionProbe + { + /// + /// Default constructor + /// + public ReflectionProbe() + { + } + + public float Ambiance = 0; + public float ClipDistance = 0; + public byte Flags = 0; + /// + /// + /// + /// + /// + public ReflectionProbe(byte[] data, int pos) + { + if (data.Length - pos >= 9) + { + Ambiance = Utils.Clamp(Utils.BytesToFloat(data, pos), 0, 1.0f); + ClipDistance = Utils.Clamp(Utils.BytesToFloat(data, pos + 4), 0, 1024f); + Flags = data[pos + 8]; + } + } + + /// + /// + /// + /// + public byte[] GetBytes() + { + byte[] data = new byte[9]; + Utils.FloatToBytes(Ambiance, data, 0); + Utils.FloatToBytes(ClipDistance, data, 4); + data[8] = Flags; + return data; + } + + public OSD GetOSD() + { + OSDMap map = new OSDMap(); + + map["ambiance"] = OSD.FromReal(Ambiance); + map["clip_distance"] = OSD.FromReal(ClipDistance); + map["flags"] = OSD.FromInteger(Flags); + return map; + } + + public static ReflectionProbe FromOSD(OSD osd) + { + ReflectionProbe probe = new ReflectionProbe(); + + if (osd.Type == OSDType.Map) + { + OSDMap map = (OSDMap)osd; + + probe.Ambiance = (float)map["ambiance"].AsReal(); + probe.ClipDistance = (float)map["clip_distance"].AsReal(); + probe.Flags = (byte)map["flags"].AsInteger(); + } + + return probe; + } + + public override int GetHashCode() + { + return Ambiance.GetHashCode() ^ ClipDistance.GetHashCode() ^ (int)Flags; + } + + /// + /// + /// + /// + public override string ToString() + { + return String.Format("ReflectionProbe: amb {0} clip {1} flags {2}", Ambiance, ClipDistance, Flags); + } + } + + /// + /// Information on the ReflectionProbe properties of a primitive + /// + public class RenderMaterials + { + public struct RenderMaterialEntry + { + public byte te_index; + public UUID id; + } + + public RenderMaterialEntry[] entries = null; + + /// + /// Default constructor + /// + public RenderMaterials() + { + } + + /// + /// + /// + /// + /// + public RenderMaterials(byte[] data, int pos, int size) + { + if (size > 17) + { + int count = data[pos]; + ++pos; + if (size >= 1 + 17 * count) + { + entries = new RenderMaterialEntry[count]; + for (int i = 0; i < count; ++i) + { + entries[i].te_index = data[pos++]; + entries[i].id = new UUID(data, pos); + pos += 16; + } + } + } + } + + /// + /// + /// + /// + public byte[] GetBytes() + { + if (entries == null || entries.Length == 0) + { + return new byte[] {0}; + } + byte[] data = new byte[1 + 17 * entries.Length]; + data[0] = (byte)entries.Length; + int pos = 1; + for (int i = 0; i < entries.Length; ++i) + { + data[pos++] = entries[i].te_index; + entries[i].id.ToBytes(data, pos); + pos += 16; + } + return data; + } + + public OSD GetOSD() + { + OSDArray eMaterials = new OSDArray(); + if(entries != null) + { + for(int i = 0; i < entries.Length;++i) + { + OSDMap map = new OSDMap() + { + ["te_idx"] = OSD.FromInteger(entries[i].te_index), + ["id"] = OSD.FromUUID(entries[i].id) + }; + eMaterials[i] = map; + } + } + return eMaterials; + } + + public static RenderMaterials FromOSD(OSD osd) + { + RenderMaterials rm = new RenderMaterials(); + try + { + if (osd.Type == OSDType.Array) + { + OSDArray mra = (OSDArray)osd; + if(mra.Count > 0) + { + RenderMaterialEntry[] entries = new RenderMaterialEntry[mra.Count]; + for(int i = 0; i < mra.Count; ++i) + { + OSDMap map = (OSDMap)mra[i]; + entries[i].te_index = (byte)map["te_idx"].AsInteger(); + entries[i].id = map["id"].AsUUID(); + } + } + } + } + catch { } + return rm; + } + + public override int GetHashCode() + { + int h = entries.Length.GetHashCode(); + for(int i = 0 ; i < entries.Length; ++i) + h ^= (int)entries[i].te_index ^ entries[i].id.GetHashCode(); + return h; + } + + /// + /// + /// + /// + public override string ToString() + { + return String.Format("RenderMaterials: nentries {0}}", entries==null? 0:entries.Length); + } + } + /// /// Extended properties to describe an object /// diff --git a/OpenMetaverseTypes/Enums.cs b/OpenMetaverseTypes/Enums.cs index d176e217..f00b3373 100644 --- a/OpenMetaverseTypes/Enums.cs +++ b/OpenMetaverseTypes/Enums.cs @@ -104,7 +104,9 @@ public enum AssetType : sbyte /// Linden mesh format Mesh = 49, - Settings = 56 + Settings = 56, + /// Render material + Material = 57 } /// @@ -170,6 +172,8 @@ public enum FolderType : sbyte MarkplaceStock = 54, /// Settings folder Settings = 56, + /// Render materials folder + Material = 57, /// Hypergrid Suitcase folder Suitcase = 100 } @@ -236,6 +240,8 @@ public enum InventoryType : sbyte Mesh = 22, Settings = 25, + + Material = 26 } /// diff --git a/OpenMetaverseTypes/EnumsPrimitive.cs b/OpenMetaverseTypes/EnumsPrimitive.cs index e0a94eb3..47d2568f 100644 --- a/OpenMetaverseTypes/EnumsPrimitive.cs +++ b/OpenMetaverseTypes/EnumsPrimitive.cs @@ -234,6 +234,9 @@ public enum ExtraParamType : ushort LightImage = 0x40, /// Whether this object is a mesh Mesh = 0x60, + MeshFlag = 0x70, + RenderMaterial = 0x80, + ReflectionProbe = 0x90 } /// From 6fa5bc9bdc06c31f4e70bb4fa48b495a450e09b5 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Wed, 24 Aug 2022 20:19:03 +0100 Subject: [PATCH 051/149] add runprebuild48.* to build as .net4.8 --- runprebuild48.bat | 48 +++++++++++++++++++++++++++++++++++++++++++++++ runprebuild48.sh | 26 +++++++++++++++++++++++++ 2 files changed, 74 insertions(+) create mode 100644 runprebuild48.bat create mode 100755 runprebuild48.sh diff --git a/runprebuild48.bat b/runprebuild48.bat new file mode 100644 index 00000000..151dd90f --- /dev/null +++ b/runprebuild48.bat @@ -0,0 +1,48 @@ +@echo OFF + +bin\Prebuild.exe /target vs2019 /targetframework v4_8 /excludedir = "obj | bin" + +setlocal ENABLEEXTENSIONS +set VALUE_NAME=MSBuildToolsPath + +if "%PROCESSOR_ARCHITECTURE%"=="x86" set PROGRAMS=%ProgramFiles% +if defined ProgramFiles(x86) set PROGRAMS=%ProgramFiles(x86)% + +set PROGRAMS64 = %PROGRAMS% +if defined ProgramFiles set PROGRAMS64=%ProgramFiles% + + +rem Try to find VS2019/22 +for %%e in (Community Enterprise Professional) do ( + if exist "%PROGRAMS64%\Microsoft Visual Studio\2022\%%e\MSBuild\Current\Bin\MSBuild.exe" ( + + set ValueValue="%PROGRAMS64%\Microsoft Visual Studio\2022\%%e\MSBuild\Current\Bin\MSBuild" + goto :found + ) + if exist "%PROGRAMS%\Microsoft Visual Studio\2019\%%e\MSBuild\Current\Bin\MSBuild.exe" ( + + set ValueValue="%PROGRAMS%\Microsoft Visual Studio\2019\%%e\MSBuild\Current\Bin\MSBuild" + goto :found + ) +) + + +@echo msbuild for at least VS2019 not found, please install a (Community) edition of VS2019 +@echo Not creating compile.bat +if exist "compile.bat" ( + del compile.bat + ) +goto :done + +:found + @echo Found msbuild at %ValueValue% + @echo Creating compile.bat +rem To compile in debug mode + @echo %ValueValue% opensim.sln > compile.bat +rem To compile in release mode comment line (add rem to start) above and uncomment next (remove rem) +rem @echo %ValueValue% /p:Configuration=Release opensim.sln > compile.bat +:done +if exist "bin\addin-db-002" ( + del /F/Q/S bin\addin-db-002 > NUL + rmdir /Q/S bin\addin-db-002 + ) \ No newline at end of file diff --git a/runprebuild48.sh b/runprebuild48.sh new file mode 100755 index 00000000..bb87334d --- /dev/null +++ b/runprebuild48.sh @@ -0,0 +1,26 @@ +#!/bin/sh + +case "$1" in + + 'clean') + + mono bin/Prebuild.exe /clean + + ;; + + + 'autoclean') + + echo y|mono bin/Prebuild.exe /clean + + ;; + + + + *) + + mono bin/Prebuild.exe /target vs2019 /targetframework v4_8 /excludedir = "obj | bin" + + ;; + +esac From d9ab33a95d4381f68ac26f3f34a8578ce81917c9 Mon Sep 17 00:00:00 2001 From: Ubit Umarov Date: Wed, 24 Aug 2022 20:25:09 +0100 Subject: [PATCH 052/149] Create dotnet.yml --- .github/workflows/dotnet.yml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 .github/workflows/dotnet.yml diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml new file mode 100644 index 00000000..d56809da --- /dev/null +++ b/.github/workflows/dotnet.yml @@ -0,0 +1,20 @@ +name: .NET + +on: + push: + branches: [ "master" ] + pull_request: + branches: [ "master" ] + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + - name: preBuild + run ./runprebuild48.sh + - name: Build + run: msbuild /p:Configuration=Release OpenMetaverse.sln + From 6ea3fe946bcf76585ab614534a3442dad0c1261a Mon Sep 17 00:00:00 2001 From: Ubit Umarov Date: Wed, 24 Aug 2022 20:28:30 +0100 Subject: [PATCH 053/149] Update dotnet.yml try again --- .github/workflows/dotnet.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index d56809da..b8c19b47 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -14,7 +14,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: preBuild - run ./runprebuild48.sh + run bash ${GITHUB_WORKSPACE}/runprebuild.sh - name: Build run: msbuild /p:Configuration=Release OpenMetaverse.sln From 6b4d54800ded01681587540d06baec2e4addbb2a Mon Sep 17 00:00:00 2001 From: Ubit Umarov Date: Wed, 24 Aug 2022 20:33:30 +0100 Subject: [PATCH 054/149] Update dotnet.yml try again --- .github/workflows/dotnet.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index b8c19b47..05c8b5fc 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -14,7 +14,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: preBuild - run bash ${GITHUB_WORKSPACE}/runprebuild.sh + run: bash ${GITHUB_WORKSPACE}/runprebuild.sh - name: Build run: msbuild /p:Configuration=Release OpenMetaverse.sln From 12e11d39490454f444f15174ce826f8afa6ca49b Mon Sep 17 00:00:00 2001 From: Ubit Umarov Date: Wed, 24 Aug 2022 20:41:34 +0100 Subject: [PATCH 055/149] Update dotnet.yml build 4.8 --- .github/workflows/dotnet.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 05c8b5fc..dc16f1ab 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -14,7 +14,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: preBuild - run: bash ${GITHUB_WORKSPACE}/runprebuild.sh + run: bash ${GITHUB_WORKSPACE}/runprebuild48.sh - name: Build run: msbuild /p:Configuration=Release OpenMetaverse.sln From 304d47854cf356b7d3890d5f473bd4306d2e50de Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Wed, 24 Aug 2022 20:45:55 +0100 Subject: [PATCH 056/149] update Prebuild.exe --- bin/Prebuild.exe | Bin 249856 -> 245760 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/bin/Prebuild.exe b/bin/Prebuild.exe index c99c15830c4ff0d74338137670e9f56d123a9235..1e4ef3fd668a389d4b0870a77d2c63eb1aa69e10 100755 GIT binary patch literal 245760 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 literal 249856 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

opq_jCDG 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 Date: Thu, 25 Aug 2022 02:59:48 +0100 Subject: [PATCH 057/149] Update dotnet.yml --- .github/workflows/dotnet.yml | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index dc16f1ab..0861bf69 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -1,4 +1,4 @@ -name: .NET +name: msbuild48 on: push: @@ -13,8 +13,17 @@ jobs: steps: - uses: actions/checkout@v3 + - name: shortsha + id: vars + run: echo "::set-output name=sha_short::$(git rev-parse --short HEAD)" - name: preBuild run: bash ${GITHUB_WORKSPACE}/runprebuild48.sh - name: Build run: msbuild /p:Configuration=Release OpenMetaverse.sln - + - name: release + run: zip -r LastBuild.zip bin LICENSE.txt + - uses: softprops/action-gh-release@v1 + with: + tag_name: ${{ steps.vars.outputs.sha_short }} + name: LastBuild + files: LastBuild.zip From be1265b1d2d8ae6cfff8a9a9c8daadc07b76be82 Mon Sep 17 00:00:00 2001 From: Ubit Umarov Date: Thu, 25 Aug 2022 05:57:13 +0100 Subject: [PATCH 058/149] Update dotnet.yml --- .github/workflows/dotnet.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 0861bf69..9eccd799 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -24,6 +24,6 @@ jobs: run: zip -r LastBuild.zip bin LICENSE.txt - uses: softprops/action-gh-release@v1 with: - tag_name: ${{ steps.vars.outputs.sha_short }} + tag_name: r${{ steps.vars.outputs.sha_short }} name: LastBuild files: LastBuild.zip From 8c63005ad984c745b12952881e65c84b920dda6d Mon Sep 17 00:00:00 2001 From: Ubit Umarov Date: Thu, 25 Aug 2022 05:58:24 +0100 Subject: [PATCH 059/149] Update dotnet.yml --- .github/workflows/dotnet.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 9eccd799..06994dfd 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -25,5 +25,5 @@ jobs: - uses: softprops/action-gh-release@v1 with: tag_name: r${{ steps.vars.outputs.sha_short }} - name: LastBuild + name: LastAutoBuild files: LastBuild.zip From f47129d9cb18e3e559fc1bea8b9dbea1494b1707 Mon Sep 17 00:00:00 2001 From: Ubit Umarov Date: Thu, 25 Aug 2022 06:16:32 +0100 Subject: [PATCH 060/149] Update dotnet.yml limit build to *.cs files changes --- .github/workflows/dotnet.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 06994dfd..d426f65f 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -3,8 +3,8 @@ name: msbuild48 on: push: branches: [ "master" ] - pull_request: - branches: [ "master" ] + paths: + - '**cs' jobs: build: From 845673eb0e6e0a8cea1f82e44a418044f17d390a Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Thu, 25 Aug 2022 06:31:08 +0100 Subject: [PATCH 061/149] add a few minor things we may need --- OpenMetaverseTypes/UtilsConversions.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/OpenMetaverseTypes/UtilsConversions.cs b/OpenMetaverseTypes/UtilsConversions.cs index b956868f..0084fbfa 100644 --- a/OpenMetaverseTypes/UtilsConversions.cs +++ b/OpenMetaverseTypes/UtilsConversions.cs @@ -157,7 +157,7 @@ static bool CheckDirectCopyBE() string.Empty, // 54 string.Empty, // 55 "settings", // 56 - string.Empty, // 57 + "material" // 57 }; private static readonly string[] _FolderTypeNames = new string[] @@ -188,7 +188,7 @@ static bool CheckDirectCopyBE() "favorite", // 23 string.Empty, // 24 "settings", // 25 - "ensemble", // 26 + "material", // 26 "ensemble", // 27 "ensemble", // 28 "ensemble", // 29 @@ -247,7 +247,7 @@ static bool CheckDirectCopyBE() string.Empty, // 23 string.Empty, // 24 "settings", // 25 - string.Empty, // 26 + "material", // 26 }; private static readonly string[] _SaleTypeNames = new string[] From 993df0a1841e6967fb50b7e61813df5b3545f37f Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Thu, 25 Aug 2022 06:40:30 +0100 Subject: [PATCH 062/149] update license --- LICENSE.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/LICENSE.txt b/LICENSE.txt index 43b484b2..426f81ff 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -1,4 +1,7 @@ + Copyright (c) Opensimulator, http://opensimulator.org/ + All rights reserved. + Copyright (c) 2006-2016, openmetaverse.co All rights reserved. From d40f2796fc45050e7aa09ec5ef695b89583557d9 Mon Sep 17 00:00:00 2001 From: Ubit Umarov Date: Fri, 26 Aug 2022 17:10:54 +0100 Subject: [PATCH 063/149] Update dotnet.yml --- .github/workflows/dotnet.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index d426f65f..cb60754b 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -4,11 +4,12 @@ on: push: branches: [ "master" ] paths: - - '**cs' - + - '**.cs' + workflow_dispatch: + jobs: build: - + if: github.repository == 'UbitUmarov/libopenmetaverse' runs-on: ubuntu-latest steps: From d466fa77c8c178fbcff45121fe3c2d5064494b94 Mon Sep 17 00:00:00 2001 From: Ubit Umarov Date: Sat, 27 Aug 2022 01:22:11 +0100 Subject: [PATCH 064/149] Create irc.yml --- .github/workflows/irc.yml | 40 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 .github/workflows/irc.yml diff --git a/.github/workflows/irc.yml b/.github/workflows/irc.yml new file mode 100644 index 00000000..ae8aa737 --- /dev/null +++ b/.github/workflows/irc.yml @@ -0,0 +1,40 @@ +name: irc + +on: + push: + branches: [ "master" ] + paths: + - '**.cs' + workflow_dispatch: + +jobs: + build: + if: github.repository == 'UbitUmarov/libopenmetaverse' + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + - name: shortsha + id: vars + run: echo "::set-output name=sha_short::$(git rev-parse --short HEAD)" + + - name: irc push + - uses: rectalogic/notify-irc@v1 + if: github.event_name == 'push' + with: + channel: "#opensim-dev" + server: "irc.libera.chat" + nickname: osGITHUB + message: | + ${{ github.actor }} pushed ${{ github.event.ref }} ${{ github.event.compare }} + ${{ join(github.event.commits.*.message) }} + + - name: irc work + - uses: rectalogic/notify-irc@v1 + if: github.event_name == 'workflow_dispatch' + with: + channel: "#opensim-dev" + server: "irc.libera.chat" + nickname: osGITHUB + message: | + 'testing' ${{ github.event.compare }} From 0a6e44351cfffb13cb53c8941f2f0bbb8f5dc362 Mon Sep 17 00:00:00 2001 From: Ubit Umarov Date: Sat, 27 Aug 2022 01:25:36 +0100 Subject: [PATCH 065/149] Update irc.yml --- .github/workflows/irc.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/irc.yml b/.github/workflows/irc.yml index ae8aa737..310f6f0b 100644 --- a/.github/workflows/irc.yml +++ b/.github/workflows/irc.yml @@ -19,7 +19,7 @@ jobs: run: echo "::set-output name=sha_short::$(git rev-parse --short HEAD)" - name: irc push - - uses: rectalogic/notify-irc@v1 + uses: rectalogic/notify-irc@v1 if: github.event_name == 'push' with: channel: "#opensim-dev" @@ -30,7 +30,7 @@ jobs: ${{ join(github.event.commits.*.message) }} - name: irc work - - uses: rectalogic/notify-irc@v1 + uses: rectalogic/notify-irc@v1 if: github.event_name == 'workflow_dispatch' with: channel: "#opensim-dev" From 1e2f80d24cee0ff618b13a32f1059a2ce3bf60b6 Mon Sep 17 00:00:00 2001 From: Ubit Umarov Date: Sat, 27 Aug 2022 01:38:52 +0100 Subject: [PATCH 066/149] Update irc.yml --- .github/workflows/irc.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/irc.yml b/.github/workflows/irc.yml index 310f6f0b..1fc8aadf 100644 --- a/.github/workflows/irc.yml +++ b/.github/workflows/irc.yml @@ -26,7 +26,7 @@ jobs: server: "irc.libera.chat" nickname: osGITHUB message: | - ${{ github.actor }} pushed ${{ github.event.ref }} ${{ github.event.compare }} + ${{ github.event.repository }}: ${{ github.actor }} pushed ${{ github.event.ref }} ${{ github.event.compare }} ${{ join(github.event.commits.*.message) }} - name: irc work @@ -37,4 +37,4 @@ jobs: server: "irc.libera.chat" nickname: osGITHUB message: | - 'testing' ${{ github.event.compare }} + 'testing' ${{ github.event.repository }} From a747b6dd5072e09331a04fc6b786eaccfd56e8e8 Mon Sep 17 00:00:00 2001 From: Ubit Umarov Date: Sat, 27 Aug 2022 01:43:21 +0100 Subject: [PATCH 067/149] Update irc.yml --- .github/workflows/irc.yml | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/.github/workflows/irc.yml b/.github/workflows/irc.yml index 1fc8aadf..b1ec6df2 100644 --- a/.github/workflows/irc.yml +++ b/.github/workflows/irc.yml @@ -8,25 +8,20 @@ on: workflow_dispatch: jobs: - build: + irc: if: github.repository == 'UbitUmarov/libopenmetaverse' runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - name: shortsha - id: vars - run: echo "::set-output name=sha_short::$(git rev-parse --short HEAD)" - + steps: - name: irc push uses: rectalogic/notify-irc@v1 if: github.event_name == 'push' with: channel: "#opensim-dev" server: "irc.libera.chat" - nickname: osGITHUB + nickname: osgithub message: | - ${{ github.event.repository }}: ${{ github.actor }} pushed ${{ github.event.ref }} ${{ github.event.compare }} + ${{ github.repository }}: ${{ github.actor }} pushed ${{ github.event.ref }} ${{ github.event.compare }} ${{ join(github.event.commits.*.message) }} - name: irc work @@ -35,6 +30,6 @@ jobs: with: channel: "#opensim-dev" server: "irc.libera.chat" - nickname: osGITHUB + nickname: osgithub message: | - 'testing' ${{ github.event.repository }} + 'testing' ${{ github.repository }} From 2a041cc6e84c6d67ed805308a445d6e4e5cfd5fe Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Sat, 27 Aug 2022 01:46:21 +0100 Subject: [PATCH 068/149] add unsafe UUID.ToBytes --- OpenMetaverseTypes/UUID.cs | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/OpenMetaverseTypes/UUID.cs b/OpenMetaverseTypes/UUID.cs index 82709bf9..c3ac220e 100644 --- a/OpenMetaverseTypes/UUID.cs +++ b/OpenMetaverseTypes/UUID.cs @@ -508,6 +508,35 @@ public unsafe void ToBytes(byte[] dest, int pos) } } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe void ToBytes(byte* ptr) + { + if (BitConverter.IsLittleEndian) + { + *ptr = bytea3; + *(ptr + 1) = bytea2; + *(ptr + 2) = bytea1; + *(ptr + 3) = bytea0; + *(ptr + 4) = byteb1; + *(ptr + 5) = byteb0; + *(ptr + 6) = bytec1; + *(ptr + 7) = bytec0; + *(ulong*)(ptr + 8) = ulongb; + } + else + { + *(ulong*)(ptr) = ulonga; + *(ptr + 8) = d; + *(ptr + 9) = e; + *(ptr + 10) = f; + *(ptr + 11) = g; + *(ptr + 12) = h; + *(ptr + 13) = i; + *(ptr + 14) = j; + *(ptr + 15) = k; + } + } + ///

/// Calculate an LLCRC (cyclic redundancy check) for this UUID /// From 80c2d45b544405c3c359469920dd0cf1d7e22e3c Mon Sep 17 00:00:00 2001 From: Ubit Umarov Date: Sat, 27 Aug 2022 02:08:45 +0100 Subject: [PATCH 069/149] Update irc.yml --- .github/workflows/irc.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/irc.yml b/.github/workflows/irc.yml index b1ec6df2..e5059543 100644 --- a/.github/workflows/irc.yml +++ b/.github/workflows/irc.yml @@ -21,8 +21,8 @@ jobs: server: "irc.libera.chat" nickname: osgithub message: | - ${{ github.repository }}: ${{ github.actor }} pushed ${{ github.event.ref }} ${{ github.event.compare }} - ${{ join(github.event.commits.*.message) }} + ${{ github.actor }} pushed to ${{ github.repository }} + ${{ join(github.event.commits.*.message, '\n') }} - name: irc work uses: rectalogic/notify-irc@v1 From e43299a987c36afe6e419919b777688574ed7f4d Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Sat, 27 Aug 2022 02:10:10 +0100 Subject: [PATCH 070/149] add unsafe Vector3.ToBytes --- OpenMetaverseTypes/Vector3.cs | 37 +++++++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/OpenMetaverseTypes/Vector3.cs b/OpenMetaverseTypes/Vector3.cs index ba6b05d1..f0a8049e 100644 --- a/OpenMetaverseTypes/Vector3.cs +++ b/OpenMetaverseTypes/Vector3.cs @@ -305,11 +305,40 @@ public byte[] GetBytes() /// Position in the destination array to start /// writing. Must be at least 12 bytes before the end of the array [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToBytes(byte[] dest, int pos) + public unsafe void ToBytes(byte[] dest, int pos) { - Utils.FloatToBytesSafepos(X, dest, pos); - Utils.FloatToBytesSafepos(Y, dest, pos + 4); - Utils.FloatToBytesSafepos(Z, dest, pos + 8); + if (Utils.CanDirectCopyLE) + { + fixed (byte* d = &dest[0]) + { + *(float*)(d + pos) = X; + *(float*)(d + pos + 4) = Y; + *(float*)(d + pos + 8) = Z; + } + } + else + { + Utils.FloatToBytesSafepos(X, dest, pos); + Utils.FloatToBytesSafepos(Y, dest, pos + 4); + Utils.FloatToBytesSafepos(Z, dest, pos + 8); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe void ToBytes(byte* dest) + { + if (Utils.CanDirectCopyLE) + { + *(float*)(dest) = X; + *(float*)(dest + 4) = Y; + *(float*)(dest + 8) = Z; + } + else + { + Utils.FloatToBytes(X, dest); + Utils.FloatToBytes(Y, dest); + Utils.FloatToBytes(Z, dest); + } } #endregion Public Methods From e345ae8d0028c468173312c07e86826866906fd8 Mon Sep 17 00:00:00 2001 From: Ubit Umarov Date: Sat, 27 Aug 2022 02:30:14 +0100 Subject: [PATCH 071/149] Update irc.yml --- .github/workflows/irc.yml | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/.github/workflows/irc.yml b/.github/workflows/irc.yml index e5059543..484b487e 100644 --- a/.github/workflows/irc.yml +++ b/.github/workflows/irc.yml @@ -5,14 +5,16 @@ on: branches: [ "master" ] paths: - '**.cs' - workflow_dispatch: jobs: - irc: + ircPush: if: github.repository == 'UbitUmarov/libopenmetaverse' runs-on: ubuntu-latest - steps: + steps: + - name: shortsha + id: vars + run: echo "::set-output name=sha_short::$(git rev-parse --short HEAD)" - name: irc push uses: rectalogic/notify-irc@v1 if: github.event_name == 'push' @@ -21,15 +23,5 @@ jobs: server: "irc.libera.chat" nickname: osgithub message: | - ${{ github.actor }} pushed to ${{ github.repository }} + ${{ github.actor }} pushed to ${{ github.repository }} ${{ steps.vars.outputs.sha_short }} ${{ join(github.event.commits.*.message, '\n') }} - - - name: irc work - uses: rectalogic/notify-irc@v1 - if: github.event_name == 'workflow_dispatch' - with: - channel: "#opensim-dev" - server: "irc.libera.chat" - nickname: osgithub - message: | - 'testing' ${{ github.repository }} From 07567786a5bdfc5399011450e972c855d718ead3 Mon Sep 17 00:00:00 2001 From: Ubit Umarov Date: Sat, 27 Aug 2022 03:32:04 +0100 Subject: [PATCH 072/149] Update dotnet.yml --- .github/workflows/dotnet.yml | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index cb60754b..d05a505e 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -13,18 +13,41 @@ jobs: runs-on: ubuntu-latest steps: + - name: checkout - uses: actions/checkout@v3 - - name: shortsha + - name: readshortsha id: vars run: echo "::set-output name=sha_short::$(git rev-parse --short HEAD)" - name: preBuild run: bash ${GITHUB_WORKSPACE}/runprebuild48.sh - name: Build - run: msbuild /p:Configuration=Release OpenMetaverse.sln + id: build + run: echo "::set-output name=errors::$(msbuild /p:Configuration=Release OpenMetaverse.sln)" - name: release + if: success() run: zip -r LastBuild.zip bin LICENSE.txt - uses: softprops/action-gh-release@v1 with: tag_name: r${{ steps.vars.outputs.sha_short }} name: LastAutoBuild - files: LastBuild.zip + files: LastBuild.zip + - name: report push to irc + if: github.event_name == 'push' + uses: rectalogic/notify-irc@v1 + with: + channel: "#opensim-dev" + server: "irc.libera.chat" + nickname: osgithub + message: | + ${{ github.actor }} pushed to ${{ github.repository }} + ${{ join(github.event.commits.*.message, '\n') }} + compiled errors: ${{ steps.build.outputs.errors }} + - name: report manual irc + if: github.event_name == 'push' + uses: rectalogic/notify-irc@v1 + with: + channel: "#opensim-dev" + server: "irc.libera.chat" + nickname: osgithub + message: | + ${{ github.repository }} compiled errors: ${{ steps.build.outputs.errors }} From 8e67a670945a4dfa3966b4e08b30a2979dd6698b Mon Sep 17 00:00:00 2001 From: Ubit Umarov Date: Sat, 27 Aug 2022 03:35:40 +0100 Subject: [PATCH 073/149] Update dotnet.yml --- .github/workflows/dotnet.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index d05a505e..601d371c 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -13,7 +13,6 @@ jobs: runs-on: ubuntu-latest steps: - - name: checkout - uses: actions/checkout@v3 - name: readshortsha id: vars @@ -27,6 +26,7 @@ jobs: if: success() run: zip -r LastBuild.zip bin LICENSE.txt - uses: softprops/action-gh-release@v1 + if: success() with: tag_name: r${{ steps.vars.outputs.sha_short }} name: LastAutoBuild From 3d6f168e580d79a3b6aad3603ea39c2f80e4ed30 Mon Sep 17 00:00:00 2001 From: Ubit Umarov Date: Sat, 27 Aug 2022 03:54:12 +0100 Subject: [PATCH 074/149] Update dotnet.yml --- .github/workflows/dotnet.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 601d371c..25865280 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -21,7 +21,7 @@ jobs: run: bash ${GITHUB_WORKSPACE}/runprebuild48.sh - name: Build id: build - run: echo "::set-output name=errors::$(msbuild /p:Configuration=Release OpenMetaverse.sln)" + run: msbuild /p:Configuration=Release OpenMetaverse.sln - name: release if: success() run: zip -r LastBuild.zip bin LICENSE.txt @@ -41,7 +41,7 @@ jobs: message: | ${{ github.actor }} pushed to ${{ github.repository }} ${{ join(github.event.commits.*.message, '\n') }} - compiled errors: ${{ steps.build.outputs.errors }} + compile ${{ steps.build.conclusion }} - name: report manual irc if: github.event_name == 'push' uses: rectalogic/notify-irc@v1 @@ -50,4 +50,4 @@ jobs: server: "irc.libera.chat" nickname: osgithub message: | - ${{ github.repository }} compiled errors: ${{ steps.build.outputs.errors }} + ${{ github.repository }} compile: ${{ steps.build.conclusion }} From 1d89b8577f43df786057bba3e99861c2ff78006b Mon Sep 17 00:00:00 2001 From: Ubit Umarov Date: Sat, 27 Aug 2022 03:57:19 +0100 Subject: [PATCH 075/149] Update dotnet.yml --- .github/workflows/dotnet.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 25865280..2ec4924a 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -43,7 +43,7 @@ jobs: ${{ join(github.event.commits.*.message, '\n') }} compile ${{ steps.build.conclusion }} - name: report manual irc - if: github.event_name == 'push' + if: github.event_name == 'workflow_dispatch' uses: rectalogic/notify-irc@v1 with: channel: "#opensim-dev" From c94cb9b3eb4d5fed56206396ebeadf8c5f0b90b5 Mon Sep 17 00:00:00 2001 From: Ubit Umarov Date: Sat, 27 Aug 2022 04:00:10 +0100 Subject: [PATCH 076/149] Update dotnet.yml --- .github/workflows/dotnet.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 2ec4924a..df48378a 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -41,7 +41,7 @@ jobs: message: | ${{ github.actor }} pushed to ${{ github.repository }} ${{ join(github.event.commits.*.message, '\n') }} - compile ${{ steps.build.conclusion }} + mono compile: ${{ steps.build.conclusion }} - name: report manual irc if: github.event_name == 'workflow_dispatch' uses: rectalogic/notify-irc@v1 @@ -50,4 +50,5 @@ jobs: server: "irc.libera.chat" nickname: osgithub message: | - ${{ github.repository }} compile: ${{ steps.build.conclusion }} + ${{ github.repository }} + mono compile: ${{ steps.build.conclusion }} From 2d16f9f163ad2b31d4362c09148e9960d611e1e8 Mon Sep 17 00:00:00 2001 From: Ubit Umarov Date: Sat, 27 Aug 2022 04:02:22 +0100 Subject: [PATCH 077/149] Delete irc.yml --- .github/workflows/irc.yml | 27 --------------------------- 1 file changed, 27 deletions(-) delete mode 100644 .github/workflows/irc.yml diff --git a/.github/workflows/irc.yml b/.github/workflows/irc.yml deleted file mode 100644 index 484b487e..00000000 --- a/.github/workflows/irc.yml +++ /dev/null @@ -1,27 +0,0 @@ -name: irc - -on: - push: - branches: [ "master" ] - paths: - - '**.cs' - -jobs: - ircPush: - if: github.repository == 'UbitUmarov/libopenmetaverse' - runs-on: ubuntu-latest - - steps: - - name: shortsha - id: vars - run: echo "::set-output name=sha_short::$(git rev-parse --short HEAD)" - - name: irc push - uses: rectalogic/notify-irc@v1 - if: github.event_name == 'push' - with: - channel: "#opensim-dev" - server: "irc.libera.chat" - nickname: osgithub - message: | - ${{ github.actor }} pushed to ${{ github.repository }} ${{ steps.vars.outputs.sha_short }} - ${{ join(github.event.commits.*.message, '\n') }} From 22a93b3cfd035c3560b9d11e1d16b7e358f1181c Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Sun, 28 Aug 2022 01:42:15 +0100 Subject: [PATCH 078/149] add a few more unsafe ToBytes* --- OpenMetaverseTypes/Quaternion.cs | 149 +++++++++++++++- OpenMetaverseTypes/UtilsConversions.cs | 227 ++++++++++++++++++------- OpenMetaverseTypes/Vector2.cs | 26 ++- OpenMetaverseTypes/Vector3.cs | 145 ++++++++++++++-- OpenMetaverseTypes/Vector4.cs | 33 +++- prebuild.xml | 5 - 6 files changed, 493 insertions(+), 92 deletions(-) diff --git a/OpenMetaverseTypes/Quaternion.cs b/OpenMetaverseTypes/Quaternion.cs index 3c66aa3e..848c20c2 100644 --- a/OpenMetaverseTypes/Quaternion.cs +++ b/OpenMetaverseTypes/Quaternion.cs @@ -304,7 +304,7 @@ public byte[] GetBytes() /// Destination byte array /// Position in the destination array to start /// writing. Must be at least 12 bytes before the end of the array - public void ToBytes(byte[] dest, int pos) + public unsafe void ToBytes(byte[] dest, int pos) { float norm = LengthSquared(); if (norm > 1e-6f || norm < 0.9999f) @@ -313,15 +313,150 @@ public void ToBytes(byte[] dest, int pos) norm = -1f / (float)Math.Sqrt(norm); else norm = 1f / (float)Math.Sqrt(norm); - Utils.FloatToBytesSafepos(norm * X, dest, pos); - Utils.FloatToBytesSafepos(norm * Y, dest, pos + 4); - Utils.FloatToBytesSafepos(norm * Z, dest, pos + 8); + if (Utils.CanDirectCopyLE) + { + fixed (byte* d = &dest[0]) + { + *(float*)(d + pos) = norm * X; + *(float*)(d + pos + 4) = norm * Y; + *(float*)(d + pos + 8) = norm * Z; + } + } + else + { + Utils.FloatToBytesSafepos(norm * X, dest, pos); + Utils.FloatToBytesSafepos(norm * Y, dest, pos + 4); + Utils.FloatToBytesSafepos(norm * Z, dest, pos + 8); + } + } + else + { + if (Utils.CanDirectCopyLE) + { + fixed (byte* d = &dest[0]) + { + *(long*)(d + pos) = 0; + *(int*)(d + pos + 8) = 0; + } + } + else + { + Utils.FloatToBytesSafepos(0, dest, pos); + Utils.FloatToBytesSafepos(0, dest, pos + 4); + Utils.FloatToBytesSafepos(0, dest, pos + 8); + } + } + } + + public unsafe void ToBytes(byte* dest) + { + float norm = LengthSquared(); + if (norm > 1e-6f || norm < 0.9999f) + { + if (W < 0f) + norm = -1f / (float)Math.Sqrt(norm); + else + norm = 1f / (float)Math.Sqrt(norm); + if (Utils.CanDirectCopyLE) + { + *(float*)(dest) = norm * X; + *(float*)(dest + 4) = norm * Y; + *(float*)(dest + 8) = norm * Z; + } + else + { + Utils.FloatToBytes(norm * X, dest); + Utils.FloatToBytes(norm * Y, dest + 4); + Utils.FloatToBytes(norm * Z, dest + 8); + } + } + else + { + if (Utils.CanDirectCopyLE) + { + *(long*)dest = 0; + *(int*)(dest + 8) = 0; + } + else + { + Utils.FloatToBytes(0, dest); + Utils.FloatToBytes(0, dest + 4); + Utils.FloatToBytes(0, dest + 8); + } + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe void ToShortsBytes(byte[] dest, int pos) + { + ushort sx = Utils.FloatToUnitUInt16(X); + ushort sy = Utils.FloatToUnitUInt16(Y); + ushort sz = Utils.FloatToUnitUInt16(Z); + ushort sw = Utils.FloatToUnitUInt16(W); + + if (Utils.CanDirectCopyLE) + { + fixed (byte* d = &dest[0]) + { + *(ushort*)(d + pos) = sx; + *(ushort*)(d + pos + 2) = sy; + *(ushort*)(d + pos + 4) = sz; + *(ushort*)(d + pos + 6) = sw; + } + } + else + { + Utils.UInt16ToBytes(sx, dest, pos); + Utils.UInt16ToBytes(sy, dest, pos + 2); + Utils.UInt16ToBytes(sz, dest, pos + 4); + Utils.UInt16ToBytes(sw, dest, pos + 6); + } + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe void ToShortsBytes(byte* dest, int pos) + { + ushort sx = Utils.FloatToUnitUInt16(X); + ushort sy = Utils.FloatToUnitUInt16(Y); + ushort sz = Utils.FloatToUnitUInt16(Z); + ushort sw = Utils.FloatToUnitUInt16(W); + + if (Utils.CanDirectCopyLE) + { + *(ushort*)(dest + pos) = sx; + *(ushort*)(dest + pos + 2) = sy; + *(ushort*)(dest + pos + 4) = sz; + *(ushort*)(dest + pos + 6) = sw; + } + else + { + Utils.UInt16ToBytes(sx, dest, pos); + Utils.UInt16ToBytes(sy, dest, pos + 2); + Utils.UInt16ToBytes(sz, dest, pos + 4); + Utils.UInt16ToBytes(sw, dest, pos + 6); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe void ToShortsBytes(byte* dest) + { + ushort sx = Utils.FloatToUnitUInt16(X); + ushort sy = Utils.FloatToUnitUInt16(Y); + ushort sz = Utils.FloatToUnitUInt16(Z); + ushort sw = Utils.FloatToUnitUInt16(W); + + if (Utils.CanDirectCopyLE) + { + *(ushort*)(dest) = sx; + *(ushort*)(dest + 2) = sy; + *(ushort*)(dest + 4) = sz; + *(ushort*)(dest + 6) = sw; } else { - Utils.FloatToBytesSafepos(0, dest, pos); - Utils.FloatToBytesSafepos(0, dest, pos + 4); - Utils.FloatToBytesSafepos(0, dest, pos + 8); + Utils.UInt16ToBytes(sx, dest); + Utils.UInt16ToBytes(sy, dest + 2); + Utils.UInt16ToBytes(sz, dest + 4); + Utils.UInt16ToBytes(sw, dest + 6); } } diff --git a/OpenMetaverseTypes/UtilsConversions.cs b/OpenMetaverseTypes/UtilsConversions.cs index 0084fbfa..68caec0b 100644 --- a/OpenMetaverseTypes/UtilsConversions.cs +++ b/OpenMetaverseTypes/UtilsConversions.cs @@ -453,7 +453,7 @@ public unsafe static int BytesToInt(byte* bytes) { if (CanDirectCopyLE) { - return *(int*)bytes; + return *(int*)bytes; } return *bytes | @@ -765,9 +765,10 @@ public unsafe static uint BytesToUInt(byte* bytes) [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static ulong BytesToUInt64(byte[] bytes, int pos) { + if (bytes.Length < pos + 8) return 0; if (CanDirectCopyLE) { - if (bytes.Length < pos + 8) return 0; + //return Unsafe.As(ref bytes[pos]); fixed (byte* p = &bytes[pos]) return *(ulong*)p; } @@ -861,8 +862,9 @@ public unsafe static ulong BytesToUInt64(byte* bytes) [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static float BytesToFloat(byte[] bytes) { - int tmp = BytesToInt(bytes); - return *(float*)&tmp; + int tmp = BytesToInt(bytes); + return *(float*)&tmp; + //return Unsafe.As(ref bytes[0]); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -928,8 +930,8 @@ public unsafe static double BytesToDoubleSafepos(byte[] bytes, int pos) public static byte[] Int16ToBytes(short value) { byte[] bytes = new byte[2]; - bytes[0] = (byte)(value); - bytes[1] = (byte)((value >> 8)); + bytes[0] = (byte)value; + bytes[1] = (byte)(value >> 8); return bytes; } @@ -943,52 +945,74 @@ public static void Int16ToBytes(Stream ms, short value) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Int16ToBytes(short value, byte[] dest, int pos) { - dest[pos] = (byte)(value); - dest[pos + 1] = (byte)((value >> 8)); + dest[pos] = (byte)value; + dest[pos + 1] = (byte)(value >> 8); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static unsafe void Int16ToBytes(short value, byte* dest) { - *dest = (byte)(value); - dest[1] = (byte)((value >> 8)); + *(short*)dest = value; + //*dest = (byte)value; + //dest[1] = (byte)(value >> 8); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static unsafe void Int16ToBytes(short value, byte* dest, int pos) + { + *(short*)dest[pos] = value; + //*dest = (byte)value; + //dest[1] = (byte)(value >> 8); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static byte[] UInt16ToBytes(ushort value) { byte[] bytes = new byte[2]; - bytes[0] = (byte)(value); - bytes[1] = (byte)((value >> 8)); + bytes[0] = (byte)value; + bytes[1] = (byte)(value >> 8); return bytes; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void UInt16ToBytes(ushort value, byte[] dest, int pos) { - dest[pos] = (byte)(value); - dest[pos + 1] = (byte)((value >> 8)); + //Unsafe.As(ref dest[pos]) = value; + dest[pos] = (byte)value; + dest[pos + 1] = (byte)(value >> 8); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static unsafe void UInt16ToBytes(ushort value, byte* dest, int pos) + { + *(ushort*)dest[pos] = value; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static unsafe void UInt16ToBytes(ushort value, byte* dest) { - *dest = (byte)(value); - dest[1] = (byte)((value >> 8)); + *(ushort*)dest = value; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void UInt16ToBytesBig(ushort value, byte[] dest, int pos) { - dest[pos] = (byte)((value >> 8)); - dest[pos + 1] = (byte)(value); + dest[pos] = (byte)(value >> 8); + dest[pos + 1] = (byte)value; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static void UInt16ToBytesBig(ushort value, byte* dest, int pos) + { + dest[pos] = (byte)(value >> 8); + dest[pos + 1] = (byte)value; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static unsafe void UInt16ToBytesBig(ushort value, byte* dest) { - *dest = (byte)((value >> 8)); - dest[1] = (byte)(value); + *dest = (byte)(value >> 8); + dest[1] = (byte)value; } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -1027,9 +1051,10 @@ public unsafe static byte[] IntToBytes(int value) [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void IntToBytes(int value, byte[] dest, int pos) { + if (dest.Length < pos + 4) return; if (CanDirectCopyLE) { - if (dest.Length < pos + 4) return; + //Unsafe.As(ref dest[pos]) = value; fixed (byte* p = &dest[pos]) *(int*)p = value; } @@ -1041,6 +1066,21 @@ public unsafe static void IntToBytes(int value, byte[] dest, int pos) dest[pos + 3] = (byte)((value >> 24)); } } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static void IntToBytes(int value, byte* dest, int pos) + { + if (CanDirectCopyLE) + { + *(int*)dest[pos] = value; + } + else + { + dest[pos] = (byte)(value); + dest[pos + 1] = (byte)((value >> 8)); + dest[pos + 2] = (byte)((value >> 16)); + dest[pos + 3] = (byte)((value >> 24)); + } + } [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void IntToBytes(int value, byte* dest) @@ -1103,6 +1143,15 @@ public static void IntToBytesBig(int value, byte[] bytes, int pos) bytes[pos + 3] = (byte)value; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static void IntToBytesBig(int value, byte* bytes, int pos) + { + bytes[pos] = (byte)(value >> 24); + bytes[pos + 1] = (byte)(value >> 16); + bytes[pos + 2] = (byte)(value >> 8); + bytes[pos + 3] = (byte)value; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static unsafe void IntToBytesBig(int value, byte* bytes) { @@ -1118,12 +1167,24 @@ public unsafe static byte[] UIntToBytes(uint value) return IntToBytes((int)value); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static void UIntToBytes(uint value, byte* dest) + { + IntToBytes((int)value, dest); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void UIntToBytes(uint value, byte[] dest, int pos) { IntToBytes((int)value, dest, pos); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static void UIntToBytes(uint value, byte* dest, int pos) + { + IntToBytes((int)value, dest, pos); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void UIntToBytesSafepos(uint value, byte[] dest, int pos) { @@ -1186,6 +1247,27 @@ public unsafe static void Int64ToBytes(long value, byte[] dest, int pos) } } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static void Int64ToBytes(long value, byte* dest, int pos) + { + if (CanDirectCopyLE) + { + //Unsafe.As(ref dest[pos]) = value; + *(long*)dest[pos] = value; + } + else + { + dest[pos] = (byte)value; + dest[pos + 1] = (byte)(value >> 8); + dest[pos + 2] = (byte)(value >> 16); + dest[pos + 3] = (byte)(value >> 24); + dest[pos + 4] = (byte)(value >> 32); + dest[pos + 5] = (byte)(value >> 40); + dest[pos + 6] = (byte)(value >> 48); + dest[pos + 7] = (byte)(value >> 56); + } + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void Int64ToBytes(long value, byte* dest) { @@ -1240,7 +1322,6 @@ public static void Int64ToBytes(Stream ms, long value) ms.WriteByte((byte)(value >> 56)); } - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static byte[] Int64ToBytesBig(long value) { @@ -1269,6 +1350,19 @@ public static void Int64ToBytesBig(long value, byte[] dest, int pos) dest[pos + 7] = (byte)value; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static void Int64ToBytesBig(long value, byte* dest, int pos) + { + dest[pos] = (byte)(value >> 56); + dest[pos + 1] = (byte)(value >> 48); + dest[pos + 2] = (byte)(value >> 40); + dest[pos + 3] = (byte)(value >> 32); + dest[pos + 4] = (byte)(value >> 24); + dest[pos + 5] = (byte)(value >> 16); + dest[pos + 6] = (byte)(value >> 8); + dest[pos + 7] = (byte)value; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static unsafe void Int64ToBytesBig(long value, byte* dest) { @@ -1300,12 +1394,24 @@ public static byte[] UInt64ToBytesBig(ulong value) return Int64ToBytesBig((long)value); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static void UInt64ToBytes(ulong value, byte* dest) + { + Int64ToBytes((long)value, dest); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void UInt64ToBytes(ulong value, byte[] dest, int pos) { Int64ToBytes((long)value, dest, pos); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static void UInt64ToBytes(ulong value, byte* dest, int pos) + { + Int64ToBytes((long)value, dest, pos); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void UInt64ToBytesSafepos(ulong value, byte[] dest, int pos) { @@ -1340,6 +1446,14 @@ public unsafe static void FloatToBytes(Stream ms, float value) [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void FloatToBytes(float value, byte[] dest, int pos) { + //Unsafe.As(ref dest[pos]) = value; + IntToBytes(*(int*)&value, dest, pos); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static void FloatToBytes(float value, byte* dest, int pos) + { + //Unsafe.As(ref dest[pos]) = value; IntToBytes(*(int*)&value, dest, pos); } @@ -1379,6 +1493,12 @@ public unsafe static void DoubleToBytes(double value, byte[] dest, int pos) Int64ToBytes(*(long*)&value, dest, pos); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static void DoubleToBytes(double value, byte* dest, int pos) + { + Int64ToBytes(*(long*)&value, dest, pos); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void DoubleToBytes(double value, byte* dest) { @@ -2130,6 +2250,7 @@ public static ushort FloatToUInt16(float value, float lower, float upper) return (ushort)(value * 0xffff); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ushort FloatToUInt16(float value, float range) { value += range; @@ -2143,53 +2264,39 @@ public static ushort FloatToUInt16(float value, float range) return (ushort)(value * 32767.5); } - public static void FloatToUInt16Bytes(float value, float range, byte[] dest, int pos) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ushort FloatToUnitUInt16(float value) { - value += range; - if (value <= 0) - { - dest[pos] = 0; - dest[pos + 1] = 0; - return; - } + if (value <= -1.0) + return 0; - value /= range; - if (value >= 2.0f) - { - dest[pos] = 0xff; - dest[pos + 1] = 0xff; - return; - } + if (value >= 1.0f) + return 0xffff; - ushort s = (ushort)(value * 32767.5); - dest[pos] = (byte)s; - dest[pos + 1] = (byte)(s >> 8); + return (ushort)(value * 32767.5 + 32767); } - public static byte[] FloatToUInt16Bytes(float value, float range) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void FloatToUInt16Bytes(float value, float range, byte[] dest, int pos) { - byte[] dest = new byte[2]; + UInt16ToBytes(FloatToUInt16(value, range), dest, pos); + } - value += range; - if (value <= 0) - { - dest[0] = 0; - dest[1] = 0; - return dest; - } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static void FloatToUInt16Bytes(float value, float range, byte* dest, int pos) + { + UInt16ToBytes(FloatToUInt16(value, range), dest, pos); + } - value /= range; - if (value >= 2.0f) - { - dest[0] = 0xff; - dest[1] = 0xff; - return dest; - } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static void FloatToUInt16Bytes(float value, float range, byte* dest) + { + UInt16ToBytes(FloatToUInt16(value, range), dest); + } - ushort s = (ushort)(value * 32767.5); - dest[0] = (byte)s; - dest[1] = (byte)(s >> 8); - return dest; + public unsafe static byte[] FloatToUInt16Bytes(float value, float range) + { + return UInt16ToBytes(FloatToUInt16(value, range)); } #endregion Packed Values diff --git a/OpenMetaverseTypes/Vector2.cs b/OpenMetaverseTypes/Vector2.cs index 2febaa9a..201bc0a6 100644 --- a/OpenMetaverseTypes/Vector2.cs +++ b/OpenMetaverseTypes/Vector2.cs @@ -210,10 +210,30 @@ public byte[] GetBytes() /// Position in the destination array to start /// writing. Must be at least 8 bytes before the end of the array [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public void ToBytes(byte[] dest, int pos) + public unsafe void ToBytes(byte[] dest, int pos) { - Utils.FloatToBytesSafepos(X, dest, pos); - Utils.FloatToBytesSafepos(Y, dest, pos + 4); + if (Utils.CanDirectCopyLE) + { + fixed (byte* d = &dest[0]) + *(Vector2*)(d + pos) = this; + } + else + { + Utils.FloatToBytesSafepos(X, dest, pos); + Utils.FloatToBytesSafepos(Y, dest, pos + 4); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe void ToBytes(byte* dest) + { + if (Utils.CanDirectCopyLE) + *(Vector2*)(dest) = this; + else + { + Utils.FloatToBytes(X, dest); + Utils.FloatToBytes(Y, dest + 4); + } } [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] diff --git a/OpenMetaverseTypes/Vector3.cs b/OpenMetaverseTypes/Vector3.cs index f0a8049e..0369bce1 100644 --- a/OpenMetaverseTypes/Vector3.cs +++ b/OpenMetaverseTypes/Vector3.cs @@ -25,9 +25,9 @@ */ using System; +using System.Globalization; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -using System.Globalization; namespace OpenMetaverse { @@ -310,11 +310,7 @@ public unsafe void ToBytes(byte[] dest, int pos) if (Utils.CanDirectCopyLE) { fixed (byte* d = &dest[0]) - { - *(float*)(d + pos) = X; - *(float*)(d + pos + 4) = Y; - *(float*)(d + pos + 8) = Z; - } + *(Vector3*)(d + pos) = this; } else { @@ -328,16 +324,141 @@ public unsafe void ToBytes(byte[] dest, int pos) public unsafe void ToBytes(byte* dest) { if (Utils.CanDirectCopyLE) + *(Vector3*)dest = this; + else + { + Utils.FloatToBytes(X, dest); + Utils.FloatToBytes(Y, dest + 4); + Utils.FloatToBytes(Z, dest + 8); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe void ClampedToShortsBytes(float range, byte[] dest, int pos) + { + float a, b; + + a = Math.Abs(X); + b = Math.Abs(Y); + if (b > a) + a = b; + b = Math.Abs(Z); + if (b > a) + a = b; + + ushort sx, sy, sz; + if (a > range) { - *(float*)(dest) = X; - *(float*)(dest + 4) = Y; - *(float*)(dest + 8) = Z; + a = range / a; + sx = Utils.FloatToUInt16(X * a, range); + sy = Utils.FloatToUInt16(Y * a, range); + sz = Utils.FloatToUInt16(Z * a, range); } else { - Utils.FloatToBytes(X, dest); - Utils.FloatToBytes(Y, dest); - Utils.FloatToBytes(Z, dest); + sx = Utils.FloatToUInt16(X, range); + sy = Utils.FloatToUInt16(Y, range); + sz = Utils.FloatToUInt16(Z, range); + } + + if (Utils.CanDirectCopyLE) + { + fixed (byte* d = &dest[0]) + { + *(ushort*)(d + pos) = sx; + *(ushort*)(d + pos + 2) = sy; + *(ushort*)(d + pos + 4) = sz; + } + } + else + { + Utils.UInt16ToBytes(sx, dest, pos); + Utils.UInt16ToBytes(sy, dest, pos + 2); + Utils.UInt16ToBytes(sz, dest, pos + 4); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe void ClampedToShortsBytes(float range, byte* dest, int pos) + { + float a, b; + + a = Math.Abs(X); + b = Math.Abs(Y); + if (b > a) + a = b; + b = Math.Abs(Z); + if (b > a) + a = b; + + ushort sx, sy, sz; + if (a > range) + { + a = range / a; + sx = Utils.FloatToUInt16(X * a, range); + sy = Utils.FloatToUInt16(Y * a, range); + sz = Utils.FloatToUInt16(Z * a, range); + } + else + { + sx = Utils.FloatToUInt16(X, range); + sy = Utils.FloatToUInt16(Y, range); + sz = Utils.FloatToUInt16(Z, range); + } + + if (Utils.CanDirectCopyLE) + { + *(ushort*)(dest + pos) = sx; + *(ushort*)(dest + pos + 2) = sy; + *(ushort*)(dest + pos + 4) = sz; + } + else + { + Utils.UInt16ToBytes(sx, dest, pos); + Utils.UInt16ToBytes(sy, dest, pos + 2); + Utils.UInt16ToBytes(sz, dest, pos + 4); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe void ClampedToShortsBytes(float range, byte* dest) + { + float a, b; + + a = Math.Abs(X); + b = Math.Abs(Y); + if (b > a) + a = b; + b = Math.Abs(Z); + if (b > a) + a = b; + + ushort sx, sy, sc; + if (a > range) + { + a = range / a; + sx = Utils.FloatToUInt16(X * a, range); + sy = Utils.FloatToUInt16(Y * a, range); + sc = Utils.FloatToUInt16(Z * a, range); + } + else + { + sx = Utils.FloatToUInt16(X, range); + sy = Utils.FloatToUInt16(Y, range); + sc = Utils.FloatToUInt16(Z, range); + } + + if (Utils.CanDirectCopyLE) + { + *(ushort*)(dest) = sx; + *(ushort*)(dest + 2) = sy; + *(ushort*)(dest + 4) = sc; + } + else + { + Utils.UInt16ToBytes(sx, dest); + Utils.UInt16ToBytes(sy, dest + 2); + Utils.UInt16ToBytes(sc, dest + 4); } } diff --git a/OpenMetaverseTypes/Vector4.cs b/OpenMetaverseTypes/Vector4.cs index 2a63caee..fd869b15 100644 --- a/OpenMetaverseTypes/Vector4.cs +++ b/OpenMetaverseTypes/Vector4.cs @@ -276,12 +276,35 @@ public byte[] GetBytes() /// Destination byte array /// Position in the destination array to start /// writing. Must be at least 16 bytes before the end of the array - public void ToBytes(byte[] dest, int pos) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe void ToBytes(byte[] dest, int pos) { - Utils.FloatToBytesSafepos(X, dest, pos); - Utils.FloatToBytesSafepos(Y, dest, pos + 4); - Utils.FloatToBytesSafepos(Z, dest, pos + 8); - Utils.FloatToBytesSafepos(W, dest, pos + 12); + if (Utils.CanDirectCopyLE) + { + fixed (byte* d = &dest[0]) + *(Vector4*)(d + pos) = this; + } + else + { + Utils.FloatToBytesSafepos(X, dest, pos); + Utils.FloatToBytesSafepos(Y, dest, pos + 4); + Utils.FloatToBytesSafepos(Z, dest, pos + 8); + Utils.FloatToBytesSafepos(W, dest, pos + 12); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe void ToBytes(byte* dest) + { + if (Utils.CanDirectCopyLE) + *(Vector4*)dest = this; + else + { + Utils.FloatToBytes(X, dest); + Utils.FloatToBytes(Y, dest + 4); + Utils.FloatToBytes(Z, dest + 8); + Utils.FloatToBytes(W, dest + 12); + } } #endregion Public Methods diff --git a/prebuild.xml b/prebuild.xml index 5860f74e..4caa043f 100644 --- a/prebuild.xml +++ b/prebuild.xml @@ -67,7 +67,6 @@ ../bin/ - OpenMetaverseTypes.XML @@ -92,7 +91,6 @@ ../bin/ - OpenMetaverse.StructuredData.XML @@ -116,7 +114,6 @@ ../bin/ - OpenMetaverse.XML @@ -149,7 +146,6 @@ ../bin/ - OpenMetaverse.Utilities.XML @@ -282,7 +278,6 @@ ../bin/ - OpenMetaverse.GUI.XML From 75ce0c09e5dd5213e48088bb0fee6d9cae44b06a Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Sun, 28 Aug 2022 22:45:29 +0100 Subject: [PATCH 079/149] a few more minor changes --- OpenMetaverse/BitPack.cs | 8 +- OpenMetaverse/Imaging/BakeLayer.cs | 12 +-- OpenMetaverseTypes/Color4.cs | 49 ++++++----- OpenMetaverseTypes/Utils.cs | 109 +++++++------------------ OpenMetaverseTypes/UtilsConversions.cs | 11 +++ OpenMetaverseTypes/Vector3.cs | 17 +++- OpenMetaverseTypes/Vector4.cs | 16 +++- 7 files changed, 101 insertions(+), 121 deletions(-) diff --git a/OpenMetaverse/BitPack.cs b/OpenMetaverse/BitPack.cs index 0400fbc7..cdaf7786 100644 --- a/OpenMetaverse/BitPack.cs +++ b/OpenMetaverse/BitPack.cs @@ -203,10 +203,10 @@ public void PackUUID(UUID data) /// public void PackColor(Color4 data) { - PackBitsFromByte(Utils.FloatToByte(data.R, 0f, 1f)); - PackBitsFromByte(Utils.FloatToByte(data.G, 0f, 1f)); - PackBitsFromByte(Utils.FloatToByte(data.B, 0f, 1f)); - PackBitsFromByte(Utils.FloatToByte(data.A, 0f, 1f)); + PackBitsFromByte(Utils.FloatZeroOneToByte(data.R)); + PackBitsFromByte(Utils.FloatZeroOneToByte(data.G)); + PackBitsFromByte(Utils.FloatZeroOneToByte(data.B)); + PackBitsFromByte(Utils.FloatZeroOneToByte(data.A)); } /// diff --git a/OpenMetaverse/Imaging/BakeLayer.cs b/OpenMetaverse/Imaging/BakeLayer.cs index 4ebaa814..63d471e6 100644 --- a/OpenMetaverse/Imaging/BakeLayer.cs +++ b/OpenMetaverse/Imaging/BakeLayer.cs @@ -581,9 +581,9 @@ private void ApplyTint(ManagedImage dest, Color4 src) for (int i = 0; i < dest.Red.Length; i++) { - dest.Red[i] = (byte)((dest.Red[i] * Utils.FloatToByte(src.R, 0f, 1f)) >> 8); - dest.Green[i] = (byte)((dest.Green[i] * Utils.FloatToByte(src.G, 0f, 1f)) >> 8); - dest.Blue[i] = (byte)((dest.Blue[i] * Utils.FloatToByte(src.B, 0f, 1f)) >> 8); + dest.Red[i] = (byte)((dest.Red[i] * Utils.FloatZeroOneToByte(src.R)) >> 8); + dest.Green[i] = (byte)((dest.Green[i] * Utils.FloatZeroOneToByte(src.G)) >> 8); + dest.Blue[i] = (byte)((dest.Blue[i] * Utils.FloatZeroOneToByte(src.B)) >> 8); } } @@ -610,9 +610,9 @@ private void InitBakedLayerColor(Color4 color) /// Blue value private void InitBakedLayerColor(float r, float g, float b) { - byte rByte = Utils.FloatToByte(r, 0f, 1f); - byte gByte = Utils.FloatToByte(g, 0f, 1f); - byte bByte = Utils.FloatToByte(b, 0f, 1f); + byte rByte = Utils.FloatZeroOneToByte(r); + byte gByte = Utils.FloatZeroOneToByte(g); + byte bByte = Utils.FloatZeroOneToByte(b); byte rAlt, gAlt, bAlt; diff --git a/OpenMetaverseTypes/Color4.cs b/OpenMetaverseTypes/Color4.cs index a4bc542e..a3432e8b 100644 --- a/OpenMetaverseTypes/Color4.cs +++ b/OpenMetaverseTypes/Color4.cs @@ -248,17 +248,19 @@ public void ToBytes(byte[] dest, int pos) /// instead of 255) public void ToBytes(byte[] dest, int pos, bool inverted) { - dest[pos + 0] = Utils.FloatToByte(R, 0f, 1f); - dest[pos + 1] = Utils.FloatToByte(G, 0f, 1f); - dest[pos + 2] = Utils.FloatToByte(B, 0f, 1f); - dest[pos + 3] = Utils.FloatToByte(A, 0f, 1f); - - if (inverted) + if (!inverted) + { + dest[pos + 0] = Utils.FloatZeroOneToByte(R); + dest[pos + 1] = Utils.FloatZeroOneToByte(G); + dest[pos + 2] = Utils.FloatZeroOneToByte(B); + dest[pos + 3] = Utils.FloatZeroOneToByte(A); + } + else { - dest[pos + 0] = (byte)(255 - dest[pos + 0]); - dest[pos + 1] = (byte)(255 - dest[pos + 1]); - dest[pos + 2] = (byte)(255 - dest[pos + 2]); - dest[pos + 3] = (byte)(255 - dest[pos + 3]); + dest[pos + 0] = (byte)(255 - Utils.FloatZeroOneToByte(R)); + dest[pos + 1] = (byte)(255 - Utils.FloatZeroOneToByte(G)); + dest[pos + 2] = (byte)(255 - Utils.FloatZeroOneToByte(B)); + dest[pos + 3] = (byte)(255 - Utils.FloatZeroOneToByte(A)); } } @@ -313,22 +315,17 @@ public float GetHue() /// public void ClampValues() { - if (R < 0f) - R = 0f; - if (G < 0f) - G = 0f; - if (B < 0f) - B = 0f; - if (A < 0f) - A = 0f; - if (R > 1f) - R = 1f; - if (G > 1f) - G = 1f; - if (B > 1f) - B = 1f; - if (A > 1f) - A = 1f; + if (R < 0f) R = 0f; + else if (R > 1f) R = 1f; + + if (G < 0f) G = 0f; + else if(G > 1f) G = 1f; + + if (B < 0f) B = 0f; + else if (B > 1f) B = 1f; + + if (A < 0f) A = 0f; + else if (A > 1f) A = 1f; } #endregion Public Methods diff --git a/OpenMetaverseTypes/Utils.cs b/OpenMetaverseTypes/Utils.cs index 534d29d3..d1bff1a9 100644 --- a/OpenMetaverseTypes/Utils.cs +++ b/OpenMetaverseTypes/Utils.cs @@ -114,16 +114,7 @@ public enum Runtime [MethodImpl(MethodImplOptions.AggressiveInlining)] public static float Clamp(float value, float min, float max) { - // First we check to see if we're greater than the max - if (value >= max) - return max; - - // Then we check to see if we're less than the min. - if (value < min) - return min; - - // There's no check to see if min > max. - return value; + return (value < max) ? (value > min ? value : min) : max; } ///
@@ -136,16 +127,7 @@ public static float Clamp(float value, float min, float max) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static double Clamp(double value, double min, double max) { - // First we check to see if we're greater than the max - if (value >= max) - return max; - - // Then we check to see if we're less than the min. - if (value < min) - return min; - - // There's no check to see if min > max. - return value; + return (value < max) ? (value > min ? value : min) : max; } /// @@ -158,16 +140,7 @@ public static double Clamp(double value, double min, double max) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int Clamp(int value, int min, int max) { - // First we check to see if we're greater than the max - if (value >= max) - return max; - - // Then we check to see if we're less than the min. - if (value < min) - return min; - - // There's no check to see if min > max. - return value; + return (value < max) ? (value > min ? value : min) : max; } /// @@ -213,40 +186,38 @@ public static float Distance(float value1, float value2) public static float Hermite(float value1, float tangent1, float value2, float tangent2, float amount) { + if (amount <= 0f) + return value1; + if (amount >= 1f) + return value2; + // All transformed to double not to lose precission // Otherwise, for high numbers of param:amount the result is NaN instead of Infinity - double v1 = value1, v2 = value2, t1 = tangent1, t2 = tangent2, s = amount, result; - double sCubed = s * s * s; + double v1 = value1, v2 = value2, t1 = tangent1, t2 = tangent2, s = amount; double sSquared = s * s; - - if (amount == 0f) - result = value1; - else if (amount == 1f) - result = value2; - else - result = (2d * v1 - 2d * v2 + t2 + t1) * sCubed + + double sCubed = sSquared * s; + + return (float)((2d * v1 - 2d * v2 + t2 + t1) * sCubed + (3d * v2 - 3d * v1 - 2d * t1 - t2) * sSquared + - t1 * s + v1; - return (float)result; + t1 * s + v1); } public static double Hermite(double value1, double tangent1, double value2, double tangent2, double amount) { + if (amount <= 0d) + return value1; + if (amount >= 1f) + return value2; + // All transformed to double not to lose precission // Otherwise, for high numbers of param:amount the result is NaN instead of Infinity - double v1 = value1, v2 = value2, t1 = tangent1, t2 = tangent2, s = amount, result; - double sCubed = s * s * s; + double v1 = value1, v2 = value2, t1 = tangent1, t2 = tangent2, s = amount; double sSquared = s * s; + double sCubed = sSquared * s; - if (amount == 0d) - result = value1; - else if (amount == 1f) - result = value2; - else - result = (2d * v1 - 2d * v2 + t2 + t1) * sCubed + + return (2d * v1 - 2d * v2 + t2 + t1) * sCubed + (3d * v2 - 3d * v1 - 2d * t1 - t2) * sSquared + t1 * s + v1; - return result; } public static float Lerp(float value1, float value2, float amount) @@ -261,20 +232,12 @@ public static double Lerp(double value1, double value2, double amount) public static float SmoothStep(float value1, float value2, float amount) { - // It is expected that 0 < amount < 1 - // If amount < 0, return value1 - // If amount > 1, return value2 - float result = Utils.Clamp(amount, 0f, 1f); - return Utils.Hermite(value1, 0f, value2, 0f, result); + return Utils.Hermite(value1, 0f, value2, 0f, amount); } public static double SmoothStep(double value1, double value2, double amount) { - // It is expected that 0 < amount < 1 - // If amount < 0, return value1 - // If amount > 1, return value2 - double result = Utils.Clamp(amount, 0f, 1f); - return Utils.Hermite(value1, 0f, value2, 0f, result); + return Utils.Hermite(value1, 0f, value2, 0f, amount); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -424,26 +387,20 @@ public static double RandomDouble() public static Platform GetRunningPlatform() { const string OSX_CHECK_FILE = "/Library/Extensions.kextcache"; - - if (Environment.OSVersion.Platform == PlatformID.WinCE) + switch(Environment.OSVersion.Platform) { - return Platform.WindowsCE; - } - else - { - int plat = (int)Environment.OSVersion.Platform; - - if ((plat != 4) && (plat != 128)) - { - return Platform.Windows; - } - else + case PlatformID.WinCE: + return Platform.WindowsCE; + case PlatformID.Unix: + case PlatformID.MacOSX: { if (System.IO.File.Exists(OSX_CHECK_FILE)) return Platform.OSX; else return Platform.Linux; } + default: + return Platform.Windows; } } @@ -453,11 +410,7 @@ public static Platform GetRunningPlatform() /// Enumeration of the current runtime we are running on public static Runtime GetRunningRuntime() { - Type t = Type.GetType("Mono.Runtime"); - if (t != null) - return Runtime.Mono; - else - return Runtime.Windows; + return (Type.GetType("Mono.Runtime") == null) ? Runtime.Windows : Runtime.Mono; } #endregion Platform diff --git a/OpenMetaverseTypes/UtilsConversions.cs b/OpenMetaverseTypes/UtilsConversions.cs index 68caec0b..704f687f 100644 --- a/OpenMetaverseTypes/UtilsConversions.cs +++ b/OpenMetaverseTypes/UtilsConversions.cs @@ -2183,6 +2183,17 @@ public static byte FloatToByte(float val, float lower, float upper) return (byte)(255 * val); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static byte FloatZeroOneToByte(float val) + { + if (val <= 0) + return 0; + if (val >= 1.0f) + return 255; + + return (byte)(255 * val); + } + /// /// Convert a byte to a float value given a minimum and maximum range /// diff --git a/OpenMetaverseTypes/Vector3.cs b/OpenMetaverseTypes/Vector3.cs index 0369bce1..9d14dbbc 100644 --- a/OpenMetaverseTypes/Vector3.cs +++ b/OpenMetaverseTypes/Vector3.cs @@ -149,9 +149,20 @@ public void Sub(Vector3 v) [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Clamp(float min, float max) { - X = Utils.Clamp(X, min, max); - Y = Utils.Clamp(Y, min, max); - Z = Utils.Clamp(Z, min, max); + if (X > max) + X = max; + else if (X < min) + X = min; + + if (Y > max) + Y = max; + else if (Y < min) + Y = min; + + if (Z > max) + Z = max; + else if (Z < min) + Z = min; } [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/OpenMetaverseTypes/Vector4.cs b/OpenMetaverseTypes/Vector4.cs index fd869b15..6131040d 100644 --- a/OpenMetaverseTypes/Vector4.cs +++ b/OpenMetaverseTypes/Vector4.cs @@ -132,11 +132,19 @@ public void Sub(Vector4 v) [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Clamp(float min, float max) { - X = Utils.Clamp(X, min, max); - Y = Utils.Clamp(Y, min, max); - Z = Utils.Clamp(Z, min, max); - W = Utils.Clamp(W, min, max); + if (X < min) X = min; + else if (X > max) X = max; + + if (Y < min) Y = min; + else if (Y > max) Y = max; + + if (Z < min) Z = min; + else if (Z > max) Z = max; + + if (W < min) W = min; + else if (W > max) W = max; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Min(Vector4 v) { From 24a90c7d379dfa1307bb2cacfdfa7028cce34361 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Mon, 29 Aug 2022 19:40:46 +0100 Subject: [PATCH 080/149] add a float to ushort pre clamped to range 0,1 --- OpenMetaverseTypes/UtilsConversions.cs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/OpenMetaverseTypes/UtilsConversions.cs b/OpenMetaverseTypes/UtilsConversions.cs index 704f687f..f7012f6f 100644 --- a/OpenMetaverseTypes/UtilsConversions.cs +++ b/OpenMetaverseTypes/UtilsConversions.cs @@ -2194,6 +2194,19 @@ public static byte FloatZeroOneToByte(float val) return (byte)(255 * val); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ushort FloatZeroOneToushort(float val) + { + if (val <= 0) + return 0; + + if (val >= 1.0f) + return 0xffff; + + return (ushort)(val * 0xffff); + } + + /// /// Convert a byte to a float value given a minimum and maximum range /// From c7cc50e03c91a6cd085b66316640c5b3a1540927 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Thu, 22 Sep 2022 21:15:49 +0100 Subject: [PATCH 081/149] try to detect new caps with more complex urls --- Programs/GridProxy/GridProxy.cs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Programs/GridProxy/GridProxy.cs b/Programs/GridProxy/GridProxy.cs index 266e932b..735408bd 100644 --- a/Programs/GridProxy/GridProxy.cs +++ b/Programs/GridProxy/GridProxy.cs @@ -645,6 +645,15 @@ private void ProxyCaps(NetworkStream netStream, string meth, string uri, Diction int indx = capuri.IndexOf("/item/"); if (indx < 0) indx = capuri.IndexOf("/category/"); + + if (indx < 0) + { + indx = capuri.IndexOf("/cap/"); + if(indx > 0 && indx + 45 < capuri.Length) + indx += 41; + else + indx = -1; + } if(indx > 0) capuri = capuri.Substring(0,indx); From 2bed8b3c295775fceb23a08879d04795c0503843 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Fri, 25 Nov 2022 08:10:03 +0000 Subject: [PATCH 082/149] create a branch for dotnet 6-7, and add basic changes for it (still far from working) --- bin/OpenMetaverse.dll.config | 16 +- bin/Prebuild.exe | Bin 245760 -> 0 bytes bin/System.Drawing.Common.dll | Bin 0 -> 454248 bytes bin/System.Drawing.Common.dll.linux | Bin 0 -> 427112 bytes bin/System.Drawing.Common.dll.win | Bin 0 -> 454248 bytes bin/log4net.dll | Bin 270336 -> 266240 bytes ...-1-x86_64.so => openjpeg-dotnet-x86_64.so} | Bin ...0-dotnet-1.dylib => openjpeg-dotnet.dylib} | Bin ....0-dotnet-1-i686.so => openjpeg-dotnet.so} | Bin bin/prebuild.dll | Bin 0 -> 262144 bytes nantprebuild | 14 -- prebuild.xml | 163 +++++++----------- runprebuild.bat | 64 ++----- runprebuild.sh | 60 +++---- runprebuild48.bat | 48 ------ runprebuild48.sh | 26 --- 16 files changed, 109 insertions(+), 282 deletions(-) delete mode 100755 bin/Prebuild.exe create mode 100644 bin/System.Drawing.Common.dll create mode 100644 bin/System.Drawing.Common.dll.linux create mode 100644 bin/System.Drawing.Common.dll.win rename bin/{libopenjpeg-dotnet-2-1.5.0-dotnet-1-x86_64.so => openjpeg-dotnet-x86_64.so} (100%) mode change 100755 => 100644 rename bin/{libopenjpeg-dotnet-2-1.5.0-dotnet-1.dylib => openjpeg-dotnet.dylib} (100%) mode change 100755 => 100644 rename bin/{libopenjpeg-dotnet-2-1.5.0-dotnet-1-i686.so => openjpeg-dotnet.so} (100%) mode change 100755 => 100644 create mode 100644 bin/prebuild.dll delete mode 100644 nantprebuild delete mode 100644 runprebuild48.bat delete mode 100755 runprebuild48.sh diff --git a/bin/OpenMetaverse.dll.config b/bin/OpenMetaverse.dll.config index ccafc0ff..20b1df5e 100755 --- a/bin/OpenMetaverse.dll.config +++ b/bin/OpenMetaverse.dll.config @@ -1,7 +1,9 @@ - - - - - - - + + + + + + + + + diff --git a/bin/Prebuild.exe b/bin/Prebuild.exe deleted file mode 100755 index 1e4ef3fd668a389d4b0870a77d2c63eb1aa69e10..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 245760 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 diff --git a/bin/System.Drawing.Common.dll b/bin/System.Drawing.Common.dll new file mode 100644 index 0000000000000000000000000000000000000000..7c9e87b4e1820b2beb6928ab1dd927d23a8cb2e7 GIT binary patch literal 454248 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�Q$QrG!1cj(vNR~%ioVHm)It4uz^t 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 literal 0 HcmV?d00001 diff --git a/bin/System.Drawing.Common.dll.linux b/bin/System.Drawing.Common.dll.linux new file mode 100644 index 0000000000000000000000000000000000000000..9e26473d19758449ffdf145fe1975e6a627e3639 GIT binary patch literal 427112 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 Ss~A|tz$yk-G4P)f1OE?AqI9tU literal 270336 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 literal 0 HcmV?d00001 diff --git a/nantprebuild b/nantprebuild deleted file mode 100644 index a9b2d7d6..00000000 --- a/nantprebuild +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - \ No newline at end of file diff --git a/prebuild.xml b/prebuild.xml index 4caa043f..71c3b88f 100644 --- a/prebuild.xml +++ b/prebuild.xml @@ -1,6 +1,6 @@ - + TRACE;DEBUG @@ -14,6 +14,11 @@ true true false + false + true + false + false + false @@ -29,12 +34,17 @@ false true false + false + true + false + false + false - + ../bin/ @@ -47,8 +57,7 @@ ../bin/ - - + @@ -58,7 +67,7 @@ - + ../bin/ @@ -71,9 +80,6 @@ ../bin/ - - - @@ -82,7 +88,7 @@ - + ../bin/ @@ -95,8 +101,6 @@ ../bin/ - - @@ -105,7 +109,7 @@ - + ../bin/ @@ -118,11 +122,7 @@ ../bin/ - - - - - + @@ -137,7 +137,7 @@ - + ../bin/ @@ -150,9 +150,6 @@ ../bin/ - - - @@ -163,7 +160,7 @@ - + ../bin/ @@ -176,9 +173,6 @@ ../bin/ - - - @@ -190,7 +184,7 @@ - + ../../bin/ @@ -203,8 +197,6 @@ ../../bin/ - - @@ -219,7 +211,7 @@ - + ../bin/ @@ -232,8 +224,7 @@ ../bin/ - - + @@ -243,7 +234,7 @@ --> - + ../bin/ @@ -256,8 +247,7 @@ ../bin/ - - + @@ -269,7 +259,7 @@ - + ../bin/ @@ -282,9 +272,7 @@ ../bin/ - - - + @@ -297,7 +285,7 @@ - + ../../bin/ @@ -310,10 +298,7 @@ ../../bin/ - - - - + @@ -333,7 +318,7 @@ --> - + ../../bin/ @@ -346,9 +331,7 @@ ../../bin/ - - - + @@ -365,7 +348,7 @@ - + ../../bin/ @@ -378,8 +361,7 @@ ../../bin/ - - + @@ -390,7 +372,7 @@ - + ../../bin/ @@ -403,7 +385,6 @@ ../../bin/ - @@ -411,7 +392,7 @@ - + ../../../bin/ @@ -424,7 +405,6 @@ ../../../bin/ - @@ -435,7 +415,7 @@ - + ../../../bin/ @@ -448,8 +428,7 @@ ../../../bin/ - - + @@ -469,7 +448,7 @@ - + ../../bin/ @@ -512,10 +490,7 @@ ../../bin/ - - - - + @@ -538,7 +513,7 @@ - + ../../bin/ @@ -551,9 +526,7 @@ ../../bin/ - - - + @@ -567,7 +540,7 @@ - + ../../bin/ @@ -580,8 +553,6 @@ ../../bin/ - - @@ -590,7 +561,7 @@ - + ../../bin/ @@ -603,11 +574,7 @@ ../../bin/ - - - - - + @@ -627,7 +594,7 @@ - + ../../bin/ @@ -683,8 +648,6 @@ ../../bin/ - - @@ -693,7 +656,7 @@ - + ../../bin/ @@ -706,7 +669,6 @@ ../../bin/ - @@ -720,7 +682,7 @@ - + ../../../bin/ @@ -733,9 +695,7 @@ ../../../bin/ - - - + @@ -750,7 +710,7 @@ - + ../../../bin/ @@ -763,9 +723,7 @@ ../../../bin/ - - - + @@ -782,7 +740,7 @@ - + ../../../bin/ @@ -795,9 +753,7 @@ ../../../bin/ - - - + @@ -814,7 +770,7 @@ - + ../../../bin/ @@ -838,7 +794,7 @@ - + ../../../bin/ @@ -851,10 +807,7 @@ ../../../bin/ - - - - + diff --git a/runprebuild.bat b/runprebuild.bat index e2b68326..93f85203 100644 --- a/runprebuild.bat +++ b/runprebuild.bat @@ -1,54 +1,18 @@ @echo OFF -bin\Prebuild.exe /target vs2015 +dotnet bin\prebuild.dll /target vs2022 /targetframework net6_0 /excludedir = "obj | bin" /file prebuild.xml -setlocal ENABLEEXTENSIONS -set VALUE_NAME=MSBuildToolsPath - - -rem try find vs2017 -if "%PROCESSOR_ARCHITECTURE%"=="x86" set PROGRAMS=%ProgramFiles% -if defined ProgramFiles(x86) set PROGRAMS=%ProgramFiles(x86)% - -for %%e in (Enterprise Professional Community) do ( - - if exist "%PROGRAMS%\Microsoft Visual Studio\2017\%%e\MSBuild\15.0\Bin\MSBuild.exe" ( - - set ValueValue="%PROGRAMS%\Microsoft Visual Studio\2017\%%e\MSBuild\15.0\Bin\" - goto :found - ) - -) - - -rem We have to use grep or find to locate the correct line, because reg query spits -rem out 4 lines before Windows 7 but 2 lines after Windows 7. -rem We use grep if it's on the path; otherwise we use the built-in find command -rem from Windows. (We must use grep on Cygwin because it overrides the "find" command.) - -for %%X in (grep.exe) do (set FOUNDGREP=%%~$PATH:X) -if defined FOUNDGREP ( - set FINDCMD=grep -) else ( - set FINDCMD=find -) - -rem try vs2015 -FOR /F "usebackq tokens=1-3" %%A IN (`REG QUERY "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSBuild\ToolsVersions\14.0" /v %VALUE_NAME% 2^>nul ^| %FINDCMD% "%VALUE_NAME%"`) DO ( - set ValueValue=%%C - goto :found -) - -@echo msbuild for at least VS2015 not found, please install a (Community) edition of VS2017 or VS2015 -@echo Not creating compile.bat -if exist "compile.bat" ( - del compile.bat - ) -goto :done - -:found - @echo Found msbuild at %ValueValue% @echo Creating compile.bat - @echo %ValueValue%\msbuild opensim.sln > compile.bat - -:done \ No newline at end of file +rem To compile in debug mode + @echo dotnet build --configuration Release OpenSim.sln > compile.bat +rem To compile in release mode comment line (add rem to start) above and uncomment next (remove rem) +rem @echo %ValueValue% /p:Configuration=Release opensim.sln > compile.bat +:done +if exist "bin\addin-db-002" ( + del /F/Q/S bin\addin-db-002 > NUL + rmdir /Q/S bin\addin-db-002 + ) +if exist "bin\addin-db-004" ( + del /F/Q/S bin\addin-db-004 > NUL + rmdir /Q/S bin\addin-db-004 + ) \ No newline at end of file diff --git a/runprebuild.sh b/runprebuild.sh index f48aebaf..cc5561b3 100755 --- a/runprebuild.sh +++ b/runprebuild.sh @@ -1,32 +1,28 @@ -#!/bin/bash - -mono bin/Prebuild.exe /target nant -mono bin/Prebuild.exe /target monodev -mono bin/Prebuild.exe /target vs2010 - -if [ x$1 == xnant ]; then - nant -buildfile:OpenMetaverse.build - RES=$? - echo Build Exit Code: $RES - if [ x$2 == xruntests ]; then - nunit-console bin/OpenMetaverse.Tests.dll -exclude=Network -labels -xml=testresults.xml - fi - - exit $RES -fi - -if [ x$1 == xprimrender ]; then - nant -buildfile:OpenMetaverse.Rendering.GPL.build - exit $? -fi - -if [ x$1 == xopenjpeg ]; then - ARCH=`arch` - cd openjpeg-dotnet - if [ $ARCH == x86_64 ]; then - # since we're a 64bit host, compile a 32bit vesion of openjpeg - make ARCH=-i686 ARCHFLAGS=-m32 install - fi - # compile for default detected platform - make install -fi +#!/bin/sh + +case "$1" in + + 'clean') + dotnet bin/prebuild.dll /file prebuild.xml /clean + + ;; + + + 'autoclean') + + echo y|dotnet bin/prebuild.dll /file prebuild.xml /clean + + ;; + + + + *) + + dotnet bin/prebuild.dll /target vs2022 /targetframework net6_0 /excludedir = "obj | bin" /file prebuild.xml + echo "dotnet build -c Release OpenMetaverse.sln" > compile.sh + chmod +x compile.sh + cp bin/System.Drawing.Common.dll.linux bin/System.Drawing.Common.dll + + ;; + +esac \ No newline at end of file diff --git a/runprebuild48.bat b/runprebuild48.bat deleted file mode 100644 index 151dd90f..00000000 --- a/runprebuild48.bat +++ /dev/null @@ -1,48 +0,0 @@ -@echo OFF - -bin\Prebuild.exe /target vs2019 /targetframework v4_8 /excludedir = "obj | bin" - -setlocal ENABLEEXTENSIONS -set VALUE_NAME=MSBuildToolsPath - -if "%PROCESSOR_ARCHITECTURE%"=="x86" set PROGRAMS=%ProgramFiles% -if defined ProgramFiles(x86) set PROGRAMS=%ProgramFiles(x86)% - -set PROGRAMS64 = %PROGRAMS% -if defined ProgramFiles set PROGRAMS64=%ProgramFiles% - - -rem Try to find VS2019/22 -for %%e in (Community Enterprise Professional) do ( - if exist "%PROGRAMS64%\Microsoft Visual Studio\2022\%%e\MSBuild\Current\Bin\MSBuild.exe" ( - - set ValueValue="%PROGRAMS64%\Microsoft Visual Studio\2022\%%e\MSBuild\Current\Bin\MSBuild" - goto :found - ) - if exist "%PROGRAMS%\Microsoft Visual Studio\2019\%%e\MSBuild\Current\Bin\MSBuild.exe" ( - - set ValueValue="%PROGRAMS%\Microsoft Visual Studio\2019\%%e\MSBuild\Current\Bin\MSBuild" - goto :found - ) -) - - -@echo msbuild for at least VS2019 not found, please install a (Community) edition of VS2019 -@echo Not creating compile.bat -if exist "compile.bat" ( - del compile.bat - ) -goto :done - -:found - @echo Found msbuild at %ValueValue% - @echo Creating compile.bat -rem To compile in debug mode - @echo %ValueValue% opensim.sln > compile.bat -rem To compile in release mode comment line (add rem to start) above and uncomment next (remove rem) -rem @echo %ValueValue% /p:Configuration=Release opensim.sln > compile.bat -:done -if exist "bin\addin-db-002" ( - del /F/Q/S bin\addin-db-002 > NUL - rmdir /Q/S bin\addin-db-002 - ) \ No newline at end of file diff --git a/runprebuild48.sh b/runprebuild48.sh deleted file mode 100755 index bb87334d..00000000 --- a/runprebuild48.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/bin/sh - -case "$1" in - - 'clean') - - mono bin/Prebuild.exe /clean - - ;; - - - 'autoclean') - - echo y|mono bin/Prebuild.exe /clean - - ;; - - - - *) - - mono bin/Prebuild.exe /target vs2019 /targetframework v4_8 /excludedir = "obj | bin" - - ;; - -esac From 4a4d0a7ee5f01e869b2e704d8887cd4b085cb563 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Fri, 25 Nov 2022 08:50:17 +0000 Subject: [PATCH 083/149] some more changes. Many projects will only compile on and for windows, and after fixing their target platform on projects props (prebuild still does not have that). libs needed for opensim should compile --- CSJ2K/AssemblyInfo.cs | 2 +- OpenMetaverse.GUI/AvatarList.cs | 10 +- OpenMetaverse.GUI/InventoryTree.cs | 12 +- .../LLSD/NotationLLSD.cs | 2 +- OpenMetaverse.StructuredData/LLSD/XmlLLSD.cs | 16 +- .../StructuredData.cs | 137 +- OpenMetaverse/AssemblyInfo.cs | 2 +- OpenMetaverse/BitPack.cs | 109 +- OpenMetaverse/Capabilities/CapsBase.cs | 33 +- OpenMetaverse/Imaging/OpenJPEG.cs | 99 +- OpenMetaverse/Imaging/TGALoader.cs | 4 - OpenMetaverse/Login.cs | 23 +- OpenMetaverse/Rendering/Rendering.cs | 10 +- OpenMetaverseTypes/Color4.cs | 22 +- OpenMetaverseTypes/Matrix3x3.cs | 122 +- OpenMetaverseTypes/Matrix4.cs | 78 +- OpenMetaverseTypes/OSUTF8Constants.cs | 6 +- OpenMetaverseTypes/Quaternion.cs | 507 +- OpenMetaverseTypes/UUID.cs | 355 +- OpenMetaverseTypes/Utils.cs | 79 +- OpenMetaverseTypes/UtilsConversions.cs | 167 +- OpenMetaverseTypes/Vector2.cs | 170 +- OpenMetaverseTypes/Vector3.cs | 572 +- OpenMetaverseTypes/Vector3d.cs | 183 +- OpenMetaverseTypes/Vector4.cs | 248 +- .../Properties/Resources.Designer.cs | 46 +- .../Properties/Settings.Designer.cs | 24 +- Programs/GridProxy/GridProxy.cs | 38 +- .../Properties/Resources.Designer.cs | 48 +- .../Properties/Settings.Designer.cs | 24 +- Programs/PrimWorkshop/frmBrowser.cs | 32 +- .../WinGridProxy/Properties/AssemblyInfo.cs | 2 +- .../examples/GridAccountant/AssemblyInfo.cs | 2 +- bin/openmetaverse_data/avatar_lad.xml | 29784 +++++++++------- bin/openmetaverse_data/avatar_skeleton.xml | 313 +- openjpeg-dotnet/DllOpenJPEG.sln | 11 +- 36 files changed, 19900 insertions(+), 13392 deletions(-) diff --git a/CSJ2K/AssemblyInfo.cs b/CSJ2K/AssemblyInfo.cs index 6daddfbe..c4e1d7a2 100644 --- a/CSJ2K/AssemblyInfo.cs +++ b/CSJ2K/AssemblyInfo.cs @@ -30,7 +30,7 @@ // You can specify all the values or you can default the Revision and Build Numbers // by using the '*' as shown below: -[assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] // // In order to sign your assembly you must specify a key to use. Refer to the diff --git a/OpenMetaverse.GUI/AvatarList.cs b/OpenMetaverse.GUI/AvatarList.cs index e7e65e67..5999ef96 100644 --- a/OpenMetaverse.GUI/AvatarList.cs +++ b/OpenMetaverse.GUI/AvatarList.cs @@ -99,10 +99,10 @@ public AvatarList() this.ListViewItemSorter = _ColumnSorter; EventHandler clickHandler = new EventHandler(defaultMenuItem_Click); - this.ContextMenu = new ContextMenu(); - this.ContextMenu.MenuItems.Add("Offer Teleport", clickHandler); - this.ContextMenu.MenuItems.Add("Teleport To", clickHandler); - this.ContextMenu.MenuItems.Add("Walk To", clickHandler); + this.ContextMenuStrip = new ContextMenuStrip(); + this.ContextMenuStrip.Items.Add("Offer Teleport", null, clickHandler); + this.ContextMenuStrip.Items.Add("Teleport To", null, clickHandler); + this.ContextMenuStrip.Items.Add("Walk To", null, clickHandler); this.DoubleBuffered = true; this.ListViewItemSorter = _ColumnSorter; @@ -362,7 +362,7 @@ private void UpdateCoarseInfo(Simulator sim, List newEntries, List r private void defaultMenuItem_Click(object sender, EventArgs e) { - MenuItem menuItem = (MenuItem)sender; + ToolStripItem menuItem = (ToolStripItem)sender; switch (menuItem.Text) { diff --git a/OpenMetaverse.GUI/InventoryTree.cs b/OpenMetaverse.GUI/InventoryTree.cs index b4fd414f..cf2cc9a9 100644 --- a/OpenMetaverse.GUI/InventoryTree.cs +++ b/OpenMetaverse.GUI/InventoryTree.cs @@ -38,13 +38,13 @@ namespace OpenMetaverse.GUI public class InventoryTree : TreeView { private GridClient _Client; - private ContextMenu _ContextMenu; + private ContextMenuStrip _ContextMenu; private UUID _SelectedItemID; ///

/// Gets or sets the context menu associated with this control /// - public ContextMenu Menu + public ContextMenuStrip Menu { get { return _ContextMenu; } set { _ContextMenu = value; } @@ -65,9 +65,9 @@ public GridClient Client public InventoryTree() { EventHandler clickHandler = new EventHandler(defaultMenuItem_Click); - _ContextMenu = new ContextMenu(); - _ContextMenu.MenuItems.Add("Wear", clickHandler); - _ContextMenu.MenuItems.Add("Detach", clickHandler); + _ContextMenu = new ContextMenuStrip(); + _ContextMenu.Items.Add("Wear", null, clickHandler); + _ContextMenu.Items.Add("Detach", null, clickHandler); this.NodeMouseClick += new TreeNodeMouseClickEventHandler(InventoryTree_NodeMouseClick); this.BeforeExpand += new TreeViewCancelEventHandler(InventoryTree_BeforeExpand); @@ -172,7 +172,7 @@ private void InitializeClient(GridClient client) private void defaultMenuItem_Click(object sender, EventArgs e) { - MenuItem menuItem = (MenuItem)sender; + ToolStripItem menuItem = (ToolStripItem)sender; InventoryItem item = (InventoryItem)Client.Inventory.Store[_SelectedItemID]; diff --git a/OpenMetaverse.StructuredData/LLSD/NotationLLSD.cs b/OpenMetaverse.StructuredData/LLSD/NotationLLSD.cs index 0918ef0f..0b58100e 100644 --- a/OpenMetaverse.StructuredData/LLSD/NotationLLSD.cs +++ b/OpenMetaverse.StructuredData/LLSD/NotationLLSD.cs @@ -232,7 +232,7 @@ private static OSD DeserializeLLSDNotationElement(TextReader reader) if (reader.Read(uuidBuf, 0, 36) < 36) throw new OSDException("Notation LLSD parsing: Unexpected end of stream in UUID."); UUID lluuid; - if (!UUID.TryParse(new String(uuidBuf), out lluuid)) + if (!UUID.TryParse(new String(uuidBuf).AsSpan(), out lluuid)) throw new OSDException("Notation LLSD parsing: Invalid UUID discovered."); osd = OSD.FromUUID(lluuid); break; diff --git a/OpenMetaverse.StructuredData/LLSD/XmlLLSD.cs b/OpenMetaverse.StructuredData/LLSD/XmlLLSD.cs index bd802946..dd9a5bd4 100644 --- a/OpenMetaverse.StructuredData/LLSD/XmlLLSD.cs +++ b/OpenMetaverse.StructuredData/LLSD/XmlLLSD.cs @@ -636,8 +636,7 @@ private static OSD ParseLLSDXmlElement(XmlTextReader reader) if (reader.Read()) { - int value = 0; - Int32.TryParse(reader.ReadString().Trim(), out value); + Int32.TryParse(reader.ReadString().Trim(), out int value); ret = OSD.FromInteger(value); break; } @@ -653,7 +652,7 @@ private static OSD ParseLLSDXmlElement(XmlTextReader reader) if (reader.Read()) { - double value = 0d; + double value; string str = reader.ReadString().Trim().ToLower(); if (str == "nan") @@ -676,8 +675,7 @@ private static OSD ParseLLSDXmlElement(XmlTextReader reader) if (reader.Read()) { - UUID value = UUID.Zero; - UUID.TryParse(reader.ReadString().Trim(), out value); + UUID.TryParse(reader.ReadString().AsSpan(), out UUID value); ret = OSD.FromUUID(value); break; } @@ -693,12 +691,12 @@ private static OSD ParseLLSDXmlElement(XmlTextReader reader) if (reader.Read()) { - DateTime value = Utils.Epoch; - DateTime.TryParse(reader.ReadString().Trim(), out value); - ret = OSD.FromDate(value); + if(DateTime.TryParse(reader.ReadString().Trim(), out DateTime value)) + ret = OSD.FromDate(value); + else + ret = OSD.FromDate(Utils.Epoch); break; } - ret = OSD.FromDate(Utils.Epoch); break; case "string": diff --git a/OpenMetaverse.StructuredData/StructuredData.cs b/OpenMetaverse.StructuredData/StructuredData.cs index bca87d4e..4c414d00 100644 --- a/OpenMetaverse.StructuredData/StructuredData.cs +++ b/OpenMetaverse.StructuredData/StructuredData.cs @@ -145,16 +145,14 @@ public virtual int AsInteger() return Int32.MinValue; return (int)Math.Round(v); case OSDType.String: - string s = ((OSDString)this).value; - double dbl; - if (Double.TryParse(s, out dbl)) + var s = ((OSDString)this).value.AsSpan(); + if (Double.TryParse(s, out double dbl)) return (int)Math.Floor(dbl); else return 0; case OSDType.OSDUTF8: - string us = ((OSDUTF8)this).value.ToString(); - double udbl; - if (Double.TryParse(us, out udbl)) + var us = ((OSDUTF8)this).value.ToString().AsSpan(); + if (Double.TryParse(us, out double udbl)) return (int)Math.Floor(udbl); else return 0; @@ -167,10 +165,12 @@ public virtual int AsInteger() List l = ((OSDArray)this).value; if (l.Count < 4) return 0; - byte[] by = new byte[4]; - for (int i = 0; i < 4; i++) - by[i] = (byte)l[i].AsInteger(); - return (by[0] << 24) | (by[1] << 16) | (by[2] << 8) | by[3]; + return + (byte)l[0].AsInteger() << 24 | + (byte)l[1].AsInteger() << 16 | + (byte)l[2].AsInteger() << 8 | + (byte)l[3].AsInteger(); + case OSDType.Date: return (int)Utils.DateTimeToUnixTime(((OSDDate)this).value); default: @@ -196,16 +196,14 @@ public virtual uint AsUInteger() return UInt32.MinValue; return (uint)Math.Round(v); case OSDType.String: - string s = ((OSDString)this).value; - double dbl; - if (Double.TryParse(s, out dbl)) + var s = ((OSDString)this).value.AsSpan(); + if (Double.TryParse(s, out double dbl)) return (uint)Math.Floor(dbl); else return 0; case OSDType.OSDUTF8: - string us = ((OSDUTF8)this).value.ToString(); - double udbl; - if (Double.TryParse(us, out udbl)) + var us = ((OSDUTF8)this).value.ToString().AsSpan(); + if (Double.TryParse(us, out double udbl)) return (uint)Math.Floor(udbl); else return 0; @@ -221,10 +219,11 @@ public virtual uint AsUInteger() List l = ((OSDArray)this).value; if (l.Count < 4) return 0; - byte[] by = new byte[4]; - for (int i = 0; i < 4; i++) - by[i] = (byte)l[i].AsInteger(); - return (uint)((by[0] << 24) | (by[1] << 16) | (by[2] << 8) | by[3]); + return ( + ((uint)(byte)l[0].AsInteger() << 24) | + ((uint)(byte)l[1].AsInteger() << 16) | + ((uint)(byte)l[2].AsInteger() << 8) | + (byte)l[3].AsInteger()); default: return 0; } @@ -248,16 +247,14 @@ public virtual long AsLong() return Int64.MinValue; return (long)Math.Round(v); case OSDType.String: - string s = ((OSDString)this).value; - double dbl; - if (Double.TryParse(s, out dbl)) + var s = ((OSDString)this).value.AsSpan(); + if (Double.TryParse(s, out double dbl)) return (long)Math.Floor(dbl); else return 0; case OSDType.OSDUTF8: - string us = ((OSDUTF8)this).value.ToString(); - double udbl; - if (Double.TryParse(us, out udbl)) + var us = ((OSDUTF8)this).value.ToString().AsSpan(); + if (Double.TryParse(us, out double udbl)) return (long)Math.Floor(udbl); else return 0; @@ -283,18 +280,15 @@ public virtual long AsLong() List l = ((OSDArray)this).value; if (l.Count < 8) return 0; - byte[] b = new byte[8]; - for (int i = 0; i < 8; i++) - b[i] = (byte)l[i].AsInteger(); - return ( - ((long)b[0] << 56) | - ((long)b[1] << 48) | - ((long)b[2] << 40) | - ((long)b[3] << 32) | - ((long)b[4] << 24) | - ((long)b[5] << 16) | - ((long)b[6] << 8) | - b[7]); + return + ((long)(byte)l[0].AsInteger() << 56) | + ((long)(byte)l[1].AsInteger() << 48) | + ((long)(byte)l[2].AsInteger() << 40) | + ((long)(byte)l[3].AsInteger() << 32) | + ((long)(byte)l[4].AsInteger() << 24) | + ((long)(byte)l[5].AsInteger() << 16) | + ((long)(byte)l[6].AsInteger() << 8) | + (byte)l[7].AsInteger(); } default: return 0; @@ -319,16 +313,14 @@ public virtual ulong AsULong() return UInt64.MinValue; return (ulong)Math.Round(v); case OSDType.String: - string s = ((OSDString)this).value; - double dbl; - if (Double.TryParse(s, out dbl)) + var s = ((OSDString)this).value.AsSpan(); + if (Double.TryParse(s, out double dbl)) return (ulong)Math.Floor(dbl); else return 0; case OSDType.OSDUTF8: - string us = ((OSDUTF8)this).value.ToString(); - double udbl; - if (Double.TryParse(us, out udbl)) + var us = ((OSDUTF8)this).value.ToString().AsSpan(); + if (Double.TryParse(us, out double udbl)) return (ulong)Math.Floor(udbl); else return 0; @@ -354,18 +346,15 @@ public virtual ulong AsULong() List l = ((OSDArray)this).value; if (l.Count < 8) return 0; - byte[] b = new byte[8]; - for (int i = 0; i < 8; i++) - b[i] = (byte)l[i].AsInteger(); return ( - ((ulong)b[0] << 56) | - ((ulong)b[1] << 48) | - ((ulong)b[2] << 40) | - ((ulong)b[3] << 32) | - ((ulong)b[4] << 24) | - ((ulong)b[5] << 16) | - ((ulong)b[6] << 8) | - b[7]); + ((ulong)(byte)l[0].AsInteger() << 56) | + ((ulong)(byte)l[1].AsInteger() << 48) | + ((ulong)(byte)l[2].AsInteger() << 40) | + ((ulong)(byte)l[3].AsInteger() << 32) | + ((ulong)(byte)l[4].AsInteger() << 24) | + ((ulong)(byte)l[5].AsInteger() << 16) | + ((ulong)(byte)l[6].AsInteger() << 8) | + (byte)l[7].AsInteger()); } default: return 0; @@ -383,16 +372,14 @@ public virtual double AsReal() case OSDType.Real: return ((OSDReal)this).value; case OSDType.String: - string s = ((OSDString)this).value; - double dbl; - if (Double.TryParse(s, out dbl)) + var s = ((OSDString)this).value.AsSpan(); + if (Double.TryParse(s, out double dbl)) return dbl; else return 0; case OSDType.OSDUTF8: - string us = ((OSDUTF8)this).value.ToString(); - double udbl; - if (Double.TryParse(us, out udbl)) + var us = ((OSDUTF8)this).value.ToString().AsSpan(); + if (Double.TryParse(us, out double udbl)) return udbl; else return 0; @@ -449,14 +436,13 @@ public virtual UUID AsUUID() switch (Type) { case OSDType.String: - UUID uuid; - if (UUID.TryParse(((OSDString)this).value, out uuid)) + if (UUID.TryParse(((OSDString)this).value.AsSpan(), out UUID uuid)) return uuid; else return UUID.Zero; case OSDType.OSDUTF8: UUID ouuid; - if (UUID.TryParse(((OSDUTF8)this).value.ToString(), out ouuid)) + if (UUID.TryParse(((OSDUTF8)this).value.ToString().AsSpan(), out ouuid)) return ouuid; else return UUID.Zero; @@ -577,19 +563,19 @@ public Vector3 AsVector3() switch (Type) { case OSDType.String: - return Vector3.Parse(((OSDString)this).value); + return Vector3.Parse(((OSDString)this).value.AsSpan()); case OSDType.OSDUTF8: - return Vector3.Parse(((OSDUTF8)this).value.ToString()); + return Vector3.Parse(((OSDUTF8)this).value.ToString().AsSpan()); case OSDType.Array: List l = ((OSDArray)this).value; - Vector3 vector = Vector3.Zero; if (l.Count == 3) { - vector.X = (float)l[0].AsReal(); - vector.Y = (float)l[1].AsReal(); - vector.Z = (float)l[2].AsReal(); + return new Vector3( + (float)l[0].AsReal(), + (float)l[1].AsReal(), + (float)l[2].AsReal()); } - return vector; + return Vector3.Zero; default: return Vector3.Zero; } @@ -600,9 +586,9 @@ public Vector3d AsVector3d() switch (Type) { case OSDType.String: - return Vector3d.Parse(((OSDString)this).value); + return Vector3d.Parse(((OSDString)this).value.AsSpan()); case OSDType.OSDUTF8: - return Vector3d.Parse(((OSDUTF8)this).value.ToString()); + return Vector3d.Parse(((OSDUTF8)this).value.ToString().AsSpan()); case OSDType.Array: List l = ((OSDArray)this).value; Vector3d vector = Vector3d.Zero; @@ -1307,7 +1293,7 @@ public override double AsReal() public override UUID AsUUID() { UUID uuid; - if (UUID.TryParse(value.ToString(), out uuid)) + if (UUID.TryParse(value.ToString().AsSpan(), out uuid)) return uuid; else return UUID.Zero; @@ -1411,8 +1397,7 @@ public override double AsReal() public override UUID AsUUID() { - UUID uuid; - if (UUID.TryParse(value, out uuid)) + if (UUID.TryParse(value.AsSpan(), out UUID uuid)) return uuid; else return UUID.Zero; diff --git a/OpenMetaverse/AssemblyInfo.cs b/OpenMetaverse/AssemblyInfo.cs index 70fb0783..580c2ed4 100644 --- a/OpenMetaverse/AssemblyInfo.cs +++ b/OpenMetaverse/AssemblyInfo.cs @@ -25,7 +25,7 @@ // You can specify all the values or you can default the Revision and Build Numbers // by using the '*' as shown below: -[assembly: AssemblyVersion("0.9.4.*")] +[assembly: AssemblyVersion("0.9.4.0")] // // In order to sign your assembly you must specify a key to use. Refer to the diff --git a/OpenMetaverse/BitPack.cs b/OpenMetaverse/BitPack.cs index cdaf7786..ac32f73b 100644 --- a/OpenMetaverse/BitPack.cs +++ b/OpenMetaverse/BitPack.cs @@ -69,26 +69,46 @@ public BitPack(byte[] data, int pos, int? bitp = null) { Data = data; bytePos = pos; - if(bitp.HasValue) + if (bitp.HasValue) { bitPos = bitp.Value; - if(bitPos < 0) + if (bitPos < 0) bitPos = 0; - else if(bitPos > 7) + else if (bitPos > 7) bitPos = 7; // this is wrong anyway if (bitPos == 0) Data[pos] = 0; else - Data[pos] &= (byte)~(0xff >> bitPos); + Data[pos] &= (byte)~(0xff >> bitPos); } else bitPos = 0; } + public void Reset(byte[] data, int pos, int? bitp = null) + { + Data = data; + bytePos = pos; + if (bitp.HasValue) + { + bitPos = bitp.Value; + if (bitPos < 0) + bitPos = 0; + else if (bitPos > 7) + bitPos = 7; // this is wrong anyway + if (bitPos == 0) + Data[pos] = 0; + else + Data[pos] &= (byte)~(0xff >> bitPos); + } + else + bitPos = 0; + } /// /// Pack a floating point value in to the data /// /// Floating point value to pack + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public unsafe void PackFloat(float data) { int d = (*(int*)&data); @@ -103,16 +123,10 @@ public unsafe void PackFloat(float data) ///

(3RkJ%yVF<3!xI*lX^* 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 literal 0 HcmV?d00001 diff --git a/bin/System.Drawing.Common.dll.win b/bin/System.Drawing.Common.dll.win new file mode 100644 index 0000000000000000000000000000000000000000..7c9e87b4e1820b2beb6928ab1dd927d23a8cb2e7 GIT binary patch literal 454248 zcmd4437nio(Les|^E~s+wMS-mGqbxnb`#j8nVDU3KnOt~+@}!kBp{c7B!LX>5{_&( z1QbN%@u4`6{ADyby7Xcp+YR-{JTDRy{}0UP*Y(`~UAJnWvuW>gww1 z>h9{}>3;Fb+Z@kv93TImf8KFEi6{S-%J0-an-JXG{a~~6vFz99e6r!Vug^K{Zu8|FFA!-3=E6nopTJi}L|cJ>9|69|LvTM;$>do*w^5+T!0Bap{E891lJfja>7I8MeQ%i#Se>wVy| z3$DBj@0o|fd@-+(+y3iuoO1>ShX!8?q{zm+lj$R(gP3$Fifdr-f{SY)q^ypkI&i)+ zj_wc%wtm)7ulS>Eu9I?}YH*$B_Vt~tU>)bN{SbaPo<9hjO(AZo$86UefI=&urBAnX z^P3!}p||M0b)*5MR9+I|y|J$>ODhyM>6hoao;i@*R(i)2_i~G6Jm$NlGSE;%P=+9F z^IT^DPcSdItqnq+3;NTpK@NiaAn=#Ax`OV@^k=aFlG=mRwjf86_Q8q7R?6OvIw4@Bx$^gvd~TiG33+d4 zvz0=s**8Zs*8P5Uk5F_k5#6s7-8aXO)GKe?cs$Crx4+o8g*C|>3-r)&`03rmfbziL zToi?r7T{wnc#{R+XTeWcud%z|&R;0G-DSqq+-O5z@7!B<-F z`z-hg3*KhIy9WuMWfr`_g72~5Us!N1oy09$@c9<}9t-}W1^?ZGmt+z?XIb#|7W}XU z|IUKDvPs+nEqH?kKV-qrSg@N*;vQqc8!h-d7QA~tp}*9E-(|tSu;6Kp3H>P+ywQU1 zw%`XXc&i0ZYfAVmu;Ak?c#{R+Yr#)hu-lyQS!ThTE%-4D{+R{;+k!h<5! zw^^`hOZXgO!Dm|Vl@@%r1#hw7=JtfoaTa`o1wUfJ!SsZ_YQd*j@J0*1&w{sFaHg2> zSzy5zTJRez_$~{6)PkS2;A$!1d5i_Gwcy(=_!}{dzLI@r2cGZ|3WGfz=-?gc;QPH| zr6JfPeKKk2*P-_=Y+QzCwV}-3I%iJKqK^#}Mr)p{nxK2R83FdQWPsU?6FqglDo#qyF+Z!1-L@r-?#wOATA?V>aMnR4f(UZGHPZ}XC zOa9QC!W)C^@KOBf3->j*B8`xI#nP1qdCRTJ1>NVrq(3ub6NxHqc-t#8Q(uBv@|5WG zlV;3IIq$_2-dv%j!5||!JRozfv8cP?`&KW^>A z2yOFQeTl!udMBeb23g9rdP#&Zp*3MjA%SrGEU7+gpru^e&1O1kD6e2Nm#zls+Cm_o zf_Fz>$#v#9>))cI0G4SxqM=VNXxawOr8rEl!?S$v1O>6MePf-Xw>1>EHIz%`14W_k z#i1tgej8XM@9SF}$)tHB(14jib35Q66jZLf$nAIA>3B)PkcqO*z!QFH!ClthPJ{eWkhi?R9TrkJ&Xw}# zz3Lp-HE%;eX}P%@4~?oQvl8rzC)*JgX}Bjr>Ysbgp3n=t@q&gGH92zzBIjEhwiR7i zXYEY9pE8vHxI@WH)@-ikCCuh|RI?Y#>r)WM(Wxp7L#d6y`-?;=l^5h|N*-^hf zMw^s8crr#M50BMLbcou(tdtg3>ln_iV_2-651M+mA0}JMg&trsxs>;c`HikZqL{Gm z1miNRG_lgj8`Z;Uiu0^8NsfIg+E+!3^=fX^>T<<=rMcBfhuTP&mgm#x;8=ARJQEhK zZ>8fqP=V7Nr&FifDO1W98!PRt4H-?Tw`2LVhNDl;l$JMUFp!q?o}M5*&q3XsOlN56 zFMyyc<~O+^D7kED(A;Z2)q*bsUC2HpjWV?zd-13}Pqi0#8YwJrPt3G@pj*;l&wMDh zAK!U7sw6$9Kr0vbSZqVB#t#LMKhtt(Y zNh4jXT?B@a{c?@~T^i~Do9&#tZ8~bC8-&C`NQ@bjccQo8TnL}Y=@0Qv*yh6Q>ogma7%_R1sh~6n`8`y zBZ^{s7f7Fz=qHZd>^G+nEi+LxiC3wUA&OT_2{duclU&cM-3KjtwU6M}e32Pi>3S`$ zx>>F|4}yjt7C46^jW+7jPbDg#B5#Sa>xv@=e+)L8tNjBx4!mN~Pu2R6!YG`IAW%1n zwxxd3T&H7+`bjVq-@J>(N?oYWL_gSt{CVVD?O^DWlye5kcMtG@UsdqTAWO^*Q2iSt zy0p+Wj-~@MgwUrlkzbZ}O0(&TInDytpnJ)guS!WWP0u+Ic85B6?dm%fL|yTHulF1)YjVV$fWK>1#$1;Yvin<0^fSS;)n&&!uS*Df*kj zvBr8(R?}&75zy-c)jsp$OI@B$U9FI2K@?D&KS$M4oZsOVT|>_s-jbM7X@&U~v>hB6G-eWeY=u46lbel*Gc<}s+ERrS>crmxX58#px{gAsU9?#{7(7QC z3#n?lkWzD2J8ARXv>40?ttMUYhz7%P!WB;SojU#PqF2BA>sl9F zX!o}7D|{g8MQUi6s`w@q)rK(LHuXW?#o>`I;I_-Cvx z(GpF!Dck0yomYa6Z3F7fwP01v0(b?0{-g#TFjWmieAc<^^g$LOgRwPmn&@iE8p!q! zHJbAYQD2IN_b zVX6or%rT!l!INde2AX}ASDlT{75yI^3hnhp^3jYJ)Gk5vr&#~tSh%R-EuFgLHe+5^ zd}8VIL=VaVzB@BwUd1dcc!PlF5X*+o-5?+vKUJV6SuFPSIFC8zCe8wlqKl$#$EM%t z9CZraeJoqL8($3$Bj)4QpU%^va{3_eaf2>~ls~s<{)oU)ETCa>B1iRx`o$PNtNs1$7`r?RqAKPNq)Pba8N6aTBz*fd-!6}+ zapsNwK-j*RrN#f zG^nT2kssnaowH;*&{+bvpTfK5W{6HZ^&E8N6gp~apc}R{D_!$b5Jvr7@3jl!%Wth1D$zmwaz%s-p9$n1EhuRg zy1UOluPt3j3#$Wuf@DR6wyer)L`5^r9cZiCvh9Vew7$gx-07D<-nLAowOt!%3s=bO zcLx|1+j5K1$vK5oA@}WVGci1KS1vCE@-E zDUSSws9b4zTdt5Rqz@W={`u!i<@PqexV4dUT4`q*6bPFsxE*3)u6Yhc>6Y}xGd1LK zG}iimkI)g! zF8FScmf2cuh|xb%5Yazi5@=8OI?DJm(kq3z2xT>L5fQ`kYgNNFcKuyb`xZJTbeGL3 zO^5YP<3Klo^BeHWVZ77Z`!+T{(T54JMw1q7o zZuVDptki%xVL(q5&=m$?=11f5d9pAsj+}yLSR;XM*0FHWoCR@n?RCSOJmMT2|SqA|l zau$90^IGg62IupjWMdj_S2d9xqO2ie0QO3a1c4b3L< zZp4JNS{N~0X@W_`rnokW=ltQwKj}<$i^CIWu#}Wg@Kn3*?1`tZ$KU+#LJ0zqlFkG;&uxGv-P<= z6Gyp>2sCRk0z($xyxBrvEbW^+EyNW>yv0IXNyJ+%#8pJR%|f8L_03%tVwi}xTZj!r z+-)IHcD{Lsg+O`xX0wI3nuvE=h)qPG4#s)8hKP4t2z2bed5?v71rhJH5U(WSeHP+6 zBHnKyt|#Ii3-Kxoujso-Y zIRzRcU|v3_DPsi8%Qp{M2$+}5X2ujSFW)?DQNX->^H~c4^YYCj76RtwbCxpZ0rT?B z=Pd-x%Qs)J5HK&F^MG*_n3r$9WFcT)zWK6+fO+}me=G#d%Qs)K5HK&Fb8InFn3r!J zwGc2b-+awNz`T6(n1z6O`J5$+dBD7U^9>6D^YS@85>vpue6z(uz`T4;K*ba=FW)?F zAz)s<`L>0CdHLo$76Rtwo9|i(n3r$9XCYu-zWKg|fO+{k&lomJFfZRcVNt-md=5Qh z!C+p#dD23_ynORR3jy=;%~KWv=H;6oSqPYyZ$>Qy%**EhFizz&L~OMXFfX5@)R+S1 z<(sE11kB6l2qdO}dHLpN76Rtwo1a?x&UEFP|f| z7y^LCeA8edU`@VpEd;E| zH=c!nHTlN35U?iSq$~ui$v1(8fHh&?s)c|x`6go_U`@WsS_oK^Z*msm86xr)0@mc4 zMho#Q5lt52*F-d12w0PES}X*t$u}4`#QK0WVYbymz?yv1Y9U}vzG<@%uqNNMTL@Sa zW*RL7tjRY;3ju5LP02#Qntan?Az)3u>9i2ACf{^f2w0PEW>^SVlW%5P2w0PEW?2YW zlW%6n2>O$II*!u~f6`olc|y0=jlj$1!8OKOS(`WXkPo+7gMwNQ!a^Uq!Ffdr5%D*4 zJ*;a}4U84KG=^RtLxV9i6hoKA(7G79Jch1_p(|tPsu)@yL&Gt&A%;d`Xk!dr9YdR9 z=$aV1HiljiL$8dX>tYC54RiUb7`h>bUL8X>#?WhG=%yIDIfibDp<83-hTa@QcgE0LV(6_g^tKqfD~8@4LwCo}J7Q>a481dk-W5ad zj-mI&(0gNuUV&Q9`(ucHfa2%?DD=S?`cMqr8$%zCq5ER!BQbP;41F|)J{ChCkD&)* z=o2yY$r$=n3_Tb_pN^r2V(2q5^l%J)HijOFA$GHxH}j;G4#V2Vo#;Au!~ZNeUm~zj-jnF#BNAK+5afSjz=N(I12qdhJF!4>|8XIy^2D= ziXrwRiem?&5PJ@V*kvfhzCxkj$Ix>z^oJPwV+{Q%hW;Ewe~F>L#?aql=bI*0NACXQ|d1-CUGqbxM0ak+yJ za(o+Ws3MpEB8TTx@tgxWh6?O%uv~O2c*raZCfHkm(;1g<@h#% za*p2FeLVkHMsz{>NpCv%cg6fqpNju0qIfp{-tqizi|A~9OhEVAiRk*q^LtG_o#$MD zeDP0&pA`##cD?Z4^c9EuplZZ_6uJCQ<5`*BIjx~GZ5Dp=#&D9V2Df31F0YQ#wDanX zmu*W#XXkYSy2mG?n?NTwCv@M?4a4&@-dwY0?eU8y7xvaDl4VzWjFj0YYo=DUIio`H{fBeiHPI;>^Y97xjrI_@>6GzNq*Lj z&Citf*fpg+UKgcl+hc0HY&S-90rvS?&5vjBRgShk$zBcc8e3Mcj;Po+uBcb&W>M@nfufJwy25qdM(2Q|b-j!-90D28 zx?peE-^OMzVi1cxWdbq(wA0-et;f0250Ssj$=B%*xqc!N-VH_`M=$0M^H)9#<=Q`X z;VZ_-+gz+&;{(m0Jf@BNe$2(ZoUvpl(_PqxK}2ta25n7HUR_6ztqNC;q595*R9D4R(%O8FL}Tq`eM|$n+puTpMa%&Hn1{yBXot01 zCxKUc9&MP`ZIoYgsyS#*o87qK>`pdrcgenEQLU?cR9)Hdip|JuOc2Fsw0SQu1bgsQSpo=Q9W|x=YLe{iQYFrte<(uDf~GwD{qB zDhyBQyYhTpteH?Tp7CMoSrO-cCnK(mBccpa&RNiZKl}AMTl4YO9$TK@ zo3EzQx&bCv$)=09?#2Bt=%sCs%d*G-yJgH7Q9|u`^!ZU*13R780XvY^nO0h=?MW@) z{Okp2dyj~Jd3$B~ix=uGZPS5LV|TjFN?S1yr<&LU zENKGU>zTs#4&DKK*egn@&i3Z*bXvVTkQN#;Z2{x7j+;i?qyLI~x`DX09_taD98Dl|jDc#mPn7(2 z`_ccr0Pc%o?n(a=`8J7+FU+@zb0WUYzEMhXn@>L~@@;lJt%-e``m`2XY3YEZfet>> zi`tT?4%DZ+^L=Ptx+$}8T*96v9HkrC=#Hm5aeq1{-My`Jx97~ID3N%;i4fZ}!ub*Z z?HXbF1#n*wbKgPNDl1AIJMP=z?8vz9m^jg~KH5(35g+Z?m{U@Rc8PtNBcha0hvbVq zbpo0q8%sOqT0TIM57yuRrENE3{C<>`ywoM_yLO39nu*WirMS9{~TGn|RM3~PpgQnWtoGPBu928I4XduKG5n5H1qASc2?8*5y&y?{n)GlY_ zQH>hLjF`s?+UlU2^b7go1v6I4|#*D0)``m7q9c^LH z8iU2$nq-y!_X8-Gg;u#3ES6Tr*v{l-?wDtz$-&@eY#3_D2RCDe*KI5|RZ5wxEZT2Q zXEWJ5W#0ZR+0yc+Y_QSh`(A!J9Gj#z)rb_)cA>D!13i4z*h(|cQ@O&+qFwIHwMZYnnSyT#{$Jbd}MOzf8pBY*2bYaqFc)+V zv;sL(;R!6W8a*BPQG1!%_)-z)Hd%0 z$Ya%z(CR}=hddIdU;5$=S!G|(6%MrgmOLj-Do>+>9hd)S^#S#2$CY?8gr2DC9Kt4q zEoytw?8AB;PTkQf2{CQ+njGwt{QpnB#(I54e8nnDX3ar6R?GH6W2M_NCd;(=>dk&T z^1L7OY%4(!bxIJ7)HT(^|5Y2KsUsMhua(ZW`(}EF7)a#p(oUZZWBL#BZM%8p1XL@=QC&9y)fwZcuAhMFCF7`GH38Mx#_+CQc` z-K+5gF>?qH595yWD!lwtCy6U$# zjaGx9BK*2WDf?WeX_6g<_mbgLS?W>G{%LfUovB^SovxV&A?uG^SQ{%Bo8@og3d2S{ zMPU4y46dC1pnFH#!QV&zcy8X8BSC|q3t5Exj*I=CgmYy3iAZlD0S;_h6PI=U8GN4{ zLrPwlEK*)|<1Rg$xd++AXNZUa1OE4;99%PqwALL7zW_)4G^J~=A-DDs?3co69Eok3PeI(i z(ek>(po-ppzpq$n!eMmB!&dO!Lvfq8t4HyC)oBC^h@&b(QOZ@j~t{Xdo< z_kSO$U<6F-XdE=V|C@()g2hit!+L_l5;LFYp&cNCbGjKuWIDn5j zk2nJ>0g!y)#L8lTbDZZi!u8JYoB?D+Favv6W&q6Q{^bnp3E({Ed1s&p01{j}P#Sy# z>REHJr4OpMzTRj_$)PVfJWqr*5S)NqVqMtxA~Ya2!`gP zBCj896Z(uE!LDY5($#vusG;|a264@}FMkh+kwRI7YnpW}ChEth6;^Z)64c6 zKmOS*m*+*pj=-7|ZE@8zuUngl$0X(vs!kT;(Wn0x`F?H} z@%{WR;`;@gZ^mKU$~sp+mxxhtC*}?3So4Nsw=Euwet_E+lMZF#V&Pb0%7Xb~Bv4p4 zRVLQWot9|=2W&!9*{)1q8Y5HISteGvV|FM@0y;!aN0ypyPA3Co^W}&?Z2Z5?`+s&J z@2~7a-e0wN=N$I8yWB3fUr>)mLeV%mFGIO@xovJ=uCLY0m6Gor_CuY4UtPi&;5BGS zqifC5z5PL-E^qagf}y{lY27ToHjZV0_l9we-|w|o;5c4@SSR9C-Fx9cTyqpEI1W{v zehi;ja^+LK(MHcKfE%%d&XZ>r0?aL@^OUJg2XFH?aOrQvk&E*7SG*N>gf? zg0;EeqiN;jbM{x=7I79Hbqm*r`ObS9O=Au5`;lwdFzWXsjF0aRq)hxBiv}BWXjB;s2z=Ll~y%8J2p8c)J@cmgzbnKJIsG=$dm15nXim?sAx z8aFzhJ5y^1ZBVMs#se#sw?dJbp{oLLe~+CjZx{nsoUs(yxEmsF1HHLV5#l(lQ`^e#|JY?-1;HASvPZ5%}X#Qe5 z`MP_D1$hqzd17KgZdv7-??)Qu*{q&}uX(70!bW_}VxP46(v9DxeH8QDD6t4OK9*pS z*%#RMZNZySLPLuI*Y?BDc72M)&lkVTN=wGQ z(*FlZ>kWdeg zAJ793n9=eP{uWF@%#h)hSrYHTe_kVo3Q9F_*>y8yfuylcs+`O|Ctk&}r*sx5Gccz`CWr}H>gAvGc6rQHO=b~K_00Eq6VjS8d zdLYqDIQ=yEG%PvEO6?GkUM3pDg(0FQ^EKF?`67NsTl+>^Fn!TCn(Z6KEC;U&EjP%3 zX^zvrkK>&Vv3OcT`(npi9>M!N-iio5(D7DA@WGCEMg$+`cxM9US<6_H;y#Lk=#W>8 zK8}<<5fgU;Ksrm%6Xk7xc*A6NHAN-5H{{P%#$m5IRdid@PBST>+cH8k$krD z(Cz?9qIL#DM=^JZz<9eO-r%^yVa z`E+knHI>!PB#o79wsW|Zsc?Ws z4~eCjnA>QMMiB?KWANLQ?QKip9BE9~_XowTZGI(RNQDPUbDFCysFNUF2+Tht&c(L$ z;!VhBrjQ=OS-dzbx{$%~&uN?mjR`^?|NO@Qv#~g~Iv5-9CkC88LBO9Guws0G*~kR4 ztyyy{q^_MI6q^gUeTs)$uTHN$=yLd>?QPgpituc)b{rmPF=_X^g=Ov479kq^t3;)( zIHlP9Ey@s1Z8m(J80Uw?%X)==QRu#Kz3zhjC}yQg(tKRBiqfF%q@)7E+0# z_!29JFR?=KqDlx_gG32=9Cj^|WHigjg5-HF@_;6~Fkzl?>|i7T%oX&mGYI+@3;jyy zXxtJHrf)Gr(duoR&XR4#B{^AVuqKSgmR(-6~CmO&H=xKj{V8Wpo5Q7$FBurFLQ2`bhecZ#@?HIjpU_m&s|2b))RsVHsFS&?Wc&*NW z+ryi-&c?z3&PM{=qwwwavd}bMdln4-hA!t#NO?Va_Mfnem-6MFsT0QJ4<=fSQ!362 zOrQ-6+qVfC7^3SNm`q?w5d$_bWq0;V<@TPlRZLtNLy>7O3y}UYrjJCuC=R-S(f~Ht z4P-0LuHGQz4$Xx6%A8>jx6QE+MERiI!fZS4$&}T*!$2gfcl*IbbLy{^L7~OjLZLO3 z)7{hdnvFy53#qN!W-=E)*w#`=4IPhyYzqpQov$>dxgE8^oIn&>F?4Qe=zmQt?p?18S!txNo#rz%?`lT>XZ(O2#kbh1pXRx@JxToG{nlxqMDTG9-nkKcLWB5qY)i48s(utkL&+^PuHHi9 zna7|I-0v3N;ug6`?QZBIY2Cn>OzzhS@2)9otmxu5G4koyxoEZ04aSXZ43~8XGxW&x zrO?JXC((}V8*n`P2Aq4MnDz}g?~jl;c4o|VH<_}Io6^ocFVg#NmZ;N=wOP8utbeY| zW1#@?yNfwh8kDtjoI8w4Nr_P{zD`!o~RD(Kp(OR*kEORd-ug zw16lI;sPS?$l%Rr?Z#<>Z`;6C+&TN``XT$VeuSQav^e+s&v@kO*N%g6!&%9jBWUXK zhRbW(&9}n#i+AyELEKXjm!sZHS9I0`Id#QvxV;cD)MZZLvXyo*;8g8N@<%t`!ohX1 zQ4P9!YvtOo;e++&AJ-ezdmkRRa*{xsS($3`M8G5*DHxK{XMp_ zJlq}-9%S^vNcE%b_VpVuNNK&x)EVx&ce-wj?&4bFT=QwUwio5<%UZ^BmR5%RscQwAA?%pv729be`0$dY$j6 zw)d{rc5j`wOPJJ>MrMqXGyR8q#pFIITythwWWkT_kBW5tp;*_uxBB*tQB&&vMrY5D zYQ1u?BlFfTsO~vNh0i5>45C3;+EY^s4a*iLx@+m)ScHj-I~*^UobE+YI=-A+m(*Qa zc(RimM&?hRsgx&zB^Ihoh_DDaqjD7e-1#-F2=#mv;kU$IY}4*(}d_|t1E(5MtK z3n$^Vm3V8coQ8SMGXOPZYkxp0?!vvZwO<3M8b#n%8TcH2Yf9$rvb8@VEW91i*NL}M zzLE>$xTRc>KD+9Uc7p4f;M)HVbTl{_GmHFbBNlAJp&b5bUPP+B1T@??04Kvmi&3~B zYM%z2m%cWtFWt@!?}e|6KbF@Gc)~|4Y$Ttl^P1!{SE;~dV?Og~$tS+q$>4(o&PAp* zPq{4aG1MG^RD^#_d&xxj;snC0><2s3PSiOV7hfJPzA%z~H)q9$M0OwE2j*l7E()hT z=fcq7`xEvxEWO%U6dt;qz7{qoC0km)i3N;XxWe*1 z8zhaRUE$j~cpGg}$`wNS6x#D=S+?h^h2)0L1v`I zaRJGvg<}f{SF%|Jl%KMIaQX8QQV5yaYKYwAYAsyY?`3PhK>?XH!1m(;z6hba|GFhk zwstW>`$qSY>!Jl!y9Ag89~zw*3DMdxQCWz8P^$*{nELqKZn!x84h++>qrW*UK~!w%kUCu(}P>6ejDDN712V!P2QS< zbhf=lUrZCMsYt;|Vh?nGZw z0HV!r^<8x!*FiP7d8#bMjl-)J{Gh#jM6xcBGMBRyb6n7%PlOu8yCU(e?-ju3f}ZIx z&;h@_adbsXLq~_XlA2~v9=pn}!ZY37x_o{I<}kV&m(SGTpCMNUO?RcA@#eHNbRTbq zLE407e*>OcKBF0(+HWt*S(`|Pf9Ibc&Eo@pnd8BWZa`lGK4WB z^p$dO6odn%Kws|>!{6_BP~iB=gaz+2=^i1Zz6kbv81(IEx;VONM7KaSS(cg?CFU1n z2`0poNH$x`cu34SFIvqn##Iy+5fxd-iE7R-{tF~el9P!an-le(U(DfWLX=z#9VW+u z$S?jt9Z@ny3yD}V`Ni-GElw;9OQwtzRlah5l9r5#6M-^=EVz8-kc5H-RmX$Hn6LCC z6f8E2A{b<$qG>E`VIhhAr_C!-itR(!;kTTiOE>qx?0bt_*m(=#W^+AAnzE&vXGw@M zzKP+RHMV|&!PD4LiCBlwKgnNr?q;UfTQtn}=H8MN?&jVODZkCVorZ#L?(H%xh0VP) zq?O#Pi=o=SVEs$xo}ww8k>AsY!^}6n7}lePd|n%V6ega- z^(?GKlDoTsl-!|*#>6%2+2_Rx{6`X??y(2N;?J>VvP(4_*V-FLnby(c(vnqNRAf1~ zU!Ksf?jJ6Iz4E~>kN6`ba5*O75)A#F@^GuX>sgDB^x4>MaQ?|dTU``2Rc5)vR9AJn z=|oi-{5)*cx>w#ErT~(pUWj<0ov=9;$&T6h9!^<}+xR|0M$x=g19kzmuXa4lVPm|r zzq8doo);5M5JnUewwQ?FO^O{f|?Xvz5GOPP8SRQqEKUKb7;O9hURd z@p58bMfbSi4)2bEF0V6I++{CVai>`VO{ur#u{;OWF4vw>>p$_zJk(WW9_)Pqy zxv|$(Jk7*Pu_~QFbwNER7~->7Q+hMIE8(4c9f32V$Fp~1gwj)Yu0s{s6CxNwmn^q2=NXTtqWKi(Y-9g z;so4=HqyM7{rmo|>4wO-IUH_QxNJGjcwd${(M@o|z3f;FyTp(SmM)K!4Q`qV#2rQB&;iZ>%*SXTm_#(NxbipGPJ?}eSL_( zpfMLE}deoJ+`}G%VptxROJ9}{=yf- z%kdw?GFeV3oPI;>{M~A4J?~A^u4O zY&+)hFCyM*A^uIo+bqO?h`7r_Y$F17H0JR<5qDb%bVcC}=3#EJRUy2=JVdxeywi$; zBVEHA%tH#Fh<95QDIzex5hoiE@m>poxv}sD^N>e|i1%9*St9PS5IG_~U?K8Ee9%HP z67eAmfrCNA8_dI0nu++ZMbSdUeHLOG5g)M-1tKsp7w4sw2&`kqh&CcVW+B>%__&3b zPQ(Ki0*6?JH<*Wlm5BJHMbSaTrz}J#5f563E+Rf{A!ZQqkcF5@#AhtTEFvDZ5VMK+ ztcB<%;t>ncL&WDS#2g|%Zz1Lq@dXR98xdc$5W5rcB@59@#Fs4u&b13~Fc0;y2N7Sf zC=3x_wGjA*HoU<+j8Z1zYZgU?h{r5Mm58rfh<+lzVIc;H_@;%}i-;{20_|0JgL#9X$Z40rGi0@d4y@~j)h1iFP?^%dNM10>u>`TOD7Gg0GPgscki1>kpSVF{; z76PX(g*TXoqT`UI@CNe`aR3oNvZ5SF#HfWhh=?Csh^0hqwGamr@e>Pi2oXpB4gV+=MrnhjN@r#J??ymk{wE3vm_^+bqP{ zL_BXH&LIN(8RORSTp}7Q#Cb%x7UHEucoyP(BCsnV=5YZLDGPyfRl*z0L(yMGMB1Xb zh=`1ZSVctELaZhtXCc-Qk+%>R6VYfPE+L}HLaZgC*+SHaXt5BN5;4s}yqt)Fg%~8F z)j|vr(PkkoBck0xtRrH&g}9uEqJ_AEh?0f4l86oqaTO7r7GgaSST>5aK1{?63$cNS znHFM%h*=h5BN4M>1pPhzM&=T@eD)pYJs99&MX??GPXB=k@^P1#b1eM|j-2tQpRmzQ zQ;7bVLUha&qDQ6>T``5|gDFJkOCfq)3enwCh<=trbg&enXQdEbDuw7vDMTkqA$m^= z(QQ(Q{*pp;loXWm?}BZ{LRq7WSrh3I)GM3+M$`Wgz+$xw*i zg+g>I6rw+&5FH7H=s_q%*Fhor3<}X%P>5cFLUa!lqF2h@HOT z*xM__ZeAhw?+USFSBO2jLhQ;FVjr#$J8y;diy?N`ieo>m5Ibmv*fT4{E?FV=#R{<# zR*1c?LhN=GVt=a;J6eU^>D@zo`&AOoiA}D#R{QA@+?5 zu~Srty`e(v1{Grerw}_nh1laM#I8;u_Hhcab5m$V46!>?9Q!ea*nug;o=YKiSqibQ zQiz?DLhPLsVz;Ca`y++e5h=tTNFjDT3bD^oh@Fi>>}3>U_o5K{6@}QLD8!ybA$B1O zvF}iborXf}Efiump%D8Ah1fAD#2!H*b_EKt4^W7Wzd~2V5Sx3&v7J|l4ZK2Z*%e}w zj`d6Vf)#V2xAC>lEf&p}I9irDWr4J=t!3+j zq0d9iMsDSi`HvnvYn0KF2(h+~i6!%lvq3BRv}ir^<1wmG-OrhbmfyqwU>v!~fvG3# zzSsG%I{BX-D~a-dQOI8|LGFmx#P%FBS6e6PPsSw8`JYMC{n>vn-Jed7ZV%+gJkMCY z|6**a^jRj!>x-w#>(9rf={s24l6gXpnRfP`VUFUu{-ape_ip+G<}q~_5v(D%-sj|C zQ6>k?8&P?1z~Sw9tdHjde`Xtuhx3OpA{vt<%GHKbemy25^#3}MW&!_DH-0!K9jQ@TpX%tInw-v) z??1-XC5-pRBrQHG=l3y{TqyG6r?}l{#mO<|cc8}^EcggfYd7?x-*fL6J--!pWsR>i zUZ2m3{Q6b0?4L*eZgLb!$$pFP!HIs zrv>$djrti;?I>j0^n6IUj{4$9;uz)gIg`(kIT`E|zlNaOnAw`|-qRf>DqS?ovD-6h zb6K93BYr!#CT<1iYAHRu2k6YN@sbN9|Ft1>2Fd!)IQp_hPwBTu-*3@VC)=YRu;{6Z z?a}XL(Nn=8{iwU{bTlpf{qDNueD=EQR`5B?UAL0Y>F&BS_-u05or!1rHV^xQ@UeWP z=PN=zZJUl67`MB7+e|)jL%gcA+M14(#i<@0;k?1$fr`!F z!9%a$YUb!{`)E$AyZizrknB*x!qgt!1#>N8V|VbY5Thw;o@F78@?(gsey|}YUj+Tr z$1&%L7(xFu^ASYUM6YI|LG2toItSo^2(Lh_JCVI%Z)gJBxm$5=#w^InegE0hbWgG4 z9O2A7FFH@-BByn|!p!eUpuNhmHik?QZQXWWuezUVc|FLvHO{c{vZiL+kMagQr}m;M`vZdv9^ftAXFX+N-UhJPTcH zh!r)JB`d5$l%)Y$$w8JzybqW=&{UWvrZ`~UY{7S0@LMeStrq+?3%<*O-)_NoTktz9 zc(Vn+(}Le+!SA-<_gL_IE%<#F{C*3*$AUj#!5_5X4_WZN7W`ogzR!X`V!`)Y@JB89 zV;1~z3x2?YKViY2jA7Q>>rf`cC~uVZtqAC!WoE$9XhF-rFA7dterqG4%*1SbEj-;? zH>fYm!)P!Y)6qTW<{sF-&c;Z1Q0oB!xPA(ce7Xl~I?nt|y60v*SKt%#6*yz(&VGDf zh0l)vfr*^WcrAyA4v{|(!?}k~9)=@;`oLX???YZ4C!kk-FM2-d_ppJZL+v=~ClflH z8sM1sjisD~?)?+dp_*Iia)VHERw>3DC9Gk}m;>qDGd{k4bDhY;_+2xjFLJ%wky!oI z-&#P! zhXlJ1jbX0xqtGYkH$fd)*FS*!#0qT`B;4v z`)t}oYuIQOYp`TK9!D7?TgT+Gb(o!&tz+k9>zG`&&dFu#+Z*?5({ga=J zW9U2q+gP|>^6mVMlSM}_6}M8KiWunlF>0fk{0_x`us%L|Jl#{aqwzl-$LEnMGXC3X z9`Wr2aAk#u&ofm-4xSp2q(F`{ z!6-IqlhQoq^Rp3Edguu5{NW`Za?oeHIf(rVCiX%o4#CyX41s=9&cR{cY`)kV*-K}k z!Svzb$9Gf)@~K8#+K)sji>8jzPiDgVMGuXW7AU;nLjrM|nBbWAG|$@!=f#qIAz=(X zm_9smJ}`je1LK*=rTKiFG?Ld_L7y^5#G(j<^rp!7t2Ct>rb_8^bty&p-iRpe=9oA! zfuejf5cw9|l=*(8rVlTW8NOB@ufSu{QusohG?KTgk;jp+-cDTYaVmmc@xK`JxOp#h z^?5mTZT#tJ4CCQONl9hKF#1x&h$kK0S?}^3X1P4NrR)j}4g1P}bk{uy#{CQ2b=VZs z&|eNmxpUoh5AnUrUH2J2TitaJ^Ov5$?Lz5}9@lCxC%j&@PUTq(EoY zoJ2gm)^CSytUP&&;He0S94L;pV*hEFB=!E2pj7PlVJ>(_KhGhfo%EkXtSS8`d?Ln4 zdAj7^4fFIpJ{P!#W66>nC>6eR*e|o~mo9k$kMD$OKk!9M9BCD;q%Gx`BeD) zA)g1j!+gqFiJW?XTl_l2zt}to@m7(|cSuIv7GRV7!~EAJAel0MY!}b~@b1O}w);{9 zcknEj&j?csS0o0{0iyP4B$V?8R|DR%2e`}UeRA^VyZM^;1}|q&M|}`q8@<6zGb4CbZ8?*YpGjJ{N0IA;Tiv?)hW`wRk=qidEUp!TpJ zD43SYO_V1jqfD;hM8-`NMX=@7ZgskA&O==<&Tn+X&vKWB-{h4XbptsXBqJ&%xGQgUhgnS5$(&x zV1hh2H$xtEvCy3zUQY^ISH9Qg+>GZg#K+Cvy7|xR`J#s2ZHLB{E(*QR3YF?@FinHw zMFtKMX^C&eMdGe+1Z3@e`eO6Sy zUX3})=_Dc!$N3+;r3V_@2ZiJ&F#+G;#DbtPsC@;2{Vh0_aOkUmJo6}i%U-AX8lFu+ z<16{c0GhAk2PaLgHs1gM#U~U){cz2Aa|Hqt{wrS zx}XvE*V<6Tl<{)NSz2K*Z<@nL*R2>#o(<5PgC7v^c)(ou(vz`15R(#BJUJL{!z68g zQ>)_+Q^zBG4Sgt>f3&v8wzT#>=s>EUw$JV`TW4)j-3_c|<^Twp3%XktR!uLaceD+b zw%6T2;%!A~EikK_vlf)xqSZ1zjGrtX=FwsVI`A>xj5E!J~oIlUTMzZUg( za#^ImaXqOhsG~>3^)^H`m_x^+a7e;flxGf(QQ4t)z?{u3_`zZyt71CCD}lt=9)t&| z6~Wv}+aKCIhBhu@A?Fz32gpMzY=h2;+reF9Vg3kRIX5*TZAG&`!WQ0bPO10P9E`9r z(@gajP?@ETNwO=BmU;o}(P;2%`pZ=fu`l3mU<#tt_^WGOV>kf$#25p8n6|F%Zd522 z(?d7M;QO?EtCKdz0x&m%FAsQZ*j7A{&dWli_mu33(DQU=In(;}d@A}WXxl2uMc3P$yfsLnS-^lJ-O@1vO3LuH=l4HJW+AkmHsxb{cU4f`r8cqTZt~;eSVaTu|8#M4idw$k)1zTN_=9MU`6P_apwRD7X6a zY8(ybATWu(SJO^WyIhTmq3;N*pxUg#Izz5}y<45BE^cXlTkPU4%wR0`ZFc;w-t({z z(!&Tmw3)Dwu{A5;L68PV>Ib78$vHw$f@O$eLo=aB%unZL>bf88si!Zor&GZn?bAg3 z)9S$BIF><}ep7f=u~sR)n=Xq}j3!MzJj*Cd-z-VeKk%?5efrNgPL}>!sa}(&z>22l zZBCXyPukwsu)Ji5(YX+VWA^%Gt%J5c(>1L41sCrIf$(?I(lgdH;-o2x(3Ew>t5)~7 z_6eZYtgJ&lNYokp4lr{@TWSiOq>?h3>m0W>(n--d?@HCl)Mp;yB&|0i&&df#Ja6m% zIt+&WY_B_9$3eZoxji~U*bf_h$DiA?-$B4)PRo1;CN~Yuz_#g)u$R_`phkb++>3hN z+Tho|i{RS#@S{U9exC&V;AN<|A&m|o;70nj?}N@f!5>D~u|!k$@HDh~8va8t+08Q> z&no_NL3j!NSIz;)DO*kihE^O)Gwp6h#=xj^loUZ z##>e`*j!h3x_{$0PItcHm6*3^;20Tun4DW+NA0=xyeA?|Yw*Ny@S*km)9{saE6!9r zA9*uBg(UqM{WN;PvmH18k5mo+ZM~)Lp10wM&f;v~$?-4QXL`El;};&kV&D>eA6UHjP6=$8J#fyz(dnL3zi`pB1MQ39 zEIFRGQ3tVFoLRZt(?&{OPprJm(^g7ekEks7w3(9E{VPX%+D^&qyvhxW_r6@ujnqdeIT?7s$ zSe)CS3$D=|$50H)bL&fa)KBMNR8^ediIZmArJDMKt3e?&7P>g2pmU$#?#*WtmEU9^N|jOI833 z>Yl+f7j)iC#rGDaIMByP8KQfUQrlen6^X$wI#lhDqz^LBGK}j2KZci@Y>YQ|Lt$mO zI-Fw1sb^d1!(s{T-9#T4qQ|}CGirvbzs$Dbb&y+z4>-9$;}0K)Th+qP>GPhihaSKW z?}rPGEvSdO!%U`{G53Q@uCg%G-Mp}1c8?8y2rV==5W`_F$T&o+L5S5UAq<8@a-_|+ z;TSyW^Q*uriFddMEIL5hwo$~h(hec^;$WcC3TQweEb5qfgwoMIo{;gFdHfGS)+y)l zG5;^RSo((9p@ z?xkC|weWn5c=8Z!-GZbP0`oiM$NXM0C>7bT5+k!T8JYNi58U9eR9Ws?;!&AuNn&BA zIP@MSKD$Go7jh_?Os`seDO(SCmB7oEig)%bw8YZ8OLR{*Y2{3gI1i-W+oIMr`R>1(-xqP8JJ_%jKq#W>Qtnx+4 z#K-+0!LNxMpu5iHG@>%Le(+2}GUl0td`4#yZbj!|Z6$;hTn|;dbfxW;vLBY*G1GdE zQ{R|0yXrEz2{~8gNId;M=p@K|5$$No^d*9)XEycWjs%E`Gn>p8AQYCuMP(Bl))eW4 z^K`akh{94Zoe(daqzFrj2d+?QR=t<2ijbZphAJgnVt+wxgj-@mShmE5uxyD9Vc8NJ z!m=ecgk?)?2)~^g3}M;g8p7|i@b9qT%@%yO1OhPuUV1;y-NR@3Uap5*yOUme>%MEwLdiTVg|4w#0_8Y>5qF*%BMV zvL#kvw2`_e_Khgto!JxnQxvD}iET>u#Lildtw=1Kbrd$?L^vg zEGmV4E*l2!53=sSz`0mH&))kDs-3?D{keTEmbM<)mWTn4uH51x2Q#CtYO(!bI%(&M z|7JQZo^H1BbhC}8n{9A3wzgq2|BqzAKr{zYFxuebT76(rn(gT9@iLUL($a2zD=HD4 zterw9>&}TxqGMRJ`?yH|31yl*POlY5vhjSBjwg5OjO|--x_qA%<$ibgXJ`%aSyE|) z095oGI|!(^A}gup4|r9i?8w3i5IMG;ehsxYS3cgYU5sb#68xaUcj?xSMt3s@c+(r3 zmyqYa_`#ha33fjqhMvYiY17ZyB6n?+$AC#8UhPl71NAG0UeNZN@)7*hLCJo`SJn|3F zj)tL5Wk5K z0s!&b2q6Fvzl#t80P*_>A;9b0jac-_jr<*0y_B9DyW@0o0&Gt%H>mTmHA!ER#8r?UKEL0csjYN9bUVu+A08*-p=hqp`n*Hb!Q33m zqZ_ndXQ?!_4JCoqRQsaCKOq;`Ny0}_AGql4RM7R=_d2_1BMuDnr|YBBoN~BMHC~85 zq2&A;DyRH~GN4tvCD{?~Nvb1ET2td*4~*N)fEp!5dCQ3l&OI6dJ#0* z5nsN~qhb=hB)7~#2d6;);YF0x4(^DXpnS&WcM}=nZwGA7^#-@Wq1@ubQj)!oa_hJj zhc`H_8{vIy#*T%ab#EkJwP+?T4OId2N5AS&>Rtq|&eHVs%}Vu9;sVx-_m)ZgVjNO*TT&_lM3&Qwq>1My$7h(&+O03vt!=OTXW%dlL7Y3N)Pq#Hz z%2C{ifMJ;hUZ&zIO?H8o1q@oxEJohjn!-(71s~J+xJGw59*xV*Dk`&GH**#IU_~L7 zUSVq+3z=y3S(7@=iKHEE^$Jbq)dcYrtHb#%(_oO!bI#HG;geDP(f;?s^L5lS{>%{Q zb5dk^OtM{xH!i^8wkW~nD%dh9tgyR?{n+k^Yt<`m*h3YenS@nrXd_^=goVoW;z7{g zg|y(q)i5=Jp-9cgXEu$kPOlUM+&X?Mvue5VQMAOeM1k#7YzkPfWZn#ZxVP#q>Wj;? z8*zGAE-0COff#L1K8H`XwZH+jc+^ zcYRB#=MO4xaaWP>ZmVj9akG?n5F0otaep>FYFm*?}Itx{u-^Fcg72*`StgM372wi)Zul|8h(dD1U&mVndvMu6w^JEFav=QC1F)iQQ4dX zWs@x-(%2o=o(^GEltffSjDi>zaYIC0al@6@S22nrB8J6%Lw#LP#N_+=oVs=I?dhHn zP@m`b$1i!NZ`G+&r%s(ZwVm2#>#rZM7uNALU~dOWX40j-efpTfY0^D0?lpJ-iPZlB z0`z>39`b2t+UulhULZ%Cm;$>ip4zcD$@qAgS=qHZ^la5m ziO(A9$zbg{1GV$;HhUMIS2*VAQZx-@dGfK`9a8P!oxUg->bdoq$1D3;OFrHYF! z8+#lnjK_XBW2{IHqt#Wax~F&4^|t$Mon_r)XTD`8--KF#9eU2t9geu!=5z1lO{n`$ z`FuQ=C6n=#8@jOvdC}pNAg7_7jM*# zB=VE(2@RL@$Nx8;n@j_fJdS@hizm3$A!yi2oxG#pcq6=f7WJ}m#nvS|#PUK$u%ai5b~ z0Xo~~qZLE5R!U+oM!U$xD1*Oi2HONPqi*P1#07KL;`xf@j*Oo#6!e<1TOi z+X5Bq>Fn;*Bcx6#&*~SbSG_&6Jhcv~4fV|G!CZzj4qgrJ^>ky8M|U9(x*+smJ@3zLX$!+pFhSK^4xh4$>5 zQUCOm*0-zZy5KjqlW1hT>OEi}9W}6EoT}rAqzLDEUc&VaQv!>J>-6Xd)FabfogB9c{(7Y_$j2 zbtZ!sW+Fa6>0X46tw6zfYcL{uuM!FJ3C-e?aMw^-UC#{ zyt#c}yjRWbZzzt`BmQn|J+)4X8MMbs=<%2aCNwav?|rnbv#dR@)pwNG)}-~~o2(+T zY8~erHr@I^AtV?bpTS3D;aFX0SZ)eFUioVPV@_~6bIdL3 z7?FXA05BeL3vCfV8v#xPU{A+z2#C^f39utkV$*4O1jGW2EgRwh zjLzP+0(lYxTIB@Rfjz+FMg~bZbcc1Ejm`V1JFgfToil99+}2TxQF+u$QS3688A`p< z8@ULE-<&!XG@P9Ns^j5-CZ<4=!M#~^27`NZ@-@L}245#@K@#jX2V)yaJF%eTIM)N~ zeLVp$ph-fdto8z*w}Ve}o^~bjhUc9Jy_%rPFAl`k7{iudIS`xW8cL3>2dv~cHwpem zj&w?$Fmuw7<*Jhj>D8;^;)V^i7cZm{O!@o*>3#s|V)0dzEoEZ5pOGZ@hm8-<=Eh1% z9hxp;cu9`1W|HK)Y0NT$_tC+)7EeM;L;AbE1KGH^1NhQeX&1*I)vvORj-ShLY_{_f zY7Gd*N9S(n0X$bbQD&+g8?#<;c?qsT15!ZdVnON?~h2d_yOYu=q@Vt3$#-`9OTy`CyIbo>+>* zhJZyF4+lQ@W;MD`>qDS}@nGp#Tj8h!mXb;%@yZm`agLe|KhM@2je=-T!1DcCCbYd6 z)@ElErFR?hm-0js9brO_B(%M7?jh(1heqAuY;hJ>y5vfQ@SHeG5#e&SWs#L$tlI(J zCAa!Q%Xu~UV;Qf;_rugJ<`>MuZY7y39Tu0qvOST~@^?#f5;K-oN|=kCSnBemSouD( z2m^!bqlC0i7+S%caw!FM;Y>PppZ34t<0B$3C*7;J>c>Y9u*-Q7+~8Pw4jg=Ns&5SY zt7ExIf2%dxVG*gCi}3b%tRIm(k_pWQCeXX@sHi^7jCj{cbGJkAm)CVXz=}+KtrI z!LGqB?W6kk_Ey8nI*%W-p9x z=+Ob?0*OTdN1@^v9!8GvBhDw5dL42h?bk3;xs$vK2&e4a%hiH_kXK#^cN(^wF((#3 zW<L3n#5()BqJKGSZnN%v)lI)uMs#fdM$k{(G0pg~BX9(KAB&}5 z&D9kmP*go>12*A%7xL_YNV@V_Xo6m`!7BKUzNerfJVY;4xI9+>7N#BDR)76}k$KSQp|#{-gR{R`k2pClFsuDFq$`6RS-MmqxE`&#vvjbSlQ90ls<0#X*;tG0(Wg z!{grOHEZ{c;kRhVUx%4Crqf=x_n0apB@748UX{jN`fSXkz0!O~0^^UV3lYd^b;-#j zMleu3d$K*AUAxa+y%>Mfd;}J0(b4%%9^2_chuuy$aV&X`$=)2yhN1VouHj|*2X@Q_ z-*Z+^z6|ZV8}s)36auB)b*w9pzfZ%v0q>K#u$f@vf?A4L8}jgPUb6u&ow^e-H3g0~ z%!PY2m)poMHg(hit11@Qp7;^WcKOXsZe%nek=QaiOFQi92++1}pY6l#auNRRDGXaZ zwH!(6{n+5t#+0yfk(rCRvVZO~j^=P zcM9Co@X~MM-grDN?2Y&lI`r2^+p53Gtt3kl#hay$U~Fc67CfjLCBf{SC77GnoOS#H z%UZc&>3rYczj_mz@ir|%l+-Br@ivlmt<$!(4`^W?3ftHi!ultQI4(2jr!VZU$JE!x zZ~+zKEF|aUCQ~}i@gI$>E!>Cbl7tY|j|H&w(1PjujCm{9U@?a25sO_)j!t5baRh2v znxn!i;m~Vvdjj|K#I3=CGYESM!e|r1 zT!Szo2xIugIcI%(#Ho`-jJ@&9D|)soAbVR~i(ksh<(>vhc;?{t959OWEY&L|xH z&LlOVM0qL5@cwv5I{15=((P`;mYENsm^2r0^(JPTb%pjCjG;u z_JvfKN6O_;CW?O>;C4s5tAD}pa%ix({C9je5+(t585TPaGaGat?*LW3Q}9x_{NMzF zMQ)_I5cJ5C?ekRX_Zs3|hIpR34!ZLen{P}@wdDgxWiJ8 zeTKHW3NQ?M--*vquD%Rty4)PjeXXw{ecoNaqYrIzn^W4qx5K&mFo-B8ziL0opwx~n z7~M{J6Nc=?1l;AT;YyY|aVGy3Qcsp;`&=3O@I7@sAW+2m{z%Cy&BOX~qWo^ayz({p zh5a;QL5p|Cbi%N^FJnq`G%h-6S;fXz)~(BLMbyZh9w%9yXKOp!wD#r(CV}M(h&I~a zT2?Zt^#;u}B_*2#iEP>((m5CMIGW`lD5Z72P&W~+M!`W466BPn$*M7n*s>vCADOyT zejUVvc{hW%4@YLP9jL%ZVuL|AhfM&D{6x-bC9K2NSPtxmGEO*kowgs3N9aRAb#cEL ziLtxG{u~}H^A$q9pWqXWm-oo%O#}i5UDk(Te7}yoR&N3_3v4wmq? zwU?{E04@*fLr!@a7{}8g#K(N6yf3^tbu)cX#Sh~V6v{ z)gJed2Jo0V8x?hAhm9RfmxB*{Fl^(;_gxC#WC*>CUfF0NjG`MLm)NA0Qy*Z`%pbH_ z{@FF=C6c`{yGHC%H(Cn@=|)Jde)Ky8o%ujB*v2*NA7C2Kremam%OE3(OUt6$EzV`X zK|K?(l{l)mHtHX);>sGWl-LL-D1U(>M0rKKb_v@xuXYn!bFcP3{8rxrksx3#T88TW zY_`lhCoxIq<6zmIdMTJv%OX3a!3Xnp6uw&Ti4l?2etw+&5vTd&VWTFSTl+}j5j5bR zU`e1!nTtP+EIOB4P66rg9+c7ny6&=^C<_euQ0Kz5rSI^n%aM% zs6~fBYFs>9NM%v)joD_A`UE~5c5r-HUCcXeDawu(Nful~BKH>=91TUGd zlN?)!GBe?~5dIixJ^1|}@XK=nAyJ5aBuv-a1j}I?UM7#CcnNHnE`~_SO;|&~$^%Y; z7YA_Q_?_LJDj|3nlO*02!Ml`jZv>WsVH8S^{{&aLH0q%+w@W>oQ3v)zIuPO+=(~9O z>`KVge~?~%jycvZw5u;rcqZJDM}2g-@0M^hs4t_qxLH~p032xm;xH6)oA!lR)R!YE ze6=x!Fx*c;!a?v@Lr@$59A^OH2%5h7g@p5#Tk6_QwGlZ}-(VsfFRTJABlUrYQ}EhU z%o*H!uOU8%>s7u5vw(B;2`H1w6SNfpQ3Lh4er|`p1k|vpjUN>FH=sC1(e!CbHo>F} z?U%z*)bBm~G)1v^o;Elg0TK=8Bkv=d(l(>Ym~*aC?EAt5bsIOoHQxV3@I(T745QDO zVD8j#E)iUOvo*daZ;`oyyk@n{vi;o8(nm_Oi2N-?HpjB{i7>WtyBGJ{GsJx>@)f3w z+5b4Yu-SX%Dt|}8bh_J4LLrG&Pv4Y*j^R8M$vO_F$(=VP>~`s0x$ob2z0vNou2Nr3WqdV=LSvM&9%)xi~Iv$ zW-;1&t#3ld`!{_UWzkSUJ@tS|uV0$3A#BUOR%+BOY^jEFUM}Jt`9idIJK48LYsSXH z$%St9JwsF1^*qvF&|D|KZ?M>hGEc;Fn(=-R;+@ivyn4`taJ|N*ZO6hI1p3)8qlqkW z@uyKbKQj1Ub_qiL{i^NKZgu4259tLMbh{Y9tC!)6-Ysm*63MuF*ieX9KMVQx#L%mi z?|~~DS1&|IorL%Ep*Iuj@wV>~T`tE;SQX-mE~|S<0X>qDv4q&pmRhT?k!Dr$g{@WG zFOYFc2}cscsNet@I7nKf1^qDIKmo10K&IdHqhoDeg9XQ=#@IZXW`km`-|HXGVt*DH z-@IlFHxcou#|oz4^^fOuK=yhRA>J-Zv(*XX&DEi>vN3$)3WQ$}go|MHrr`Fx_YmHq zqEOTN)2_M7VzcnIfcmKeR6{dwzfuZ>-lh2}(f zRF5K~qH~V)mkeWwWsN5^#?mgOkc-Lz5UK7PT|b=PjVny}5kYvAVGO^1X!yl3F+b7A zB~i|aPhwK|_a9F4A(JL9A7BN*Sjx3h(4B7wbpo4N4?@1wf%w_55(OMRtrJmow11Bn zYR{vV{KUkKSHFZ@_r&7T@?hf#?iP!y1O1Bf6@>ZqhQq0ZD*6D z9ARtonttqP7I6|u!Jyzp#A%S6GP8+l6~%>prV&>};n%Pz;vuaN4auO+MPnQ~JqAUH zs=w>H=;;EIk@`H2&Ncg)SlFuHXa?%u`1Xv;YI_jMQS*|Wq1tXYitt>jt#1eWxwU?k zuD7Odka=FCmOf?@@J1e%r&V|JX!4^bo*p;qch-w2|LUJ1uEs7hdItNaCZ5M@KKz#Q zEHvo6iai*}M$Z(hpP4A~)>43@9uMHK1!mQ6kgne*p$O$46L_BIn4buUbCo`;en;wS z8+e5M`{&cJo@|NrivUX){Uee1@J)~vw0FM@a4>QCp_#adBkbGtxQ&J!v@dVN{LBoh z|Ig$-F80C@PlkV;u}(g^^7iQw(6Xwh5L5k)(S!Ms5^B7&VH{EvTD3PJO}n;9e%~y= zo8|W^`Mnyy(F9C6&}Q%*wh3Z%;u*-}*xpNVV_gjoBKGThpxmK!DHhj<3Q|Q}n)eno zux*dQy5nIJ#kB$B3E{0b?Uys@Z+m|9ha&Xf(M+E!4*!Hy{CWL$Tm1<>X#%tXY>_$@ z6Jr{PBt#pC-U&kfih&j)_-mYx3(;qpk2j1>nXC|pe6KTndQ~Yg8S~MG`(4Oju1vjo zS@FT_mfCRMhs7W`3-QHH6xrwYVq`qZGZzAilDs6_}Ls}Tk9|A_w@yFO01ljPy#BhE@%2A&id_c;P$CRi_H0+XIt1udS z8Rp2`^ZST5*pGXt=2j1t^e6)6zT3*H!vHz58>dXgAukM#JQ!t11|#^9@wNPHToHOB zd6SwO2U#ss$9e@L;a{sZM(0=VVJfB75_Bk4Ob4Zj3j`5u;#~EvK#01zNiroiHz7Wn zn=R9@(k-#x9bgI59YkVt6CtJE6X59dW=YPtZq9{O_7kyDzHAr7!PJ*!f)B;7S-}EH z1jC65)sq^be!SECh^Oh8C#8z7j>c_`)ktZV^c(mB3*n;!(}b8+Hw0Oq78HvFHRN60 z7(`)xa%4UT3xT{bcKU47qB%1(V$qCx&gM1hy@nhcGD8nq@~rf9qt!(3rdIU+4gTI2 zp$Chd%27G~1AK0c&_%v&c~6D97R?bV|1AbjzhD zkbZR~8ZUY)3|5bBGc@A77;eB;aw8wUw0Xi`d&u<1;sD@B1|SYpv%Fd$HHf^rRvEnN zeot(O==TbNmcUT8i#wH^&6t|L9X0HtnY4)-mxPZ+)A-Q+dJ-fYT*l)vh|LN;hFvfyj{nn)8X^UsW zkQ4pYB`9w7JA)*BlPhZvKhQcFrS)fnrU(9Ms8nGEVZ5iM*uyUsNa{`(KxQ=T^bhBlnN z{W|(zOY@&Wn#d39)iwCyo{8yt{FK4-(BOU%s)n~JY1~bFT3bCaymWZ|i|yn{LtVp6 z{qH7nGEwI0Q__nXUfkl`q_(@bI0Y1`@aDXxH~wf+>il)!?MJNhzCFY@1~l3uY1wGD zM{1*lF=RBD95oObVSd=~^e14nWQ1g-CGlIIpGEVQfKB2bCU4S??Do8Vr-`=v^ZFeo z%Cvbs_B{H_jxv5-9_s0#kQe{88guKpnXC%8H56FmKpTgDeByfG`$AIZKrm>%xv$Nh zhP9$4mJ?tJqX!ac`n=u^aKJa~8t2pxqs;a4X-a<@x)0c7VdzPdY&=yXd{qyU`M@}nZ-!xpJpUv9BPsw6mCwvgigt~ z-iM{vRgVD_Cs@!KZ3W?Qb##?rv+tRYI6sy;TbqS9(bWco=t*#!x*2i&WoevR)MG=A z4Rn5|;XCS<5M9qtcSZZQ5P5fK-x{JnJMG&;ZFmkv7KLH~5@r2iB#Pa< z@py3ax0H8ibrSD&(fi2K`ce&T9dxQSFjJ>K$gYdy;q$FCH`=u>fU%R%DfQT*0ywH7 z-|~xK0f0%G;aua2?$Ife#4c?y19tfYN`N{^U6cH4!V#Uc)JGfh=BYJ|rR)2m8FkZD zcS=Eob5*tvyTboi6TW_{>L)Yk#m5`*1KprKXomW7S7Q{ddqcp-Mpg8o)9M!{PoHRv zusdno-54cIW2QR)sm2Jqlg1|-qda>WpJ|M+J868nF^W!O1!VOoWd+%MNF#J&%Ntz7 z{yT`=(w-Yj7CY^#w3T-CaH@-sG*{OT=__6UT49}&9uCH_)^$&P7D+TzuzH_gSJXPt zkM3by3A#s<#~M*0R?ShAFhSa!c@LT1KHJ}qSh9EIx0?-IMAGM#d4pH)u+?!0?TT>E zpJ=(~k}T}9uCa|Ng0IK4o&{X+rps>FemD$Dour#={KD-wP9R z&)vu^+bH$CU)~&Q`#I1e4z!t%k}tHX}ao*P3Xeo($@Gbc~oC&MZ>lVEorEG zr(?6dngRFAGvWGuOGNJKE3I%tJ4`5R_0>j9-7m*1?t^b3$tSY>c6}&$6M067LaiA_h(FuY_&G8c?R5rmW&Vx}IYH zDN)1W^Tt#F^I46QmWXj5KFx=ZW;3+IjM@%XS`?^)SQg z9FyH(-tu#nNdyIowca3^c}osg(sPTAvu$GsIB?uI;mA!YtJ*i2RD z;uod0iN#qizytSzbPv#-#>tQPNW44<&rpwx1CA(GUVGM2#4XDH`NocTd7gx0+dH>Y z$o*6?+)w5CYnVN;?!=D1gTQBZ!mDR6UBabgv3j>SlJy>ZGYMR`7|k+HKb~iJ$Lmjc zu`SMl`er1=xpG8)=Nq(X@C#;uUpNE&q8Z?|8Q@a^oNYlKa@DrRkTsNB-5}{Xh0J1m z)fVOg6K3DV*@lE*Wr!hcCk_BTXPO=~PIz6sawqy+^jto(5v-BkGA+%wpxx_LHwI~n zOVVUWOo!|u%{KrGNxu=F8PmKqO!J^1H@#{r6Xm?hcODjmp}&wo_EEUUNAk+m@%CVq zAX>=Nb6& zcd?<54ntUsWD&fH&lXisADV&1YYYkKvF6XL>pd6#q#H>!@%L6k9Q<8J5n`htmGeUV z!FELY&c_F%);q}IrBNCpMD7Jq8x0{%=5ihJ3jMiMe=gHx?%V~Lw*_QS4n0ef^8OB- z)-H<|+ry>k9a%}nE^+bUc7B)@)Ll$YXe}Zk{A-zm&Uj}+T@oZuSsx7C7P>IQFd|A- z%KlPA46<#?%Zz$}yhxZMT7kTX&(%8eiRX})x0~ceZ?H$hYN^* z{5}6XtLr1=L?8d%GI>{o;Qdie-BmlQ-e_V4?ft0VAN2-(x$cj|KSO^6xwfbt>MBDV zRd_l}Gq%}ki;2Z{O!q-!&x5BIw&v;GhB|nXK61uBNPV5{UyE-1O@@RfFmq1sn}NW4 z0s_(t&PV{g;Qx}u487o+12Qup+z=q3ej1&9{&hfIZRqJfM%U4QqYm5{q4!PBrY{Po zg^{KfFLVWSJy&fqkz`Ju)Rzk)e;Ayi9hnu=-EmC1W7@dH&}CJz)iQ;V!*_!|Z6U+( zFNh~yUrf3_9OvJl@xK?~pCs6@8Gz4|@Bp*k1sbhrSg1RNgO2FXK6sQ-c3L5XxfOyx8H5Y&?=(#H*XZM!g2{1v3S8vq{8*8K+l0MB4tziUZV-==*GAS+u0B z-fPHU4aVtR@SzWmtWb|IHoR`c%lhJ4ucTn`kFtr(Z4_tU7$-C)7)~J?vJhk}rfv!n z*R!haOn8h6m{pI`&G`%z1)|z`fO?D&@{zJIKn})+uL#@arvAElOwlmI3RvOb1rq{k z`dYoa*6DV})cXv#tnK7O&y!GONn<0eW14adDYmeu<-BM6S)JlgEg~ zA#!!B0=~au-fIN}m-h$VO*J%4*s@Ll?jKqXkT>!)^h4RWKh!C|fftP4hM!R!qoSue z3qQETQapA|A)cDRN%`_O0Ix4(vM9rt^}aUC`Zd!6sb^3+!)~o3hQ-IMzIQbmb3J0Z z<=^2KMxdBF8rjBWO#SLOK(IbZnsNs#E)v%FVdH};laj`BUcMT~#mg{HReytIa7P%k zk}MwsD#I|DycqjAaIJMht~0JLK$xTNZ`}rAXyTD1q?PnWH)l6F(Df2k`juq10u z!T$BGxEiKquz%5OGLzu-t{$#;O=XgF#^FSE$zmpTS|+Wpd({A^Jng#IC?LG))sKyf z&v|J^`AG<*gp1=yGGE4{pvaMS<3Um1jlqS$uti_K<+JsD8^mMT{R=dR!@LkjN`rT0 z;Ia+LA8;HL6z z!#RNc7J2Xsp$f|D-wL#90xn#=Q@$2oPcv=jM({jU5&+ePpET29eQ1v-%6|X=-nZjJ zFh#u`mjXWt|0D78FYqZLdc6E=xJGZ!`tPM2Vr7m+X7G=^dNsfjh{ac_P{TjNNVDKfZSNTtnCgem2N99`8ZEpy z)w96rfsVFe$mFWkWcE0^j)%*sT!R5|Z~61EEMZs6;Hmn*>IHF`ufbv_|4jc=*$R9$ zgkamPd^m8&DxVJAoo?kzfyb%ug$$v?8s{fg-Vu0=@N;2H6a;h4Nqj6GUQ`` zsWmD~X*iMuIv2Lf;3afk8*VH9P87W|D+q3Yrf;5CW?jNlkMzy* z%B&r>;;-BleUXl(u{D+sRj9c|$YeC;^a2xi`DW2p%N5ETf2ut}fh(;XhoPGCMsS?9 z8eEuHUxMm&Tb28%GWUvGr=dDP5dpu829QY;@Juv-{F;Eo{0J$sZUPE(f&le(YW#Wb zws%pSFF`q~wfJG9%et|_5522p=*0}x?bJQU%O8-J*tsN>@|N8KfLHzzFmQeRDIm!U zlQCbDyA``^xBLSHl^?`UwtOmr(HUgRkHg!M#NlKXZjY-LgXx|aUKuO$pe(KpbzEHk zxuyIl@NOl}jTv0_*n{OXF1U^Vn7{e4tSTezcqPyLqwf1B=&=xYE%w#ouOEN2udPbu zMlNIO1)w)_&^A#ik-={WpuG*xo#S;bE7OUk84*mn@=}o1Q_`5POv}o^!bKvDGF)~$ zM9?zFmGzj_%B{<3$zpqc6QlAKmt@8r;!`cS<67TpFIrtb0eZZ(A&eR@Qy7(CrZDP3 zBrKj(C$f%!`^GX}#!<>PRu<8U{H6jp9Lk0=+B%erditZD*%6Pr60+o_L%r%Gq=e@} zV);$j8UkXG9Dp?+NfecxK`Kx`ir}Ww7HRrqmf*V6w^3pfCYD}U1L%l12ciqF0~Fk>uV>jM!my4Mn||& zBMzRoWRCAzGKOgqBMZ=em+RHnm0m~48_j-0@VS2L5uSUKN+83f|`vR>UC#Ft@ zqN-E);}hE!#X4XntmbyrFQ`Hr8i@KQkZHfj?`HnZI~|S=aq9wIYuAWaz%^&qxF<2O zyM`c&UcQv10Z1GI#36Ee1?1%SE4}@uUwJH=gTrQ$)4>er)g4Y#ZZNdF5|YD}7vCT^ zl|WVL#n9$!{KV>C_gNLB8=b*t@QQgh*oFa}i(a+_#sv>qV|1CXivs{5#H@*fIuOGP zI67~3jnPW`qVL2T5`N$LOf-)#VODVDnSEzdRw|1YSm*Tn%@Ax4!1bG&9Nx7EeCoB- zfm89r!2~mp?hbs|7Gz}o8M^4GRlvsM5d5U=_-gNX?21~4uJdRB^uTE3O|vXn?gR7~ zK;e5MNcldwYfn&6ZUzVx3~h{0uB0D%8bBJbLn>&UBR(1R2Pw!PU;Fgkf8^V>jsf2s z2UUB>Hipmh@b$SZ55Nu3U<6dqp!pHd0u5Ri0WBg3ZE%~={|o5bhq_1!qjswkf86yk zjKAWNh4{t4Kdwj>$9(sqm8s%_g{RBEWpHN~9`)&gD}MV*7w%MuugBqELFB)ZK6vK* z_qmv7_?Aum0jN#&3`}6~Ohx$;LSBUn4Qja0}5r$486w|?8ap1Fxmn3HEtMRdG zB&L7GIwPhNPo0R}cIkL_$vpKo6i|Dj09Can5^hfB*&_-4Rv!15I~F#iSby{Lqisa; zCQo#>w;pW33>TQ0v>E$4Bm$#VD-L?~mJf9*P};ZmH^;pm0mF{~&e-AGKK1Xz>zjt| zhn!neH;??x5Ne+LnIYIb{4+!FE}sChYh*C;4v+>!?LhJlP!zzSkbVNFb&BdFzp(tr z`ZP)N#??}5=y(gWNo{911m76Ts-@J`$t)4vcI8vrj`IcN*I1M2#zmICIZ2p3=;W6t-`+qFa~|V-eET{3NWG9jp04 zb0_wzal86Xh)|t`AKXZ`VHS)c^`9cP@BAg5(wNkLMW^l|oca^+n6{F2_$iSaq2&ia ziZ?INih&2dv^rl4euv|DMtX|G)t?ZC7o=;9FfUhr2;P3on(Uf{J`FFIB-B6P5N_ly z%OjD_-;vG&e9=uwWV`%T;G`SgnbNORwKu@DUUtw5nK=He6m3ux)g!dCYuWTz^m-1df;jvf!8H3rE zVRmNyL(1pp0F554C1=VhY;Mx=ZRk35@2yTlr?{Tpb{Li~0?iInl+wBwkCZEpMb=1K zk`;%veSK*Ao<_R7m3A@2Y)b6wEU|9eFCV!gJYia$#9+|CsMCQrdPcXE7}TYA77G5p zgH|WcI$oU)?iip&?FVFBgq)#62IQ@=NDMq~CNWac0Ew{%A=}SxnT$`YMKV4EP05fL zNi`=!1{&1P*Sm$*uiIfZ#XnP4|CF-&#q%ty+OwAxNlRIY1DYhY`3TzX*cgcI&adF) zX%TpPhCGS6Ma;k$S%~_Thk?Hy;}lz(2lnBfbryyN{{p_F-XX12E3HcV4Z)ugzf_FZ zPC|cM;MLV9%I`!!CL}>ypdU^-v%ZF%vaT-@Z=sHtJ25BtK~*vMCrc;Jda!Ie@}RN% zPwb!Q26ckVFF^8V)=vRm7RO^XLjJ`3#GoI}2}5?ajOwuSHshXIe=TrxKIXuQ0|6!{ z4F)rY7n#nipGr*J04@nFL-6RUlcUA>kmNOgQk_|Dkqn>t`aS zK`ICmekYb0B#x`kte*v>V!%ZUT1?ER#Zm9%hwE{CANI*>HWfV{i8qra%j|l)+H!cghc$2J_WVNNb@;Nw1v!ouCYy0m z*ZsO@oya65O(Fg;BH^Ydsx9l#0z4?(@8N+N)*+|HIyB+JKOzs%U@3Y0iEQOmOv9WS zYr^cT)FP+G3gmmL`yi^$-_c0R4%7N^n3m|UugMFM=4_@Zn(Wl5%F_~kTth1rq+C77 zr>|`bPDuX|(g(2(PK`>P9X~>6Ow`_2{(TLo5UBbhrp>ybqfIQQpK9;asP-^2BmX8^ zsQSG`quTq?8pO2XLM{&J5KX3f1W-{3w26EIa&f_Tw6wG8RWR{5SHptWreBDMJrtXp zch%gQY8$q&y>`6D1{LZSjJE`nOA z^YAU?!M9f&InT`H-!nI`>r^g9Ss6>rd+5GbOgy$a1r(V>&hhVv25@L#0`7|j@U>8t z(=o6T8j@Pe01Wj>>hIBjbqtuT1F{PvG0F_U%(kV0;j?ySC6MdCX5OXOtUpPoLg&W~ z8uU~-sILD3E{@jZ+qgbP5DbI==VOr82z%km2@sC-!U96%KQV}dI&rMEYkvfQ54xPd zBg?9(9|;5GO{2zu-%g7` zzr@f1VT>T)cVUc;OoM)jp#vmFW5Dmj7?&~z{Sre5NQ^MxNSzJ+{E1V33X9Izwo+sI z(_u`}z+w;t@krCa+6jaHvVVahS~0dE>Iy(U)y>a z;_#m>Wm^9$Nc+ye(b-r3r~W*{kDh(~i_XHVJz!C6;}W%=a@ks&b|4U|vh!rOS61DR zG;^3ZosR1l5Yk6GE*&FwKBqXV(!9sy9nToYWZA`wWmQcq#MsdKeN;7W97$y{Zq+_9 zjAjDMH?&SjZn3AxnoL#jc1KM-GBdFU(^*N4tOWBmhEolNWqg@;GRmw9qjZee13sf$ zoIV&5X9tGF%OJGKt?l4K@Ih!N<3XnEkC)>+bH139UFAzt;yU~-pyQ!zRT@zSCOYNY zzdApepM;ev@TKPV=C$Z~7+KxG!AD%-{gzY*LXz zYS&0ol>x|j-a~62ROi5{UXLGK#EZLoGjUacXRBHIN{oM3$Iry7$HA~QayH)3h6p%+ z=2vY)IV%iIQX@G$_0r$3z6SsoA&;{MyM^06QIx(NZG>X^I}=eK`ZZQguvlc&JH5y0 z-;=M<0X_RaL{I2|9_x-Yb>g61lABmC)-ulzuusFykp56%C0O`mtJCj1_YDq_a3dt=RS}&c{2t-DFam3eSNiW!!;$ zcN-oegcGnlI}79$^m_ zA{B^@9ts=H(0`=P7&^9v#SJSd{SCJ{tjF>vHa2AI)JWmGI^aRt{0g2{@~G8HzJl+)Lu`$0WwYdqq(@);1)Ed z7pBI&kqxO~a0)fEA+k*W?xy#~hV+)2a{eZ0OMmLf+e1B4&+h{;<&+MCC4xOn`BeB% z^WCS>Ef2$+P>u`DEAoOafZ2d*>#?S9%RQ87%F|IaET+8Be4fVha@=(2-v{Ez+0+Ox zZfP7V3&Ms|j&Km!sdZLlTUKMb--BG+k#2Pz>UYZ9hBX7<5cdrzWc^bZiR+X2^-qV+ z&xFp;(wVJ)E`&tz?jbZ+|GfTuL8E?=A3el$e^}#*=I@p;)~%uQw$S;0I9dHLfI)5Jxop*-LkA=>==wR@9uSH@0>S-@>RTj$)>bn^Z9|SWgB$MAG5lm=HL9bGX5t}FwA@H)`Zi>rt4zXY z3(tLIeC&`h#6fC8F3JgERQ@Q8_vrn1<=6lJP5Jq3{rmD`e=-Jzo5l7oGB!wIqc3|` zk+viD^YnIHtPJo3^b0+UY3nmAVjF6#cvaf6Bc_|=5|ta`UpmfYgFtvBfRd+M!H55(?)2?<9{r9S=5VsE+&znX=v zv$!ZiG9m7MAxBltF7`Ds(aKJZ&GsCHmG-r3|G+mXR>CEFCS?4ctepTQ^hfaAOHb4+ z9z+yeNjm9UwvjcMmGCuV#38wC-+ z6GQ&IOibeaKn^BmG;Frz&aA(V@eDa59V8*{RYd*gbf5Z5+Usj4Hs$M5rO zauzL9zyGJ*KgPSRtPFKWNgJrg5@|gm$D1{>OYlLxS@6Mx_H_(wSdRia{>&a%92qzH z;6pvJ!GqAOuyEO|Nb$-WC9XOb$Qjq>gC(wd9GWwUn3yneHr4MJ1VVf?K6lcDmTyAC zi{i~_bElzsS}J&0i07MhJN6?{U5v$X+ZBoye;A9$B5hos9+q`EIc&clc6;2P{1!5@ zV_~D%-dgLNL)(dnzcl{18D$>+xWxhsY1V%DI}m?I;O}VsVZW1g8vcswl47$<7f(xy zK{j1{by5tj>Eh8zF~g>dM#r=|E1WgwgC&eO|E)FMa)U|YRUQ!I3 z>0)oPwoV}FWR2>SF4}I|WJKEQ?Rc`i!$4$N5DkOe*~_ss_h+}yv67b~S2i;C^fS_B zqTVMgjQXvfP;UmiM1p;~15L;KCOn1ivp6CeGPrVedm{djo^ua&C4IEv{`hKv^|<{R z*8m3$Fg80AGr;&J?9Q=!_%6OAO^tTdD#M%USs%q08vYR@FH znPmCL1n_z(nZd{VO)PajCdDxiA>tJjAz=TCi1Q3 zm7e&Dm%~`>TLWA%Du66)3w-d3~`oQiHAAi@h zoT8s$JF^pc#M-iHX9hc>`qG~0n^>OTgn<)YjL!}}Gx$uO*wgWV{oua_|7AS=gF6Oy z7|-m!KI0rooOKCRf)EA5l|0C-QSS?^*SZANBd*19` zi(pQsUrsHGO#?k6J85)n(l=iSwh)nve|7e*y5G$1g|UJ3pgJNuRZp^@)9~}*_qKjt zOHyWy16lI>+ICQ9VR!rfq3Wu*>8y}!3r>~1l>Z&g#k$9Tk*uCX8T3RhHg0~C|WVwz_hm8v5K z8Ve844yg@r``U(A$qZ6fh7|f#dhWqbz}}-SW-{0^%P)*{9`u@KAo<>bRUJ8ArZ(!( zB&&s6Pw^A0r}@EV?{+^ZiSr#c&8v!9@#+JBbQ>^t852L(|YGsFM-4^vL#IO_V9H6OJ3zDsKSU3 z4{`zcDTG(f=I@)b)jxu}jm%O`JBit^osu;8rJitTrROO(!@T3fct`PUa|{|A*}e)W znoHn17KbtsT%z_*N2M%iCyU_8JJiDtu=CTgdD3B?@?f&{ZwM>^4z%QZp6Y7gA`?lK zTr7FJgVSSD$Bu0k&u7cgY|Wv53CLHmfKV~ppn8Sr34rz-q;Vv^kusU76e7%`Jbn-m zdzSL(u}Uj+c|4c2SYsZO{2;CGKfkmtc(#1uUNb4!`C82y#2C$DabAEB;p)L><4Wse zk9FJ{qmPa?1fKHfN2+_m0x(paLfxt_g^Ht_^=fpeZyT~fyS%6|PMvYE84Gc|8o%oP zFbdz0c{lLq$XIF(s@1S0mD=_(R26+ll2&*9!Y=C4cTC)zen03& zCi^F_HE7$NL3G(YORq2vLo#{TUW9}E12s%ZQ0dh;xD~%jqZ)FiWrMvcZ!_y`uJtMK zJr{gO2t-(osAYRXnuWO9*2sKEJn1u^%wF5$>WpJ{F@}Ze-OI(Y-N;2>w;gSGB6&gw z%HDCqO}e~kC4AQ%VgBChmrLvXMVisL`fg*!c)&C)6`imDcG>h%KC(`)L#ghUp)syr&Yy8qg^i0rq;TvxiPHQ(Dx$xc~^gTQQ?S7K>d~jLv(DGYodMv@6z8vTr$;g>Nr~X=cp@;I#Z#aqG{DzbD=M;We2L_;*^Ed}M z_hwXd|GhnlQlkvTnV;@Oi!mC^$BYjB+zDu=_ z$-#F$eK;Z59h?x{3W(V~sMEvXzU2nKzg4~t-0BsqBKxq4FhiBzp#~UpS2?8-CRq)| zf}6QTEb`57sMDL@ut9$=)}M{~bD92JqCc1F&*l1q`^XvZN`8zS2SkpyMdZjtyc&N4 zInvW4M_b-Kge)^^SXNE2+oL!?p4ifnEN5s|$K2i4bk0RbSHixKz~dr;ETD$KGZ_dSoE7NcS0R=_2c@iL(m|1P zoAp2V@?YhNK+_JOMpBn5ONNa`3XF2DY-og0yp?Y?!YI{BevgK@lvm}JVSt;LA`PCTW0N~>WAPxZT zHUMz|fa`R16mbCXNdpiE0G~1daRBgX0}uxQpD_S&0PtA@5C;JF7=Snc_?!WV;|RO( z!*73mOPx%G`Te}X5eFiD!2rYoz!wcb8~}WY0JeRjsBiq|6r6-(y>PQQy)N5YveFrx zwWP;chTUEkoXdA2XuqFHI2urE`5%0zZ7tW(7-Fr;9sEP$eNF=aUk zVQXx_DRivd+Zr?5>^_KguyH@A2o3_g*GNn28aWIzZ-x!0QiRihywr|+|*IT0RXNU(*SV*Kz1Y*aRBfy0}uxQI}AV^0PHjX zaR7jEt)?Lk0NM;d8~`wD5;18 zfTRJ41AvqPhy#GM0f++t?Bdom!~sBu0f++tDIYPJG9>8U6*d3`b4;wO$v@l4ZpmJ+ ziyzM1^>vmVq5ap_S!#67zP`@#qBDPeoh4;EIYwg{(TQlHHE<#t%Y{%xV~Nm-Xe1Q;S0-cCP`O}GLqHJ&?8f8u>qEXtmGn>&UXF3s$5~dT;C|f!aO>`7aM58?Melep_ zl5`>(Wk@HYQF?SD8s$bOqKW9(esL{n5M!1(o4PT%=JA>iFFr>e(ZuT8WI8@){0|;P zr)$AYaOSlB(~0{_C^|Z4Yn`VvueJRq52Dk0PA8&KbaWybMMo#1QFL@78bx=L2hnLw zrW4U9Iyw=JqN5YhC^|Y3jiS5BgXpxb(ursk9i50q(b0)$6dj$2M$z5mL3COh=|nV& zj!s0Q=;%Z=ijGc1qv&p;VNzj-ndfYAuQy{a?wu(>mO2D?8EkQ5H^CMy`UriUg_vwl zy7{p>JHG{PI5APLW_u{VK zqro~#1~g^HOiO!t0x{|YQPMrrzTNa6g|~J{*H#^1(0_5~HoMk~KruHeOg~e6f{+lg z?C4|Kb^1}*9P6(X4%xlwQVi3@G7^);hp8d0mtnLnQGJ5nhTlC(r!MmbOzh=fGp$%D zY0ndKxGVBG(_J|uU3+!|kNvHAJUYVTfiu&}H_*zrrnTl6pBU&+elMSy-kb({1Fh*D z6A@;9G8RxL?N`oBd+zSg2Cus4SyCY0$h%{mH#7Z#2Ks|tyUBc*T>k_4)svlWl!Ms< z3bOb_vzplbI$2lNXtdtp8ZKzJ);m#jz1Ji-+ccxz;<`3X!LCt(!yIr60Be8`pCy%t zRY+u{2+j_mV8qc=CaP)srt>bBw&@46@_D>}@x-gl+!S;3Xz&O4E4( zaxC)Nn(bGaX{_}>6lE@(Dx$HJCXIUS^{*xqu6J!z*8t5;5*`B_*ZA?y0BXVb*Mhdd zu{g2VJ-+e)JAy4>F$k^8O48}^f6d_jGPwI_0`4&^}? z+yC?MP2sQ8|HFt**7u9Eahvhn{#3C)pDOkaq>5eew-0vVO5Fkd;G*X~gnP2Ws@~~7 z5U*CDCD>3B;Xf`jDs>g>Ow4a`bXyVWcZ1@P^7uG-zzac!XK)M??6Y!=t%Fu^KDb;2 zt_$FLF1YT8zn5Ikl8yGe;$Bh1bq=s$=6U8I9HD&z9M}6$4T4cyZc_-uI77lX6A=g7 zkuq{HjC^k+UbsAk4HiV%yaoqT9+GT4C{oAvNVOO|t2aTmdZV(0u6>Yar;77+w2Zq2 z_f2}icuK)?TQs}O;^Pk|^q%a8k@g;xxgO2Pc>?oXCa%3l3b@GnL5zUX)3`(H!!esq zd6Fsbhi#X*yfLwQZBmaix6%5m^TS23Tj}L_Nx>NGiViWc57-CyHh{5BPGk2Qu$-ez z#6>i?Q#2-{IoV&CsQv(aZZ&!IR-A*qlzJbWe$!bopAwOCmkbW=w zb|vUx%P;t38j&F;-|HnvZ!J!O{tWLp66ra;<46v6`HmyUNku=OI)_nSklRFKZoTTG z%q%v(WV7lQzSH%cpu;@|FstZ(A(E?D&gpek3dC^uz`Xto(?C}JibQ6N=VW_(vrX~1 z8wBb9mQiJAi0{_vFKm&1r<=p(jV40a_K{V;7Y-QLg%PWncSKd`7M%Yf5^qt9cutm* zu$tmZqJPqnca>&)i!}edn`yR+`_~|@V-2?AH>WyUB>5DhaU9YzPPQoyH$`RDKTQ5& z7M3Ap&WaQ3m!N0jeiMGvQB8~GytwK_>ZrDujLP%Bq8|SY>9AaJJp|v=jcAsW^*o6g zsgvB!gMB$cerGP%SuHZW^I76K*}R$_PZDf{HB#ncXzKA)(q2GB{_3c@*&IZHcV z$!QSF7_~8A$g#8GfI%Dp^c#RU0GMq6;s79T0O9~(jsb`RfVl=B4glsEfH(jcFaU7? zfNMoHAL0O@U;yF(V7>u}L*#QP@-_l}lZz92A&!n@356|nHzC6r+`Glo7JZFj88@!> zKryAZGtlgqF>;z~4KBwz1pcuM8q&x%(rHK|*BG|DX;3#l)dodIKAcUT#vl#jhy88> zM2~^CeWqdD7B@Aey{eFdjzm%wSPSCSPI$Ls*paL)fTYS@@QQCCeci^l2tM@(4Diam z1~e3avIaC9fcgz+j{uZ6AQgb-8ql5ql?RM(gua6D72(?ib)HjR&oa6=3;=u6g^ zg%z*i$d49jXT_==J9o<1!IryisWZNXj&k;$l&|lkTzx0y={qS$-$~YdC-bEzSTG>U zM2i=M<5e;|HDt@SwA#;LrpC<=OMzL#D|y%sJq_XK5d^MRH6i>Wf`Di8nh|~#LHK4X zgkMJx@Jb%dlG5I-qcHH#=Lj=??qaLq4ItN zL+5vb7&~+nyw@Trj0STJ5m5<^NFb`*SZBo7KY=F=vLj#Kb$pNw;`5%hT}5CHOFkb` zPO~M#{WGQ@5xOG?_rCdTGG*PP@f!r8Xk8@kAQWTZ5IiBia& znBC!kW85)AK~0l?jmxAX+h>wMqiX+wxW2p}e-82f7>W19^NjaX#)Go#hdfB%C=LLY z8Gtwd*xvxe0l;zt5C;G+FaU7?@InI+2LJ~cfH+K5M;)@Q66#Nh^UBg5g|FQ(_Y%%5 zajvM0HJFrla^dZ5R@>^7G)1-;T*rUPadMkQs|CjmI2>^`r_o2Fpi=N`qKAf3zs=%# z1dd63JVzbdj7UDl8u2iU7P3v)2#6+uJT&vNsyT`MZU5A!It_uC$L^T>3p5;#I*VSU z%|7xVd`BS*pI4s;44}wLOucS8*(fi-YRQ)q=3T9yPC#U&`H$kA*AmZ`vmFhxyr3Cz z7qV=^j`B|-FfPk0Qm&4wwN9g{T!nvUKqucWmMaU*HS;R(DSD@-hbfS8KQ<_{aE3U3?9ij&2M0EUkq% z9hce8$Uz$j4vjm$?(B*9FzjV2Ph!uNdJ8gzlWN!CvmQ084fla`RNo3;8nfWH;Ty+u zbYpfYZu>J~cyxtHms*SRu0+9Jq-nXX~S8HzXS2db;MWW?+pB%kH1Utw+VkY z;O`6gdjNmG$KT)ahkKu_+wuK4{`SK`ZcAaN6wXuEp=YO4O3XiphGbz9#JqAc-40Z0oXLbhZQ$` z?86|KQ-L)eIwwNsA~-7x_Jnw6g}@;L)FEAA$l}lm!8K%gw9(&f%{EVUsJ#(nuDcv& zTIRaT4wONQ*DMM{!uvnVXNp4?wR5q58wWd z3Fm`EaMWWsYE*xO?%w)#erohA`yp6F=)RcOmOn$39|7tVxTISCEc|#xidyBB@z#Qe z%gAaB-^7(Ip^{xoqj9z;Ry;Nn!_8ge4&1m7Ms*__gQ?Y6`O4rnes@q6?Toi}lGkKB z3JQz;ZwHpSlXXJu8o9#U;=TSfAeNt`omr!Lm@JQS8>#n0A<%M;nQI? z(ko%m_z=F@x5MV3F~_zlW}z3g#zp3TK%`|f$J@0Z0+*(Q$MAI~>-=bsCVjx=#4;o$ zRFcGD;P)UaXHK43m(=1qrXuChxqboUR@F(~)}#cZxUWt!yVsbXj0jW%bE~dfoP%5# zsn`i3bmS&A5#dmaUk6;blwXc`=RO1R!UTU3W-#Pbtk~rU; z^Gb+DVt9NLzheMlbh$*6iVLglUYQJO4=fF1orzL1k<>Q@0$-0jg~<3fa*&0R&G_SZ z*RFTOsn(b+@b6h?BYpmJVvA43NxsRhHXK8p>~f0Al@wyRRYP5lEpCVIHc4M30K56B zF1ORoE_qKEd%O5?F?GnFBwU zltlR^2zdOfy!lbQ?_&uW&sKVl)FEiOqzGR@7~U(Ea+Ttlj&XB~SVs{yT^nv8@J3x^ zwt5QO?1iPBf8yJiK)JPt${9yxe zn@o5-TuVzB>_2xPdA%FZpp8H7ZTKKqR3E~RSA8Qp@f4oZMGL6ycU=G67j%15cvkSk zKq`L(Kk4GW@$wyT$a~Z631@csQbaAeiH_|D(f3h=;jy1mr@m`Q-#@g(PNd@HI}tQ` z@AlsKxd(tn+#uwZu#%_`$$Gr{*BMEg^LMkXgOAcS*Td{>{g8%UvHTcF_~WwW;BPfLasyxi4{Tc)z$PI_ii;hIa72jfVi^AyWuDRxBStDXkJu+Vp` zmFRbuf&R811*!9v+QH7%>aV231!`=rc+}f5_ua_Or1PlP|A2O5Q^up-?7*|bn~U;N zPa?vjUOobz7lP+Rzyl$8ZUj6Sg6BoRg%CUt0nZP?gUJYdK?I(Pz!yf~=?HvL1l}Hj z4@KY|5%_QjmmK5%N>|R7?k{CUsj2xGaba_%8!Mj!?CpHZ@>39P`*yUASOJGLG1}w5 zT+T`z0`D$qy#7Bxqq4g+Y&o~xoR@O76$O)zzCM$WnDlMSTgal*Ew2X+-0{|)5OJip zTU;kMH1c^vV@4j%-8~-KWSzGu59RY(MGw;N?KSD^`%7Epp?rRG4h;YO{kswWg58Pl z$o;8J{5x*>!WKC&>1VSheSJ?vGymm_no|$uZ{qhXNn4mp$iKqI*><%AVQ^@2B`0o6wQW78Ud(p$ zsHhL^?%@O;X4hVVubw}1#|k>#@)3ZHa{ms4^dy#j%RaQ$8zk0Ht1$v}&vqw(QD0n;35L1{X zrDlXf0Q)gE)4^FGq=S3Y(C3h3Zc^?vL(h^eqc<|iI$Le8PDV9WBo~gK3x0Jj=t3?U z^FSbp9f&l7JkS&7fhdv(O)AJkOE~gyaAO|Ow;>NCi9B2dC5YyMV95iCX{<;dTmUJ5 zesvz`YRUtF%)?7TEXV^rVIGJgdC;VSJhX%(4@WX~SPlnD9!L^-K*ejw1HqC964P8n z@(=@%dEi&)fv%=J5Xd~d3dDju&=cl?D3S+FD#$}iIP$QHvBNwZBzYi7(;s2%&Q;=LvM4J%u}M4DLYXdV%65 ztf^Tc7#CpOso{9s3Rl&*>T{CdV0-004ezk0aA{2d@2vbn!)Mu3-4S?K1p?$fS;%cq z1m0a4(C{96sy71ftsJD`efCse1fH#&so@X+F1iWQ?XO&_;Sd3?yb0j>$_F(Z_k*2= zBFBReJF*!3&(Sx4>5H{s8S1SchgilkL>+Ri2^fs|Z}3nf`>zWvoPs$X$Q1kE1b{SO z%``tRvdLHai_9v-{+bXvw{n0$A$DFW=i?4kjuI%veqsoQ*wA zKRJTmS-C^QA@)-u@UF_YG#p}oZ3Nz3c~Zk6_ERJ9-b!aliV0#rEdtM07HK%detHDn zUwMIsLj-3;;Q7ia8V(_x8G+BOT&dv@!n2z*K977gFao~lOR(`HP0{ zV^5tMfiJCej|uDh+EeF6;QLjUX!tUF>ih_N|H_dXzTBR=AOe3upgcla$oVn7ae;z=5E%9;XmXGgdMc5d(VU|A=Bm#(`n zG_F_GjO+L3S=PJ1gSOXlU=ZX#&wAJS$U0QXv*u&edoOGODeLh!S=K?IlCs_cDs*|) zDR3n|Lf0ojmfZTi5m!B}M3lOSdH~-G$?FW~d9Cf|UguWSu zN{u%hNG*hfLqUFD516JrE0E+) z=nrAt)=_{JuVakIeeOH0WB=FC`}`Ke%f6q2W<$c@3XfE2*ZCC_w+C@arPDh3WE1y| zFe)>RtTh|l>oi`7k|BScSU56xpTVW0cc9$zxOlqF=k$rY49|Oi#mMy2pr!Ni``>EU zfOQy@{{-l1r{((e2Jlq2hI!UJq@-iq@OtCA@2|!+bd7c`us-$;&EEoRA3V~eIUPiP zJ0-uL@@3F%eczYWu(dpp+W%wkE#s@WqW<4K=gcGrO|arE0g79&qHQ4V1{5pqP&_Rb zNC;jm#jR*56bck64#C~sio0uRvAfn@zmv>!@BhBLFYb$nem?!>yY||?XV0FQJ#$u3 zEu}Tep}rof-=FT0(=@#vd(!{9PN7n&2x=GkYXJQveV!}bZ(_QwRQg}-(qmLj|7+n4 ziJMcELoax!6#PZc1=IiXpyPn+mQz(2DD^F)veVdg(PPU3s$4Cl`qAuFLB*uXUmofP z9kpD(g~sf|JO^;^ucH27TLtwkJ;3D{9%{@enJtQ{)@Vr&RfonO_jFOUnC1d$)0^pK zZcDApNAfOX7yVySE3dZ2tc)lC|SQmQEWz%iF4v+8n9;(9rj(uZC7UuMDGu(JB?qEZuR%JxvJsTX)Yt*$0cbeDM=N?Kjr?cuh~OCK8- zDHWNyzNFIg2rH@*&~HW6SCp^x<-LF8uUhIcs5GBlp$ud+1r$X^R6U-_%| z5%*sWXdV~aORC57t8|w^IVZX6wq~q*bdE_c-@dlegPBz(_+?l5s6TjyqftWVGfuC9 zDptomO87-uw&hgOR5vbZ1(lylAY-UF&3aOTDQ(=jeNVk0N5yq&MGh^Xj?o+;F&6g{ zTTxY&QsMNzR@tbx7Seq3wMwRu#4(C09}4xO_VZ9p*17ZeCjBUzhmq)^8mIr&o#rr( zn_UH7ml|bP5eMCMTb4eGS0I%FY8d?`rOKDyLZ8z8_NUwWcXPMt*&Xh(jG}yHrs6qqmT3I!{<^Jm=wW5sO2Gk3Z@-#a8a|{pFD7*Ww8R;$QOSP0d+NO`N?6mHY z7){g1+N|_rI_w{J=%Bprzoz`|{wrXQ`>628UtW#`nrYnshUIYorB`%@w|YzSRo6>O zb*3?5&{D@+89z#^u*IP*k#yv6Z8{Uv3q)?I^KvTPsqY47g*rV z>xuE!!L2ck`ayhN7*(8H_p{%-(;4E}NfvK4>8?B0M6z(Kakt&EQXN;dB{e;rRL3Ko z&f#V5bbfYtnVfP!JGW(#ws@b8Tv?@#49GD|Gk9CsY_33H0oGkwfI zaClo>i^q$_r?BzN@rCxOg0Y&Q-Z?@nJ_ftd*@|;dR398+l$WMw!xSLu)hkNl>}T!u6VqSPAMg=K$@K zG|lbvxpN3v=u5z-#geK%cMjD)>!=KzPGO@MSvZ})XdFt)m7J4xtSFk}*^;V!ozrxz zD>NratQxT7rco!B+Rk|vkId|+Xcb1io2u$MS7=LS+K45Vda(TY*6kChE#9i=3bFVZ z5oF=<^9?KsD#E#j((zU||8V<6IyY#`+YqI$P+QY{=-jBwT!xM~wxp_P=XUMWFx{u2 zw$NFL&S&EDt#gkq;j45@3s@G=hvCJiH7wmC+_5^rQiYB|@#zN3+8DQ`4=giQx-CCw z3mxw?V{@#+Mt@jV(&%MNni}BTtIP9*)Tf9{XI^raq zo$%?m(e1O#`CO;dhDNWXd<>T5X>QADZSht=XOX%WHqOEFj>aL!N>JyWg*><~a;N8Y z(dk1Lr7F>Ak(4hwgS4d_%|Bwf3Cr;G-nkEpS9&d;!m=aX@6T1n;iF(>dhS`ZkGERCNn#x~yx2mct|MBkFj*StlwYK`VGgqk zS-jP6G?Q?>3LAM~3GCyxd}j8iyu4MmR${5?$ZHPJv6_x``{Xr~w51M>=i`f%s_V#a z-qLyXc%{@#nm1Bae)EC$dHt7I64d8xp%PZ4@xwmvjUwh_9cvk_w%Fop6gS^!%Yxn}4@$Kvk+N?v=|LMhit_t|g8k%i7gWEP*J+M?7JTBS%W zj+#w%I(gGu^%Plnv|ROf`eRHt(8IsVfthFD6#vVx8jv6O+OS~s_)JS+v$ z(<$r0>3FNzG;eUM1XWR6l)9WAtFA{iomcBbcRIn^;;j}hb;oK2pJwOXKJ7fd*0IK< zTe@qDw<>$r9V-z&!8FrKnMZj<>sTYwa~}uGvh;K&yDj(Jv8KaPWujPojaAx0^`bR^ z)N7STyo=Ygr?$H-YdxB4%ecyJ%T^D1zCe9(D?P7W9)n!mr#;X+32HAak5b&RZh6oH zL-ILHXIIWEQN8dOtW*A)=3dGDjmHq(&OPZGL@ZvO>$Q*C>$c?Z+^T&RUvpdXc%Ich z>(9C^pLt%vk#zEUX3xaAC(x`VmZF}eGVzG2LGuq=QdLFI(wVsKkJIa39hPN1)lbq&wCMwvbQ3QesI|`#rB{ONR<> z%VDz6C5PI;jZOc2jnlBCR1+VzT-QGHZ9ccNI4Naoz4#=k)1LRUSY+u)XAu6Epsstq z(j}~m@+7L8o?cnG%uUjBe*#NHZiz*sjw}xHsku)qJB&AMp?ckh#c=%NnOCP%Vvjr4 zKc4xsaxb5qB9;X8*0W&NUkQSGh=o?So+Y#L(~P``m7xChEUjaWZ0?TrpJ%zOSty;o zbS~w8iRv9$xL$ld<$nq4qh|$e`GM{L@V}Z4hpVD4VSIYs9jw8N4zU1hskXXV#HhGiE^B7Kggeb&rI4pp?Q-NLQ9xP;r1-_?=Y zP^pp2#X@UrvT&@F^pW5LpYJ!geSEc#ww9ktLgvQ`IjdJ_%}(tE;y3LyIM-^{#GY$)Vc8Cs7@AeNR28)Od`; zRCUJHQ(KC`Cskd9g+6Dl|D~!cWZ@Cj6h}8bYtla6>MGr<=YMo1?i#4uIol4gB&uhw zBwgmx>6YhYDWRs&>>TM=LKPUUR4nOXIwv>q%b{Xur7|aH4poxQ%X4zZCmpBrLl&?2 zB;#Ara@9pof$xH^HWmA%nxaXKMaO?7+64Z|@NWVCyzu`Le65D~k7*(r2L1wk6Y1rE z{}F`OLHH+xPey*5kY5v&r!&HPA%1D({}22#Bm6%6SAye_ejayz2#-W~0Mh%2@LTYo z4_*Xr3+{>dLlFNHcsIDtw^IN1DF0gU0dQaNEbza`e>v)t0${~Z}m|I)bo)-N_`%>;TIjm8(hLdxST zM|t5U6-AGOOH>k`7)w9m=Vz!l)9Kz5>C~&V@*~|ycWCG2^i}5%(!FhZZ7tI=rF#1L zs9$Ktd`_p{nn9etq3TDlovyj*3ZXBBcc!yRKhi--N}Z<3X(E-2H91+-Z5Ka74Mutu zt4g{#Hj6$!D(POK_=%K0|6JM}`q|j%2ApqfQd`nFIb)MXjuh>z)mK%cpSw)<^HrU_ zMGHWW(32LnkMt6q2DPAb=;wGj{26pI{j@mqByc9A+nzpc%=RS+uY&M*NGA*O>p*2? zzb_C@FP>>Gh4|aRE8#yMd=Tm0ao2-R3!Khbq_YzBC=a_g@~w|}uMz$f;ro$pKjgCt z>8?Y({NQ}>Ym0nd!S3a*AG93OnTGVIBELbXR}{j>pgdQg-gE}wdTd0zen>wCS`GO- z;NKJJ6+pb($p1IkcY*sMy(`fAus1?_E1@lr&q(+gNVf#SKf(S4+!yKWLcGJM*JyA@ zwBP55w;P&<_9%pM_JZG2#E(P$>cD;x`Td0OdPrwK!i&Q{7UdZN|3?Tv2LHN<|0U}6 z2=SI8-Z_-32;$uVw}an$s29>(0KXitPeXmyBE2BALw%HIJoFRF5rz0Q5x)`QZ$)@D zus1XaY9Rk!NN*v^xennYkpDcSa}MQL3~h|~*APA(=|n)AqFg^Ay({3-i2o7x7KmRC z;WH7wM5k}4S@aB-=c6m*dH(V6NTB(2PR>S2EuPUT&aY8Y+r6SCpNm$3Jrs5?*uRFo z5$pwFubx-Zn^0VI2(1G-{dV96w322nnO~IlDQb?QRUO-#LEF%pj(KcB(F)+D<%D<8 zN|D2(VLt+{T|(@CfKTKTo)2z<@EnMj8ReLTay%&}{(sWCiqp>m|6{1vAaFtG6!@yGl2&m`$J%p%$q@xRX|ybAVy;5{hEDQI|R@iV+cDQH}_<7ebs1LdUOJk#lI$}Sp@@XfHNfR`b>4BE3B+WRfq z;RMD(E%bLo=zOG80{u}B<<1MG7f^Nn1yRp4sCQx1w?a+{F94-a0BHXc2;YSMs{@@0 zos06UfNq6OfX2a(ew0S1mxlCiKwm=X{;du#0l&de7wR()?XnGi^u-VD-wpa4^*{KT z*ze)E4ap;?6-V!eo?MB_N^IM1V&x4MF&PDl8Kz&iJiO@~Z zThMpVoQPidI>!IsVEXxFUA`MQ?%HC0IE~|F4|Foddu@!* zYv}iB$Zr_(X$b%0uz!K^KLPE!5c$?cKC>_nZA1I#L3y%ce1##uBM7gKew~AKe}e`h z-?nIn#qRkD{r{u38)|4(Sy$%|6s6|?Y80)_3DSVs3PIiG@6_}OMQC>_U$6MoQfe-ht97bUi-^Df#Ql^}j_2!?T1xrx&H`4xTfLOheLP?C zX?94iSAM0P8GL;b6}@Pz0~Y8MXg@e;a)H6uOF z?+}GAru@k!nE`87UivR-e*Ck@c+WAmpc*Q2=Y{vN-Y98Hxc&>a@O)5Y8 z|IhQWuezkiqoH=vd7jV9PXj4`x}P^uuXB7=BdX7!EWTk**~>>twR?IwI2q_K!{a+!XcnWc5+8v<`_Rzs^sTdP@3kyy%nT zq78>D^@8kwptDDAWzx;`(Di`b-wdi>;2esmmuN#)P3)61b!cS`@c9`U*^V;uANFI%rs zQg5mk>!)8tM@?fjRA4S?&(EkHm5BR{q_6dmepi>%Gt>vH<2GTOo}uH5*N?+#{ITX( zAX;mT=naJDdM`YRj@MdL&J|SOZ|Y@~i`R{ns6377c?)Z{Na3N>AIw2C-dK4($>o|& z>*WAa`dvj`u8?DLKl%(k4dimjc*saUC57H%qWG<$A0n7D!ns|dD7+ix&w3z=IU{@+ z^;1eA*0EKtsd}$u(X0w0ouT(Fx z^Y~=-tu4Ba?&~u@|3)~8=J8&(cswuuK;g3+ingSF`@t68l+qnY;p<0<7Nfpl&J8UD zeL0K6Gup?$w^B*uH+nd0hW$TEXE@nIsxoIC1)za+ zeq(!GD80j{xv>(Z=|=Me*lGA`egLImsJSSVzFeTWZ8p*7;C|3<$agFBTj=l5`p{|6 zb13%!)Z;dI40r)J9$XgjhPu;(eG>c>9dBIU7c}3p9vde5miFH;|BCQ6&=0WBsW0Jw zQU9=C59&wOIiaEntwsGWi5}}NIt+f@!iAec$06P_=m7W?`BnU$(=)6wwtnXE*pkkh zJRVv7>9}NFP5sY0oyH;SN;>{o`_s5)9S8d&ZU3L+Vgi+)#|0~o3sxQ%6X^JwM#oVD z+dTR3j#85;d_UETwPTp*@>Zg&C_lC@gieEwhHixNxMsg9l<#C){p#*jY6jUy(>%h; z>9g*s!PI%cQnXOus4 z?ikUHux}VE?8wZTkuR^?R*?VSPemU&^3=Qym<`9Gg`32A}^k;`6%n z8pUfy?ZBFY`j54=Rv&e!5wBAW)jf%y^ZKZ7XuWWo%JELG#|-5@f693^Bi$HkhX<6- zbGjeJx`onvKsSkhqVw!iirrYmmms$Dv`?sEtnnUqE zQvCTeo_O8(_JwH5Y*9~YN4A%w@a9x*2aPw@KemciCcoykanHw@vwowbiZl*cKTtlb z-(?ZKNXIwxb?80lOj`G_y%miU)>t|&SbwGQ%6f+Sm9<(X(VyX;kWKgq(w_jnyk6|3 zH;8u1Eb8SYTC=a{%&wvzx`<{6e*vux{TWkIt+Rnx*K{Lx-Lla z-v_+{J(xx8q2Z$Ry*}LzgP`&Ue1TUqgMN`JrukNq8=31oY%>v7d+j13d&S z0>ARm9KPc311$}W^$@!U{Axifqx?&+=HGg|MmHvL+3 z7xW;)&p{_a6QFnDcLecsgTI2#gOE1#-`h_!{AAJ}}>tOf|EGFC$T5-5=L%MF_ z^6f@_)}tO@BK|sz$MdN7X7~8>mUvxqh|=M&)9HwEG=VOI&OklZK>vfbL-~$CpF^`C z-j~pCpo4Whx=sz{{0!yWNv>1*_t^P3pQw+2ANBsQtmoa~?C+|dF&|lbm}xyi$2n`2 zmZB?Zeqnw<%i3Bp;TM0q}OQ8^#dx`fMjh3-4B za(S}Z%ERZKY!v_YJW)O$F+YDQ%<0(uBTmv=sT7_Q`f<5%L_^k$>l&GlGwSUizq}NW z_rkL-rFLV@4{do$xFMCF?YpR6to(jGEAP%{OqO$M(4wTZh_91=Lpm1ef4sow z3%c*Wo37u;o|)3&>&lH}=Y2z&Udnhl&_U9@4IO3heGEf2ZzKK}>xq7Tj;`Y+_DGPEh>{)%Q{EeAhRS^aH59xj&~vGeh?^lYS_JbU(y%x;|zk3n ze9w%zJiB{^Ini(YltkbaT;vTZ#6#FPf9uhr?@A z`?KbqCi-Ea=n7hQvAqiX{(U9(n!kz8=`7m2i|BtjMQ1J%oew|XrNTv_PY^!jk=Qpa z68#u1dh)#J0p!1m)^l8r@d;wD1I-8BaZ2nXkY7vK3%wTmMU?x%XknkKqH$=S7s%(p zL$P}z{tfuM9*ey&^f}6X6#2d1F5xLVMJvFb+F7_g`YRH;6!stCcY)?@u3rP_pU`s9 zg3#ZGNqQ^Gil(8R7GYeL$2gn@U4n615##cAv~#0>B!1pQqT>#TK0?3uLVjbx#WB9Z zptBIZ2kMLQ^BDb~d5)wP3GIRQ`fa}0FM>Csy_Z)L`*MuiM;NDV?u&gM!e56A7sYr^ zL_fXh3qOp5DA>zD>!Y7*qWvpDk6~PWw?g9Ycqw}9C(+hpMDKMMtq!{nv>U=#fu}&d z$BO?@sBaG8oo__{Lc7j{mO{T2f*ygr^lR~di1F(QJ`S!LDdDGXh*rV)Y=(XqR8H&_ zvx`2>CVC8781`(?E3m(ZHi!M~Xo1f2-|D_rb9 zK~wJur*;t?25nGHcq5L>mLr5ck%zZ^{S3|re0|RK&zmOtYirTd=-0704(`%1Fm=n&EB(EiY(*TlY}k!bQQ z(UK!Y$D`gG;^6mIw6sI&H4yVn)_Ac$r}HP*Yc8$hSYOgQf%RH<(SEx{JuZuO1Q)~n zP!rl2x@)%hErVW#CLw(G7Nq+?v;^wwu~c|5!k=Q?%$g#0zHi6n;`?~*ZR>;(T90%g zdmMBj`FEl9&T1MTJxHI87hN4DItBI%;Qdr@_M5#-!UudO+8KI%nDFlrqGd0Ow*Q%x zzC=UgYEYJp^~cJAbiahk^Th!Ag_%#NL@>k(Fy$*(GD6|~34YenS z@1Xj!&gmrjCzS7#v;7v>wN^M+Lsnl^l*%)hv>(}7uh6(1{C{Y-*>qf{P&)mft2YZD zI4pXZ#w&*(fhI2&=5LX(ouBij*xHTnw~ZouWDC*Fl|(Di@y_-D*e6sGZbbECyD#0} zVqLLKces#r<7??w9KR?!(WZkQKAOOYS*Ga3i1R*LAo zp`t&7t>2jcpW}-2`eHA1BOwoJ_OD zHyIgQoe3W zB<1V4iu9bC!{<`_us!LS=yB>t=7{H_EoO`Mpz+T3PE>x5S7^TQ|Gd9os9RAIzWyGU z%TV_Wxt}iaGWv_}r!J=Y<)(IBT%W!&MeRlXqL$OR;ODi!(0s-EoYspRUaLIK52lA2 zT2Zuc1qts%{lI?J#)~Gs(CVF;j;Cc5Z-FWHE-uj`nMHrdD!QNAo8v#sE_&2UG{Rdn zk>(8!r)gR1Iftmr65WV&XCmE^NVf~pi%%B6qEvoPrwf&z_5b7gDqhd8qWb>7<+odp z2M^`HFeCp^@;{Nt&%@;x%=nrv6V;D(7quJfPgFnFdQ?BwLDUYcN8tAnekbGPM`Sy9B>2@Vf@T((o(jA%36WcMX2@8ikG@3BPaPSB%aFoUTdd1J+S=pM%He zrBnL3uJ>wxK2Q0mpXh!A?|*pHjr?d_cBgvtbL^)xm0CylXZ}1Zyg>WY{f@jG&rrX% zllvsE+KUFP5jB1n{e#lu`zD-k3Z*-T?419Yzv&BF#9J=0dU(&)>3VoC(&>7rS(GmA z=TVO+UDnE!F6+~!qKhb9=ApVi9*WQ3JZ`Rj5Ur6U`olW$D@OAV`KP~!!TV>@==kFO zGpxLShL!ivu=4&H)(jR+QhiXa8leFM#qJ_H2)GbE@!uq)*=%(%~Oy zys+O`>OaBGK$PF}VdnRI zSou94R(=nNwL=NfZM5ECo&e2JNSNOTV*9t6eUSy?J=D!3qK|3(u>B#l(f6F5hkB7DI{lgG z$E~7I<-Di{%oZMl@aG7>hVU*3FH8N(=`}<-yv_+rRQjru7Kh>(O{&bdv( z=sqj8N3Z9iM?Z>&QarYgJtO{YKZ$;%az7>e06Gqy(tYr2`guca(h!Qr=LPrk+e4k0 z4Rw>+CA7YeI`u)qCzBt~f0gt;eIM1guH2u_vWxd``KZ>E-yI6iPV4@nbUyudH>;0w z1<`$NvgZnrdWE5X8d3SVo*SwBtOF=Mw`XH2FY79_dpKP;aQG%YUOm)lXhF)K?f<+M z9Yo`U>pgXW=;eW;3u*nt_PyX<2=560VBKCmYQ}A9m-;1C0*$Zd^lj7DblmZIb6_Mh zJ-7Rk^C_X)KNkI*`h}Ul$;Qvm*Nhfz`cCxie9@@QtcI#Z{r#HSf%P5K@E7*<_tEw& zq=oeOple>}(pkK}E;cEtpwx3J+N&DcZ#rGqa67zMCOQ)1_!F&*x!%L6KUf#g{T0^U zRDRavrJ}u{p>#dW_U^PU=KY=r+R+!d{hew9)$ggFQ!S!8u>Jup`?J*V>H$`n*Phb; zn4C0!<@RrsG>GQG-2NVF-4Gdfna4}{TAR7vQzje)%chQrHdD=N#;nkj_BZ zE6{Pl{%;UIo#q+le<(}+_#@)Sf-@mr z3uq_k@Y0gbKG|s=5_UJ?9WSkf3dhZ295?lF+^oX!auAvW$IW9LH?^-TRgC(X`-%5|tfGF;;^kCPw3cL@ z+FiHN#>liv7SO?NP%es1{=)PWBy-Rk`=V5jGlGtxdk^GBOK74${VZ8Lmda^6# z-^F1P9`IH)vp%jp)GO*Iju(k`%SQddTo>&>SK2>)e4VFpRf@(@FBuv_8Sz=`T!bNT=)`rYdPUQ@c*NbaO*On`w>1E;m>GX@%x~sv}WX2hQ?!MTmA!S z{`!jYok{7j9?U7a5Soq3!S>n|k2N2q$NCiU;_?fp!M`W$Q^55RzLVCcU(q;Ufb(na zZPIT4z7QQYo7Jgu4i(+JTjr68@uG!jJo9`SluK0B|1|G3;C^+gIt@h)=mcmBJ$`8Y z9x3rMRS~_CDtZh$vb~JwKG1(?{BVBvp#T3Y7wxI1@y+WUzHY8V?aRk&J<@8O={YxP zMQCYgSTwa0*?;qsd1ax$zF(=H+z{?e=RKNl^!Vj@J3sYb9qR8HG!9r_(0F9sOXH04 zOZQt&<1mWsUCBSnX6NU&p=2*X#{p|g3TOR~=26y%(7#~+iq@-ax9B)wZ35ju`7u9+ zUlNU1=F^DZo5m+|0JIpDGnCGo7e?`T@=>vAv`?Dq{bLaAi-yMf#S~HWZ$!Q=hv_rP z^j~8ex2CgjPa7YjnQw@VIefg0^HBUb%*G_;n@D#%i5G)26L+B5G)?=bs_B!NE%hIG zGKF7pda8mx9Dk~-(iNq?_jjps;Ow-TX0FRjUqb45N5TU%Pg282@OP+OD#^ypvt?2X z!PW26-8+><9k%fTl}-I;vq^_fbs@eY+=t+w$YRao7# z@mcyVd7ffAJ=g6Ww0qnCOH~a#i$?8_#Pz@}ZwN<%3(>60;Z49f4+^&j=cUok;l04+ z{e%<2uWJjB23Nf&%wH3r`ngQ-eDIr@68;Cc%Xs09U?-goIKMsM8sHP)g5WFQQHR9; zK6oY7pX0v<-`XQ=&{4(ZIo?W`XItjObQH6HesFHO3S<5foXbzbeZk)Kh3kTk|0f&@ zu8j6>2tJ7PT7$>X_~P`x2k$}o`-A6!hlB5|lk`);`R@wP0eAmhcqw>#Z{c-dXLI2l z;A<$)5pdKr3BLdyhyJ(?&Q?dlpM$^0c=!O`)e@jX440vBdVZQso;fZuL%H??so&!Nq9Bzb6Tx%{CeP;6@??gOAKNDnh2Ng?Ox&b zVC5&=3p{7La3c5&tu8oy{+b8J&x-IV;E~|@;4a`lz)ul>BX}El4>%J3C%_fJSHL?) zO8)o3#WPF$z6L+2CgBFHrnr2orVD2S|Bm+04^DO;|KPi`#NQYEBve?wwK&Oj0LNb_ z!k^ud@P^0q+D~0NCwc&1X)z7^^U=K&9VCF}#9 znIv2u{QRD9O>mS$I1t>bi*PLX5ZeDc@S?F2-Wi;=lW+n!4CP4%|F>Sk$AMd&6P^KX zO;_n$zhA){{Um&?=G1&UY5g*g!p{q<2}6ael;--Ux|Wuw-{7L~w%|{6yfIG(SB|B- z^u+gs)mv(h(Zsx}Zr!`&Ut)+ju2$w6Lo& z9dGOWtEyI-_o_Q1=&3Bdk~{_Bqp#A_4F76s4&t|*uheehi#9&$UtPVl@j2q`)NY(V z`(O9}N)-n$`Aexs{xwx6a8`rfRPe8@ZrS*g|JSNr1&VHrQ2dsT72v1%t4412R`t|- zW|gdZ(fQq*KK<92`knJ*|I7jYD$T~;0fDL#^_x39Z$Pk`%uMMwpz`?ygs3ybE=n(} z&M#Em13#qn`InA6`HKIHo)k@mtDl)wGS=7OYNqBC&5yjo)l$vUzw~<%YORfH(JzX4 zR_6E;o|r9K<*;$tfEZOobE^7r2K{zkK%DAl3omIjP@`;IH=vO^ZR5azCMqjk4Z72h zp)CN^<>}lcptWjj8WaUlu|zg zbWs6Sb^7Y?W~Ihv>ZTglI5D7`S_^(p@yBNRUflvWrTJ!9!1pSN&Kul6S!sPt`&86v z8&3%6p&nJ2aEp$&sR2FJdmH~6&_`AJO2YF|`1*h!Rbz1WX-aJi=%@JWmz;ii;=KU_ zR7efsE^FyGOpQd<6U^l~7BGY^I&`@1&x--cYO-ec@tdON*}@H#qL%#Mc$MZ9*Dl&s z+?K*OfX@==A>JYW>bo?q?=bb$#*e&)sgL5X^S===Tve^b<+)?X`1?tX);z*x9#!gP zz)xzjuuktS@oCM;>iT4QD=1*BYEV0)K86~nh6%g6?NDl{_c%2cJeb%F9H&g02kA&x z3uwNjt3g#&^9VJx7u`(=9Iu+%I8We2)lYM>DzcOA`UU>14r_LocZ#}<@GKNwI&g~0 zN9PGXehtd+^T4T!-|AovT~E8<=@tJ+;Ah`4&sKH(Bs`Y_z(uNE zec?R0xV%f%V{nzt!bRx3%;|Ic<)QH9nn$Rgs6K}JU4Ma|&J@a@(vJ%KUEjT@k>+~; z58d?-T&9W#aQvyRqXUJjfv5Bl4gx38al-!Jf;ZBk!rTeGwTEzj@ORCG$AHfz3eN)f znkc*+yn*H?PH!uCE6Q^e?DIszuY&(wC;SZjI84|Gl=@5>B%Bl6huVYFF9yB{t_m(a zMZyEYNr>MF{Bx>=cLaAq{{6rm=1cf!a9+fp3GRXLW#EG0;=cvlhjx*0`Hq0kEs*fP z!8Ilb^H&zQzuKceRFLp5@XrB$g7z;8UP0rA)2{*^O2-j%0Qf1*7t9U8wUJ&2@N@JB z-;Lq?qfp*aU_Tmv9DfG568h_R@DjA&X7FLO&tY&9(&M+vIQ?D-e*)fx@$w107~|7B zSo|FeC4V3A?n=Uy!QLB${lR+?zX5nTrOV}S4}OR7^aHpQ$~O{R9PKk5ypztS9Dga8 zev3o%Ch#uQ{}6aQ+W#_m1I-T{|1tPSx_)5(2(Ezs_X?5vc1;uiBH&x2gnhxcQNH@% zoWDtUJa|6Zw;i|&#(x5M5XS2W@KV%o8u%sBUjiPB_Spzthx#4_f5iB@1a67=kHD8v zo)6$wNH06h3p^hD5dH=DB+66C&7Guv^}wT$KL17t#}CH%XbWzFkU(&HJ&^KkI~ z&XV3#a6Iz=4ZO9!g!8<`@fWuhJ^+qD{ujYc#D56hf$;a>I2=FOXxwpnD=F`!1I7HsHT7-ur;-@zY-#U&Fv(Mu`6uaQ?x<{8WX@GZ^i)9()t? z%YJZol$Uqqvj0M~&jWBK%y)cTargk#KP%apE1>*^!LyNG1+cY6%JU8Q=}_Sq@IoAK zt-*6K{(6HS%@h9=a2vGeWbiEX->=}7$e(x3bNPzW`kvcsAGkQ;p9eb;ejj`bHcGmSp{R@F}PnYz|gFSqOzXrG4FB}a{L;kJ6H!(l=0{h|k84BiKjp6c70{@Bp z`7Hr1Pi3UH4qO7q|6cH`pC$iu;Pq&)d*IJ8zy1p@g8s}LDd~TP^FcxI^*fSYIq**y zpLM})noD>T_!pF)zZ$~j&57f=r{+|ZWek1ipX#?n7}wW-sITJLU#>?=8h@x@Vb@5y zKJTbjs%UU3u|?b%EZ3*2R4cGtpRQ8fH1Ab^Us5XA`KMa0d8+F;U7xlKT&?(*r?`BV zHLq2?+nHA8>QNM5@6sU9|Mpr_s`B+h2KOK~DEylCPjU4*D&hAuC%Z-vKl1uZz0y3w zRdfq|oh5L+D%XG$9N{WU+?%)txYKcZo)Ne~wF0k*ruzrPBfvX}hZCoPAT9)^|ND>3IWGd6z&P;`w=q&H|e(|xjZ4nbBVJylK86%@b$uGRTVrG z+#EcU`g@#XvlU`i1tA) z+NUbfyiVm+9PSl#K-IGGXF&&54;vQ=I;{HJxMa`~wZg`}LC4ev8`q#$Umx1Ie$Ywv zd2`9{2c6$(6>sArL1)w`8}|-8t2TqHYX5WUnT>k~o>#@_x{AxsZ>bpSf~pM;ATDTJ zPz`Nd(zv90fnTx~Z~KI-EbJS32;n zin4L{pnIy7jeiJwq!xfr&*kzyR-3?S^LTtbR=aJS81zKtX({RR*SHEA&r}f`j|_UD zYJ*efaQJH#WaE)R|ESjBoOAj3`cHMW@x-8aY805?ZkitSK^?d8uR*5q*2aGZxs3X) zq&)1uEy&C03GTO(cHai&GPcH{85mP(H#68>8GF)MzW1F1(z~5**JG_ zdE*s0+Zm<42(E0jY9r|}mkF+F90c=QTh)TA8&7SVDY%AFiq2cyKOFuksIC!d8{jr#?6Hs0GfEV#STsbfa`5y3r; z(>DG&xQ`J)>twD!zm@h)a6e;}jpqdqFbZ|f2oDP$Y>cw;%HSm9C79o$n-DO}$k|2w zzo35E7ChYe%EtSHM;bkCd@6XXF~!DLg2x-j!T+6B>R#|9qfS>zkNIWr6k{=%-_H9O zJk3~Z<4hqlj4!&0KZoZHnQfG_anX=pjA`Ht)Zg2J=NnsWygzuM@!H0xf|nQtzL)ga z|4Q)hMm*S``nOWZN+Zd}bwbt{`)wQ=vdPHZUE=fGe;^_VYvZ{g zH;jQcUKMiJ7;EEgArB4jUXtD)Bj|o%$TMS$jc}epp6@b=5oxl zaf{GAj;A*66k5RHO2|mBQ$Qg{yp4N>e&Oh6;{l;Qj(y;Yb?Db~LQ6RQwsSx!$9)_3 z3N7nUKS=uQKOnTcBP)0*aj($Ij^<#l&#=&{j(av9A6nhf_s5L#O%JW%xMt&DL+d&s z`elT#4z2IFY~!@hAV;_U8R17m!yG;XGWbepl%ukZpN7Ue=oT^k8=<&7W>^!)X9F|1 zKv*kB2^*IVYv=gN#nna z!gB|2cRaLlmhjyUZ#oXSyzCzqyw5QJTy!D*;&J!^$6OnK8GhKY#>SPxPdF}uSJQdM zFZ_(-fsG@>&pY1QxLNpRhbu|)WB*R!R~?_(_=oVDjuJLb3BTj0YU9-K2aW(6{}TS# z5ohD&;m;jyY`iJ_m7|Z14}`yUq}cde_&Z0cjqikia{OxJx8bI9y^XU(WOg31ap4Fr z=M@`Qipb-9ZsYn91)R=gMgK-9u5ZJLBF?-v?ilfML66m*6BTr(|12lh;tUv?7p8L=X|T#{k$UHS!y`@C#$n`9x+tBvyA2x z*Ph+9ULdXvK2Q8MTfDQ5W;)+2q-c>1ocn2B=l<|KL|>JSZ0dXm=Hn+*a5HCBI*)L8 z(QA4=;+$vWu;4b%taM$$;rzCH-pF>&c3^%B-Y2qya|`&&V)_bDWGCk%8&{3&>MSr? z;-9EZkJ=)?cZPs@e0&|*!#U5!(UEx)QoaMY_<9m?{oPOgn{69u6b)L6zo~TvMp5rAv zbv?KLdgmg|$%?sL)OzRP2^rxvqc%Csi5XlkYO}MBuU5;kf^D$eE^juR1@Ap4WRGa-Ie!{Kb64S&ohazCUt_!grg;oQ=W#DBN>u`gk_fIcI>4qlj;5zHY3mOwYsA1!s+^ zoc>hx1&zO{QJ0(nHl7`I*|`kdbtdh1i2B>P*2c@Ct~$4Ab|1gjoyRr1kJsx?HBFaa z_m{W2?)282ssibL)7q#T&JYQAty`+pGv`fbKX3}2H->uObn@GCRDahy8kZf_P3Kzh zx6g$ygO9G^`zJS@=5+C&4lV}{J}>?az+U&2+89OYga5dz)OO;v;0U_Ev4^__du<73YUx<5kP6Fi*y?|jrPXH`-TAKHn2{W|KlvmJN_>D{Qi&RgJ3TjmQ&rk#em?)uxz@%XqaHcWfS*wLt>`Dt>)?6! zn4dZyYfe!m8u5Jl%$a+R&d+s_($5HQ#GaRx@dQoQf`IPX2@AyXUv^=4{RG@{~6>fu%eZ z%|~D>)06&tQ?Tixd5qUba(o1vwZXDqB-o75>|QSgo6j`6=id;s z$Xbps^XE86h#3R6#!;yi8k+nYY^8Zj#w}8`@iJ*JjNUZ z9z~p-BgRYvUw%W^$1$bc+MCnC zd58_-SDKU60OGNkI+(?`i2uKBm1-N)!HfZWwo|Gz@qW$8YCiQV-SIbFTg89W6Yh_W zW)1K(;^Z71%|YN~^6web$yD3KKb1Ivcnf$YJ&)@d)7f-wm+Nzl`i+KxNlQ@|;AWh;=rG6Y3)79(;{*5@9_>5-R-!m$vn|TM!`+J!G0rUPI zX4eiy|E9Wle-CqhFz@eSE(7NMJYIf4`M|uthr>&Q zd4CUcEpUhV!r@@v-^1a}!MwkR`Fk+$?_nMc=KVd)6TrN`hj|{D_xCXW3FiGh%saun zzlZr0nD_TE-vaag9_H6z-rvLQu}kX9`+J!4f_Z-rb15+I?_sV9=KVd)VPM|h!`uwa z`+JzXfq8!qb0V1c_b`tK^Zp*@xnSPk!@LU2`+JyofO&rp^GPu8?_s_P=KVd)ufV*& zhuPXK_2vCN%%6dIe-Cp>Fz-WPt^wx#J$oU%0uGggf_2eR+Qmhvx?K{vPHp!MwkRxjHxs$8#{4_xEskV=(XU zVeSm({XNVBz`VbQ`6n>%?_r(|b|U^CVBX)u;oHExzlZr4cm>ACH8Ah*;qd2R-rvLQ z*eCVn{XNXNz`VbQxj2~j_b^uj^Zp)YdZbJLrn-245A(NR-rvLA3C#O@nEQiye-HB* zaCek<7MS<qo9~WseE0Q9cQf;G zX7}|?4>Pxor^oa#i`aN>Oiwey#=ph%HYaFy-_Pk|&eQC^zUX7RPH_6}>yf@@faVdd zkLT%EPGb6+J;B*8(DQTR*}`h#NxFWGNiYv1oY(K0V}3B-gL(bFgE)Zvcs=`8hyQ5y z1!w+;!+$ilfY;Gi6!ypTGw*@-5+5b5bV|opU9Kv1CZ@l+2;74Ba?C*Ut*~p)aHVd> z3^I$Kmi$f<-zV;-d8#Y=HQkSjNi-*e*H;zZBL3>wTBY7l_&s6Q)-Zbh5;MficSh1H zO7llYHN*_joT4Uv5azF3WbD5mV$Rd-em`f3d0g{UwYwudpNbt~_B+e|scH!IbC%d- zbA#rou0`+YeogF9^B#C7INv$;pX%~?FX18Jy9nC3}_@&9?f4Er*yj{=N!_7M2&%hzzO)n&V18}fDeukT^z`18gcsKA(q~8zh@w0>v z1HVWWo(TT!nec4z2JjMaR=Td?@~#CRLw(Y~AHavf&FOwN`=19dNBM7oDlu1HAiM^6raqqxHv_=+QJ)y_QIxMa*bnhL zfvdv5FSs?@KMB0KljJ`Z9EteTh1D~f2P?-8H%njU^10u?8DUn_oZ>3Igs)dem~}NL zyJ`_X@)}`=Xm-zUBh8*RE)q1-oNi;UpiyR;jeUbgo9YVZC-G~?jxpv=5%mBy5GdS3e3M&S0reHdC10IK@-h8HueolHS^QFM)gtb-#hSUGXl)N za#tj1lG)M5UO|)1p*HpnnqscAaqqyX<~?x2evUuQbY7G6nZ1Iho1fd*H)w_#YvbO5 zGtFUO{#CsqL9@)cHuegdZEmu$Z_pg`v5k8N{$dunuIS$g#lOZ^BxtV5U-fabSI|7O zk&S(W=9{B!+&gfAxdqJk^9mXZ&9gQxY5ZzF1Mi>5_j`Ubi{Fs+`F?L`>=Lsb*!x$y z{}Q{@Tm&T4nxY<8HBknl740xxVb*H+HSr(8k?^{xUn+_=liPW^WrO#%?x8*?44Znt9X4 z6JvLpFKrwbw8vDpGxD1ryVs1gafhJ&W-A+)4m@mjvGM%aBW99~m&KkmFN25Dakn=1 zw8`K7;QHKI#K-R$bG+uMs@hr4 zyZ4jdGDE=fe)BCe=OYeJQ4^@X-s+ZFNb?9)kLq(V_O>}sbFwn0P^n|@ni15FR3DX( z!s#2w=5Eb$ez+fd&-A8sJ(W+7hnKMr%&%;$;+~i-ZJa&srOEe6-TsB+{xvt)xOCh{ zv)$0%xGRKzNSiKh2ZWP=i(t zaUoWgPn=$|nn?4*Bd-uEw`TWxCDbZr<60`rs-;=dqxaLTFdH9?i?o_+PF7bby@PSl z)-_xB$+%dn1|0<%>y$VEu>iEC_edb8cS$9;fRE_RlP=9H(d$5*ODzLN#qcUlEIIXvKi9 z&~fo5u8}ne>_y|`P29KE60ncv#@12xw-F*X(|N z*xdTX#*e&OSQ`*u&UY=Xhnjce{pOZd5mVYro(HwEx`E|+P%G=OX7}@?*48J@?&m9Q ztS@LC&h4=wjo&Y7W0eK-^%(P4V7?w>_6PIz7;`k3ug931f%$rjxg(gb$C&$o`Ff0b z2$-*@n12HE^%nCqFkhcBF9h@T8S_doU(Ydb2J`h8^FARWM(VF+T+J zyvFoMkUz&;2M2lMq9hkpy^ z>oMlGV7?w>?g8fOG3J3_z8+&93FhlD=1E|_9%G&h=Ib%$<-+=U>_c1|t1iXMxE^b3 zg=&`Z+a#c^)xgFc@$IZFHuj3|VENH^ncU~2g7KZLT{dnQ+RZv{HU}Z{#GSnJRk0FH3X;4rrRw25N$@85&A0A=xa~L;I3>s-gYu@X6w3^p*qpd*_uGb^pYP2<6 z^Hlvkk=Xb#)&v_@2^eQB)a<^#o?u;)a90gF&$Wo3VBL^#b!i>%XPaO>(LBl3oz7=% z<5R8In%(AEQ~ zeyTNDGp!%?(E1^MnspNFSxTv_p3|*sn%(7{VHM(^3&8s8ZNLmGTC@9nGSg}y;g}z1 zS`&p`ZF}?mwprG6@b|L%bqM??ab(ml)@g8Nx(=BfKi9ep&PyB_HP^Zg{%J6;*XLP}!Ly0;5Wmsv zZtwY4LHb1kTF>hKe&jXZDrMt4UJI;In%(F7Mb;!6&y4@oT5jV7@xNL5yffN!Y5eb2 zB^#HGTy8D5bHGaL%N!a0iP`?ND%p5V{Aw%2##`gpTC+7v`J>c&s}y~KJLCFbqqRWu zRJC9+oh9QpTgx@4YCaOb)#{r|=jUqNlGk_Jt$AR%KG|+<0n7ft?be3e;xGFHw_B$* zyVsZ7EoUAMPf;PQczwU!Dx=vwezsdRHM`d%+pPv*-oJY$KF#9mG9K?c7AjRd=Wgq* z<`i|7=FRKzd#qBlZsqiu@5k@Ac7t!%ru)h92d!3goMf!04qFp7PgM`7elOw=TWdAT z`n#lY#9CE|{gc(`%CuiP{+Ly&u;jn468#!%gA>+J%_G#z&GbE_1}Cj~nv>NMn%|j= z_(=T8;GW>>J$SsGw46mb+`WD~X=T+c`{fd|owO)WCH-IQy?LC?)gSnO?)F|TGUi$; zvXrFkS&IrWB)i#X%-p$iXTdNkMWKv+U$P`5TS8hm468XJe=e*8& zzwaGm>C@-){r-NB-~2J>@jS0{Ugvd|_u1a(yf2$naV@NqibwDCu)8q4XkX={zxCWI zn9l3&^>nO^@@Z_^6Y!Pb=)Io4f{jiv@2?5`0%uv?`#dj_{I)mXep>WC&wS#CUlhEY z`1vmdZy@$l_}#?gTM79w8J^@9h|`w|xp_CY&vUc+>i4G&rZ(MSUT{i=u4ghoF{XBKKhDh)4d}8At=Ae(Jrmx zeVplilv{(u;cug75ww5!Ef;Mhmy7;uUkkUkg>xRO3-c!j)3i#}F#b`;chFucl+?6( z#J@ZM>&Iwa%Ov)}ydHi7SIZ_I2lK&s(O#`hbrHWj>=!MKE~X_D$G|?ryV1937l`Zj zL46V0y){Jm-isJp746e%6Zhv_T5Cj%^Y0DOw`u)|-+=ksSJAg?)ob$nvawLUd!x&1 z@th~KqzB=BQuLkLC6W)`kLNM((gxKM;hiv#N8Uml1LgB`^j%u9+FVZMcehrRGn}Vg z3jIU$-CA|x*Wt;$5Pgr1a=zE7J-+=g>CZ3A(Kdf1;<*S2%c zW1C<+bg=4LS{+PZv{x2WT^q_7&V&2lyJ;~swFSh>INz_WBgXZ7WK08X3un1M)KI&` zSw8O#wW9Z<{vk9zH`Eqz9?pUg-@zJb5p_{MoIMAe1w4`%?_b{*(@0xIjQ68&i+Mn+ zS5Jh;`PMy-2Q@!u`Fu6eCK8M1>mh9p=gDle#{qZwAJWcpp2U)%e8#tbSi7q}>YL1P zT~RTnsaBt}DBpWxnrR(5i~BG&W14Gyh*xce{vzg4tw{rnFZ170%i%oS=m+|m# zaF*rKQX9%ymPbpiazl(S@3%*3b%@1%_9*RP&T>8wrA2WT_7#tc(qe4F^_BWh(Cb#-9DzBwuZADA3JFKMSS+o>##o^(?Qc4p*?x*5ODFR&Kg`9=Jtv6 zrd_m-oQG3=cG2c=midp?whOs272=OIqqRN6hn~XmCt5o}@oS{P{jZp4E&2h}FWYmp zHh{BS??!7Egq)2J;C^0==6{ffXK}Fa(kmubdyaD+8^h)C+7Qm7zj3exZ5n4;{t4P^ zoaO#+g0_hBaK69LCniy=+8FiA{3L4eoTYt<+Q2Y=#l{|%sC^>XSaT51Lndh(h_?Vg z4ZM~3D|k=TyJNDpn|MF))4)Fnrv2xx+7%mnSXZq=6P|x#{{iSrpf2Chvk z^rvc#WO%MWRcppsl#hq`wT?p0(;FR=rUh+0B_>_lYzu#)c&4_8vs`~=X+<9r_UuWA zUx|y!(&`c4wHeQ=W@$mM&ae0r4Dmb1*yXssXT;l|*DSiYmR&xt1k z4+g$Kyuy$7mBwfln{j)L-fv<19-~DO4+Sm->?eM`72FSt9ji5JF2cVHd=K!@M>(^d zFy7>q7^h9KaaqTB?N8z(Ts~1VT8Qw-WgU~WK7x(T2VuSyJ6W66Qt0mvTo1TOE5Ty@ zJ4Fi+i}mjmZ5FXOFFjS;K`hqKQ#E&M9-r33)3kELVm&-ft7_wcQ7>uF5{vcl%i2&I zkBFM7y-FNWwhrd!Eo0x--m!&m8~ctH z(Z7f>jmV9wy1xI(ehV#Umg2__88~k z>=9rG`#^hvIHimO_BTGz#@cvb)Jp9*v3Q^Qk@mZdM?|gCZfVEuXI;Bud;CLv!MUaE3saC*v1p1HfZt0ZytsB*Rh{#K^s38yIE`0Ug(d5{jIW&Em{{FkBHi; z^&)QK!1>|V+DKx&4?8UOYi*B>$Hnf@s&)|iP9H@1POUHTMtoloyGt8nlaGu2M%ymf zC<5&v9aedlh@)@E_j$XusvS|EoPX@rx)F={$G6%OoaOlOt@f;7BMZ`-8vCu5M~v@r zhXIc!e&ZX)4!QSeFA}c+-Ud8VFmKPpV)tr`Y&E#F@bF0p}2l{`9amg;?~LhqX(@qQ5+>wT|KXsJ}d-#oM^7XAD+4UpUX8Y1 zu#vnA%lES8Oc3_tIkxwJs}hU;|8K25vFQK*)`oEw^}o%1MVmtMfpxI`F?|;CaNupg zui3(%DDKeT5^~<&$~v6-DjR(-A`eB8eo=hXFE6NP;N;JgyL-hvqSZ^k(dy$`Xt zpJeEBh>M;=xv6g_E(e@f!qhJjH*12=r&q6@B=olhE(ILNS>z9X2TD&Ba&GUM*dls& z8-Ed7Odnw5Z(}3$Z*B2U6fdbC70il%i02JT=|z(#_-kSJ( z;D>j491ri*4{#pNzJ~gD#@(sk z>gV=wE*f{Yo=n`dC)8)$J^EPU?dxE_AnrbWm5uL-tFE&&k)O4fa6MT=uTFgFvfy~Z zEd2#+FE#X`#KRxM@vw&e4simkk88%&&}#>TJ+B~8b_T*u8_0NQy=ikBV z>0jIACyLk8k8_6amhthUz8;^B`ZgNBH^=nr>)km|seYVs$ahCIomihs~ModS>#>BOR4IOTe5de+_Zpt~2 z9fSU5Qe2eIvV?pau_2gM$i@1J(kl}G(o1k7;!3*(cO>oz;}M3>CVrH75b@u=g?u{k zW*CohVx#oc#NxbGl)lx*sZp)wZKK-j&28K{s-xc4 z#uGbr(vxjGy;HQlkoZsv{EBv5tp0(G=foxG>ukIvE=k{I;}vnKdZTV4eT=_0E}%bV z<1gYe^k^IJip$coZTv%A4}A-9n{M#FE3TJ*+QvRdZ#|;B&_4y{Bg10*=()rg{#@MC z`eYk_=w1%(BL1o8G5#Wb ztc|cO@9EWZMfeL`|NHs?8+VESK;L5H zaj_rj<$7D;v*JI}bBI6lGdLf)N}of#1IGLQ@t^2dZ1Un!tMz(Mi1;WU691__nRqU= z|B6v-^bc(8bF9^O*|>Pr2K|DKKXh)?OFb#{m4)%Zi2p)wY~#kUU+Kv<7VoRo`yoak2aK3Qq}r38SHZh~KYA6ZanuyK?d0>0@m?KmJF3m5rCh|D;##BjRKD z&*D$%Q;0Xs!S}W2^uxq>zVq3Zf9NM|yfgj}{eq421~P;_~z0en9*s{Z$*EkH4(HV`E3c6}{LqLjSF+;eBU<)40{fWfI&*WgFj} zpc{>B+#sQdu|}{l^$Lz>5yo-iPx*Qw!YJ35>o+Fx^+klyT`=$eTPH*q&)c{|LJ8wV z3Xi`R^1B&nye60}&1dXw!)Gib#{KV@gp$TO;#GqgOHL?lY!}S+r?x0#oDod#({D5W zB!;fcw_tPmS2!NtW)vmf09*?AR?frOZ;*ak!tF*2A!lPQ z!u}!fP~ssmuzpM^XViI)>xXw2@cRSN<&7BP&OCfY<5|vfJiXHZW0;HfAA?TG8y$n7 zeGg2iO!AG6{=mZ$swjQ}cyhvh##pXTo)@iVOcCjsB7fD4mjpY6ebtN^#KOLs#w^Z5 z*o$D_jD*^Tzdzca$M${#`)LVvj1$E7HAlYR*fc=MJHq?>MG19{b_02S9ilwy89j(a zej9}4uaUAJ^Y?DTgNiYKA0{+WEb`aX7|8XB^7=fXnK4$d@zP$#wk9+;W)kDQkI#Wa z%M*S8ke9D0&s_;E6=Qn&39S^1^d2`>*wXtsp{=on^CY$)4$c!Kv@;*2ZA zd$>H#DE9)U5BKw-ezI7+QJHuYum`vq@kMx^vRH!g7_ny-$`g!C&TzgK^j%0uG#ysLlkluxaWMc{OtH76l*APcQdKVJ98k>kK0bc_Co^u|< z@0MJ7G{rCmVSeQN&u>IBRWGXGdbXv4Fyh^SBwt z{dv57()r5_qa(36f0-#N!<%~^imBgZ&1MCfbU6wg=o zHqH`@^OsK;lZT>Q*8fw+%rIWXS1%j~@%V-~Z}6N^j2PFe9`>Bk zfcSP;FO*8`Z=?{XX2N>O(cj1h`Wq97lOcQ-8(_RdoDJ*&o2Z=@cgN&bv{|uu2 zdB$(VMh4oSXI$be(;sZakFcjd*vR56(!V!xurXA~dHVM!4l~9Q-v#zG0$xtMr#hAg zoO>t!9@qoCfw*EVl#ejJBCZ1L0p7z|+B4FK8Hx7D_hTasKj&$zy~DvCNgQbmvT>Wl zF~%et$0Uw7mfJX(ILY|d#!n?qF>W1&`h~v1i7y%bI8S1?6m_ski8G8noHx>VG}Bl# z8pCg7qQ8H|h#o6g^!KkC%ZWw*JlAM34&}1F&NteIae|G1PMB|u6>J>YhVRc77#|bk zdC+vWz&J{b=Rr#WpCx{z2CnB{GyLOudd5^JPvkAcufqOAI(yAHPy8luDPYe85q?EJ z+~-VOXcQw}3p^XRH1W7R_?}VX>&9KgGlAa#u1;LKJ?uv%E;42iR{>rLynuLMZJeJi zHug*u=~Y?|-{VSLY(z~G+z@yJa0lYxK6w5Uml$!xc(3p0ge67}XW5^oVhG;-h?gU1oekTqX;j*X71{#8rVK*mC1E@mEkk>1>5@f%qVBDPYITJU!#o zXK=qX>3yRdv1>h?9|FFcSd{MvMh#+7z8@F~#9d*&QX*-k@g#8$=MRlB#PvCUWGo<`BPL(q~2=&cpe9%fZ$g6FAHISZ^#6a@x;XZ#ZU(^e3A* zUtMqbh->V`_OsroP232$angFDFY((?VEJz_W)pu5Tncz8v8dmT#&XU>jNN?v*l4UG zc^^oxY0^exH}MO=QNWjpCqsM6VxJqvEMeaqU=MId&Tzi_0Gu~W+GMa-guEDxr|E2y zQI5C)?=LnP_Y!{t^GlRJLY(49{hN#q#BCve$f?8!dHS1-Y~nLK{Y}Q(#A~^Hv$2x+ zYcAhxT;V*#NQVA-oZ|~apN;knF?s+;urG`V&clr;7=Ok&zBKM8j_2dim&QZHHTJ-- zV<&Af+7Q3?HJo1nj^jMUSkw&jv&BdyUJG0bIGe&RPJ;c`q_2$L#Q2^54B&;tO#&Ey ztML|bTi{Z_9}xHF^|j6Tlz0pu@3$G7IOiGJQ_%kH#`na7fFsy;;~a&r_dV=4C4FtU zU*+|~lA6N$1$d&3pH13f44T8`#)>b{o}I>I;wsR-vw&w2*8%nbALcCkzg>ng7vm3s zldtew;7PlT);1oQ^o`MvSkq9x+gNGikxAbg$2kvYx50Sxdy75B1shLD+GE7e6ZWHg zYSLa~sEuDq+GlL%Jc&Jd3*28z$~WGbkKre=CgtF~7VyLc$a(BIw6FJ2&Uq3$4E$lz z55^wiWl+9-AN|p|b)ks=oCAMf^hYE9brF9xl;_%{AB_c^hqJQK-o~0oj18QJuxKcM z%`dU^M&}1!FhyMc`7vKM;%GBmC1iMqF+OhX2zzMO*{86z~P&`Y@hm$6PenGM*np zCpL)1`thO>!C9P#a|p#eeY}rhmz3Mx5DOa2Mh? zNS;A_XrPeyw=3ky?cbRQDi~4Gi>@xe=_-Jv>oMYn%W|&)T{7ABC?zM5N;Wl2CT+^Ip<1drznu~0_C%KXNn~jerKWzSO<1@+4%%bmG z_FqnJX_m8b(XMUG>NdWuYX`HDjVpESWVWzz^{&xoM;kZn8fT{1xMkNQvzLuyyZX)N zY@F6L-5hD-+^$*Xbk3r^wr4r!JkH{IJW;%t`K}1hetsOzS$EAfx7y;5>H3tJZ{vZ* zo;KTlVC8pm*JsQDHlEe>S#y_--{|_hS#+fpenr>8W^WsB=sMEOxAE6q$C|A_w8H<` z^+hwEGn`NV6!!DGPB$YyLb>28U1yk0ZLFotG%wh=SjsGO&&OOJk6$|F6?4ie!9~)s zKYhjgNHEQ>UNP4RHm<;YB(CEt<`=|8H{d78058@^wXGS?hUJZhQX zNyLL-d_nni&a%IlYpx>}{lz?U53%SE=9w+mVEWRYdFBw#qCY5?GS7TbFxfNToWU8s z2ek_Nmz4SDT;i{Y7ZJ}NBIIuqR~ah!ed5c51%EsWI?;svU`u7q~ zTqxon;4Je$-}J7<{K@;-3(Sg~hp_2u;Jj?g0y9W*Q63A-E$i&%vA~4Lw*6SiV*jvl z%0iNh{n(Z%OB9R!!*|TNpP@eSygAsr=3>sn4YL8xm)~taK69H%qKoM0MAP-HxCn^2i^vJl6ZJA{QayI<~ic=z#ibg ziAzI$?MQsz)YhZ@!;SL5jg#ItixX#_M)?P38RDma8z+5WRwP~t`+qwUSDICc*8?|B zT4~lHu6+jOADRykKMdSB=|i(Qano5S|Hy1Z+yS_8(nn?&;>Sj!{9`kTxHE9$q>s%Y zagAnJeyhwJ;s=2}z)ur9p*(jaeqs(JE)Lu{=@WCfVCoN6n=g}G?1!y3=Mszku+`=g zV!97xzDF$f=RP$*Cf*AB3-Eho=4Zrvf#LVc%q_&?d*5r#UBsUpgZCRLYt3RC9lZRp zTN`VxGfNR;uoK1CndON^em^s-5R3eNX4Vo+`B`r^4CB-=&Z79(ev(txo6m*GKO{L? zHO{%-TuThoX*^G7enET+0*rHRFn17N0?sS3!Q4;0*p2dy=8weh1Lu|4Xr3T`!a(`w z=2_zBf%8gyZeAw7$BXh!rss3CWVlfeIIqMe^A=)Q9)WzbS(-SP+qc=QK)lR}@-NJL zh}Qt;mH5J}O?;T!_odm0_zbu2OS2jARBqoE^D*Li+`cVlXX0nLeP5Z0#6!4!UzzE| z)46?H%^t+Bar?HKeTa{7`?i?_h|hBSwwc3-Z}p)4+s$#rcLV2@*ltcEUd!$K+MG?i zmD~5V`8x4DZr={`ZQ{4NeLKvR#2dMNJIyu3u>1l2JI&3+#a)>GF7s>Ra=>{dcA5K# z9U98NF%J>n0-RUk8}k?9Biz2-=I_M6ar<_gmxwoV`@S{Zn?(KYl-Pux9KNq&wk9qOoL6GM z*@^gPZePBcKzyFtmv06H^XDxi1L#SZ%)~a`5D4ufpb!RFu(pn zJ_&q)I1RX8%0bidrI3r?3pi|=#QmT``o|nLOK=wBi-#RH@3ygn9Wk2-X4P)R^Tbk2Q~)Rkxsid0ytI8P9pRF=!3^K4r>LGlO_6@G#(~h;jTGn{v$TPrMbzALJp# z_+7UwcFY{ZS)SK9X3pU(&+8mBw}|k(yk1N>Zr=J8&oAd0DLh%V9SaM%#F>lkI7T=i~={;-X>Zzr@%XV3E54+v_xs4sH ztara)>&?(h!hJcPXf z`_Cte-{D=vS+3v9d-n-Bua6VO%X@zciC@8cfwQd73SR%Ws9(0Hir$Hw<^E4a@8_I{ zv+6}0tbJ-l?+zQsq*n4CuyJbYUEW*v@bX}PdhtAU74NM!&PlD}jUuiC`x{TC-sA0T zcx#N|NlV0FE_Y@Cx?*X!OZ>^WZ>> z*my>2eQy)u?I3rshThgT&Pi?P?MIxk66KA&Lv5Us+Q|DhaZ@gTz`N4MIjIkLek z(!u7XKIlDdI(C()Yjg3 z8}Cbf%v&^H#D5p$4)(aWl#O#zANSTLp3UR8^*%y8iidCKg`e1i_BWh$=#1Y}Xy?te z@sZT_-aa-ymD@}!22VA z&^w5@L!QXrO5*bHeiie3nm7~QuOe4HEb=SXk3ny3VzGVCc{3DgT2=HM4D6eq@>t`B69_b(Bt!?88{&6aNM0Gfi z>z|-FmFu7E&7ttf1N>7+KDlDKkKum0f2!icP~J=Y(-n{33EvCzzpD7_r7(*7=PQn@ z55JG&U#xgo44jwpzoB>x>_6rEmn!x{_U#f9^seWY#mE~oNCj!N613dIq9e@w{_f_;Pi$Gy=cM;___**n0- z6Z|Js_?IESPp19qT}g7}=h99qIliwNlJ=YT0LhWZq@7iAM=$t(OxhocSHk>lX4-kL zaZK2cyfE!gCHH~;_tO4SjNf7UFzu4JHibuCpT>%a`k7YoGL-N3GrsPjdLV5KfV@ZxYz+Xe9hu^QcH&9bCzQ3#+ zsH6DdU5qseGzj6x0!Cjv@R;J?b@={kpuOS;Dnj~!j*8PE{P;kO z;x|8n_pgCC#gV_k`J6zK;`@OY2D&Q7-*H?RNLBnH@a#aE;!dYfp02n$@a#Z_;>%Am z_GTbU@jl??fo_Ty^@Q(h1bQfL`5~O&3G`Il75KFxPlj;5|0%^aLB2E4NAWN4eC!WA zqj(GOvB0y6i$Z;z3k*C+XjU&q+v z>8~h$1mee~&sF@u6>J|16c_s&d7g z__a~ckEg${_*gpX|44De&B&`1XK`Mw_+f~@Gq6VSeZZsA*C}3Ffw5WXn-p*O3C^3R zZ&f_C61>k(-=+8oKj=%}r?^9T_&wY7gNpAx2=$+STyYuT%jv%;UIF?&!IO%ozlG&< zO7Sw_Hv?xBZ-(_~@!;=@E3`)bL-Ec_nEyW&Uxx5yf`2K#1;UpJUQzrL5AP}pofn@E z`MKPqxG!f@@voim`7Wk-A8?;Qam6KPV||uTTn)HlFjDc)ufY2;e<{URIG0iU0dTe8 zZHnh`zC-a2;0D1;irfAHzwaEZta#d;aNastRdH|()^~NqeZN3^Ybu@wJU&oc@x9Pq zlY{pwj^f% z&e+Y^#Ne}v>j3WzJg2w~aK3+lVlT``rUeHot_J0?I5MP?T#Y;=T{3c_q;-AaGdMaa+;y3SLtaZjV#qYrLJ;A?Q@pR666mJ5~_wQ4D2)JT! zzv5KjYQgUnx8!_C@j&1P!J~?A z(hioEaZa%}6V3-^oLBtV5NvN375Cu$m*OLBQGQABY0#JNzpQvi7GqCj{H-`P1?Jls zj$#b{aQ(UW46<8skw1`i#dmP_D$aoU>2n#y6z9K*=|?Co3**JaUi*OWiZZ9swnRE8=SYxsH%7!w6FIwswtj)7S3B|)KuK5I{cn|Ms39n-Hh$ZsH=D( zwCC?K8Y-SK7wv7Vcs+2w{~^V9!T5D7<6*@mflp^NRXk=K&aav)?hkx1qlMxw5pX{| zGfMHKkMQ|xqxd}ZC*uQc6+aJhm_I8%3i3XIj*5GLzCMA@iiZG?4@4`Dhxz3AK&;}H zzf4EPl<{T=fgQ2Y|`#f+fhNzi{!@MkI> z$T?f_Yry&b?utJKt{Cj0xGiwCU@yfDI6tX46SzU}8O0Cs@%dTB_wn(&zheBI>M$@!d`bl+SyL`@-{4D|5Nx-4MS~ z=KG3A!}{i2`bx!50XNV5Sny_AfFw zDn0}KfB(!)iYI~n!!o~6TmtOx6WF3S1?-=Yxm9s--oI>D{C+a_PdgM>0Qt+AyA*#8 z@`Zujifh)u@OuY;-}z!)x==F;*JK~m(2W5@hx7M-)A0HJmU`d{jtnrisK;u z&cM%#7X#<}Pbj|qFq{|8JgIm%%y%jV&ng}Y;j0DDD{jU4FU8Y=8w9T?{)x+-x5)9S zJLt>zYl_<*f%C?hy5hQ(;QRHNUd5SQUQBU&E{{;`277r&b&?W_pjslR!(tom~UUsyhHIJNKenIp!hF7|F5L@zWZT)opqPuzZT&5Rz>k@ z(7!WKRk3RkK7aQqUIcu5RyDRt{LK|dZ-?It%4(tbx%sf4lhsObv&C4R zZ4{S;_`heiQ#=wlHLIiIsV`vtL@Q2$^6QZmtN0;U|2&hGsQ6D_=xkt@y1-tep5p0HUPrSQDjp2^`7LXy;y*^h{!!L@ibwjey)IXr zz608S_WO#TJO=GO`$NTnbNKwMQoOYu@+XQ%LHKy%d;P(QuzgAoY zI3@cV#jpO2?RBr>)XT{G6?=!n?}=xBr})=lFrH-ppm@o0*w4&9sCXFg@a)5iCqnyq zG5eU}yT+mZpA`=|gM32qv1K?O{HpkE&ZiX**@NMKQ+x;1|E%n@in||&@h1BZ#j7Ac z?_^(4{A@PtXJ-GU_+4nP;{$&y?vxMr-?Le9`Fx#&=WS=UTX8CkkNdMV#d$Mf|0>&5 zym1iBhqH?*ehTLAe`ZH0?hfI{2YiaB0=v4EQrtBM^H(N>i*>tAu^x-~@FZPb(u=P>jcV%66-yc;|2o82Qnx6@xBLj-gYEXXV)sjMU#MF< z#diTaGdn5vLwhS8j8S|m)ECU}6(557%IlV>cm=FS$9C(gxY1BpzjgB~-p$J|sQA?Y zW3P704B@xBCfq2 zT=88aU_RO1r#QC~=KprZy;kG%T2b-+FJOM|RGbd>)ahPDaf}Y@@9y_0t^w`+tM0WF zKh5LUQ#_i-Z=`qtkKaUbERWwz@f;K0pLCB>JR0P`bZ@7)Jl7wsxINb&ued4b|Eqhl z;xZ7wXpey6M|gc^E3VJ$v$x{KFdp2|qo3k8Vf?J$BTsQ@2;aKLD8);lzv|p$oZ^9p zvHT_}Uc=kNRK<7R3H!-CURFF5<||M4cwO-<;0ZmJDK;Veq8@7%4}kHYefO^ve*@vy z_1LNS0SNzfk9@@my!{+eJe#+lUlg0r{wH@oqqrY$Kj##`2l+YB<4?ukfc#{SzZEa! z{jaM8gFoEAdK=O!+0CQ4>0lh6bj5E$e|52kx5RS(zEa*VxuwKG&XbMP&EWm^qqmee zOFW?tV_MEFCGP#n0Vzyo2j7DA9muN@S3Zir$8t-FM#Qz=1I{U4;;)}E{3JF4((nIh z1f@Tz;@!~ReL0dRS6n(8_e*`szKPI&D&>??oC)oxR?h8;$3uA7?^66RFzk0J?gRZt zzW+|e3$9>)cbDR?pu8W-xm)oZDBo`~t18az2=DWAswo}<+%czy;p3anaq#brrw24!NGQ#>B}gAqANigg}7O>tEo zKB!oO_LrWMt@r@+k5hAcDqhzc<-HZxhW=o4=F^H>ypHw^P<#%`V@}Qsia&<_VR6o2 z#V&RoSafe&OZQQQyoAIN-D z@uLv`Sk60&`vU)-vs`fl9{wZ6e?$7maz0V~G`DZ9;&zapqvuA&4B|(mZB~3Yg#RjM ztK$7!|2K+1h4pIDo_iF}11{BbzvBDhd8pX)2gO4`KEeN!;?vupf9?5;;wsSI9_@Kb z@xeRc`;tA+DmFl#)bmfp>p%|C-lMn_R5Oq1CR9IqqyQA>_6^R-0%%Nk5El#NQGePmsklro5{EDxD{z|>F6xRj)5A@1a z9Qh0U9&)d~ihE=G==Fl)+mFEc>|P@j7pVl_GwU@`@tsg!;{z`%?mQIo(`%;UZ7{!H z-D|dDFSM79z2+#6h4wPoKTq*bARp;pp!jRxoq>gl&-3=VNby_1TY4=C;U9Xvt9UIu zf2Vq_RJ{EUSTE#$syMAWV?}b;DQ*n*^zFGp@gKbXe;&zx!SQh#n{$q_(z%->(>crY z{hN7s>w9yO#r?+b62Bz5xZhYVcZ*`Y-*`{%wy^lyl^nn4Rx@{pV*I{ZG% z#s5LcF@8Ebs2Jn7&$U>@|1q+UEk6k@4o8kYf%zS7WIcrOk3_ymT%s(VpFI*egLwZs z#^Q62M9w4r9e9QNNaP!w^NjPbzW&Q|G;%d@#FMD+XykDbo_zuPqgOz_?QgHZ0upjBijo$=D_@^W5iF9v7Cn+ zr=##Z>`##?#9Avn5BpPOHfOlE1MBbDh@T^85aa!!$t8b@d`E<5d0(SFCnHaDmiJ>% zMkby@`{e!DUn2vY;d_7Zd}ZYR8rhrkBsLq)Bj@Cvjy%D6IJ?juzK2lkTx5&W82_l_ zIhb!b*dLLd1e>c~!1DSdGKJ*${l-?VKO&zbe*Y-ie?D>$@$u(T--XC2#P~hOq=-Kw z7ZDeAI3Pb4BR?U=-#1E%xDeUljep4HyyTYLkE@%O0qMo0SA5aaJz zjm$0WbDtC8@%OAI=icsXL5$`1a&9@_NMiiGtOdE1e4B{z_px3pa+lBeL&V45w_1{0 z+1HvFf8T0JZdKn%V*Guq_j0TIHWB0Z$ouxJ1)~`LZS-^tK!2QD$7h`9`snwm>iJr8 z7UcuqxAw(xmie#m%O)1_>-)BI7T-hInA^yAg7Y-C3R2pV`=IX}XIb8jeV4rf*&kxz#&R3eVu=k$c?R*u5oXWSouPJ9~Z+l;BVqtH4-{Zu> z-uAxsg2~?YzD&---kQBT`kp7bu(z{sB+1dwjrQ&1EbRT= zjP@O-_@aDceD1$6f70FZ z-sFS?-!Q@4-iLc9`et%IYU1y?rm|$;0>O@t+&KOw`wkF`-+M{+ofh$pjX_vnJ(}z* zc?s>8-xo^u4ZO_ji|cnl{E3_``8MXn_NnCG3O4Zm$>4}&--R$abA*OB1oPkb9_L8* zl_D+!`=6NJBgCt~z6fAQ4E{EHu>X8Hx~pRBKVOdaD;B>8n66m-9$=RYfbrR!wg5hA|# z7`jf@-hDN8u}}1C`McS2*gHVIQqMj61=nALE~LZtyOjQ``@2;-*Oq%!dg0+@x;e2T z-5;S1qFsXF*MO*eq}yo_%H^L7=VZTAyx5OX=3psngskF!x0NaBk1@=VY(_Cgh>) zVy#AA-Tw&J=Vr}e4#H>En0?S69$&~Eti)s?7p{}_fVmNdmn`DBlpV`HK)I8>2zv$? zuITH?&>q^M>txZHg2%NHZY(^D=r7az?Tb+VQG1bHN-o2P`n%cm`$fF=b%nbL)-0&E zby;CYD7#qlmm=Ke3Ftc6R_?;N$uN6FeOUD)>-SZki2rC?5ntrj#k{ch1Gh_=kb7A7 z`p6m^I0#+%?#!>keUaizeIlNdJ&-2kBEH2^F8p08+&b8cLA`~^=hQ>Fla-!|u8XBm zJ`3|d%I$TsGBri`p0&|+Q~U6!dJd1@W1I-L{S3Mu*7Qeo9cxK8$P2jMT;lhv-S z=l{o85l^_5p5S8iw>VUvN*7YzfchUF|%2v3HG@)0xRywhKTyQdBuZ#MN z@b<2;xqghVvuWIga;A79zb=xy3&{UldSB(wgNrTXuA5~UXrG7m;;zQ-@FMH1GItFo zZX1|P+#;~-pGkVeuLro9mxuST+@cu&=EKSQm*sQq{9F2OG~B8~p>~DyKTZEXi}$~; z|7(|5;q7%e>=oPVHJoMtBkM0*F4)CxTXHo$F6KFf{%-cb;Tw^A3ejV=iboMpX9xh%&|I*R;;`djuC z7Ve+g`Jcrr_*_Z5uU)JjS@C+i1$U^t%> zdfhaBdDMKjuyAsGFHA1VRqD~yyt}aQLZ9cl;U1&$w=g|IZt0oI*AG@c=hHlN4y?=I})#V( z!_~#}RlOFv@O3%9KGoQ>e0{1HT5mTN&tMLkhstugxpZZGvp_xlXL`H^>hI?CS@m^u z@r(lP^Pk24@0Ev~&xWpd!smGwUweIJg}a`?htnovaRT zpDxy+2KvJ~n%b)jclG#g_5;`FU=`9ao|E0p*X=IVp04iiR_){J^1}2Lj3?_?_A^pn zsQ4o|iOfOV!*>9A zxc{AAS^n3v_uAnK+I#KrR{35#oTYa~Tk(9QbJxY@(|n^ae>omBqxT3eZ^ifyCie?N zT_?+IC**V6gt|hH6;JM?%Kgn7>pwKrPssJE><4eOf0OGT8BelY&&d4($#NgE*z1^| z@O?E0lm74hEb<%9vLBJ{Up(*f`LyOiHycj2`|Ihu(QvZ;TuUkR2eSRAKrUWJlQXVzkfS50rgn#|f>kSouCuvasL9?#REoJ{ex7A0A%D6aBhV z>8Zt^bL+iV@o}gh-dFQ=ik#2M{!ivR+;y^|p9#B!ekr&7W&63gc85CgPd+D3R#^Lc zh_9)Fa!Gd>$8kB;p$%qU&N8xog$840ogM|LON-H)`kg!iB#F zmd{TqIwv7qI4_Wd<>pZPi{a(FX@`&(mR`qSQSM~V{DA-AoH1vs{DpoeThJfF$v^ns zc$Nr1c^mq{_dcnA6Z@_X*7+~tFVA<#^yU7Pbmjc0Iqj_4qr#7^C;4l@3SR~{Wt5phTNwN^|#Ko2)R?~4G;Iv z-b;IwK2g4f>z8&*JO9`A$Z|fH8rnW(I}PoptaBLGn;#s8c8~2{w#OK1|NHnn0)D5D z_7(B@z;NO@a55QAx^MJCxsxRXMYyVE9Gt%$gzREZaDTU&S6y4~VPj8XJO{h6a2k7> zo==eP~m-<8XIoN$X|4u45*G-nk_3|m} zO_rY(zV9VbPjiL{SN4;#ov8IMmpcori$ytMT>O*ymF-N9=Qlflw&uxlz7aZ)vEI)_ z)4ZVfk0N~;ei7VhKzl;x71lYz@cE6%hinfpU(Uw(PWIqSLXTj}zx`Wwf0%C&`}uh( z>v@#pp?uE7bL61ssc=_5w{jmq&THg+=jBl%efiwW@l3jMoICNc2q)*UlRICHUF-y{ z??b~C^bZdw*rnFFGXC|#N&BU}(v|(BaIJGc*B-~Lb3>u$i5x7Ht#E~%FN#|x$|sJ_ zy@_+2F19U0_{(#hl7nl|-&!|{dUG;7?}+PJd0zESzAhF1*e;hJ68gmY!@ zSiQ<}D$JGZFyT5`Nm@5|C;Nr#WJ?E&^dyV%*E$y}&x^`%lEcHv@{s3VWq#zkO2(HQ z9{<|o8`_9}4mOOR(~vIg!_oXsmebsN7|zMY^L34jiTx@!n?m!LD4)+TRLv-K-Ri%cIUCTkYp*vQzG} zt$zUJ_&s~!PUr909Za}R>ZjoMviLgN$@a#GaI$^;#`QaxaGmUO63XSDJf|GaGMtpd zI+C{^7sa>M%{;(pJ?x=bZ%j6U1S&AN#*^+^T_a=ye9ldy^XH54r$8U6+GdjKU_~>z6hVn z*Do-xlm2AdXDQ78hdCnN0q$Dygk5eX^-8%&*G2j*xg0+V>!0Lvvw8`pC(m=cn7k(- z+mCd`^8@FMX&>w;KNs$V?+9aj7Zd%6n|;^?8P@C9k;{37v_r0!7JMb*hxhj~KjJxu z^RjC&ob}vDf9XEX`vbX-ak5UkgkG7RT#sFE9g@9Bq$B&$@O4m>TgX@F=(EvYa@>&RFWtiYUtKTK4e z7g^rn?uH|xT!rgo>0RyYVB!AZ@g@JCp65tA`Z>{lCp$pp@*`(AE9pUhIG@SKSxucs zmv-lSvHi+@I;(u=Q2EIEkSyD^Ot4dTsPQGuvo-6w^Ssv1r@9Tu?WOBYB{#vlJ|Tl+Clg{EtFlX7tL2>yu#cL zV?_IUj^>}C>|)y~y{r4X*}hZ4o{AJs&LidXVBc@X{Z3@O|0edIt@%b__8o=r_#DZ0 zfO=6+B0RUK=ML_=*xe6V;m{u$!?o)v(i7p~eF+aA8sDy8wo8rP4}>zDljHq`o9n@N zW1kf1Moti}%)fNy`DXFFzzI>(8_ICcvZII}>JRrjd4D70S>e9q_2p!J>3xzcZ&{9^ z<9=cHXk2QaYzyQCOG>We|K0d5x}PHLfb;1ze+*4WhI1=Bq+KGsW$)GF{d@YwIVzYp z(mX+&Pk{F^G>(Y-EpEEs;$X7>`ls>acrw?I?ZBn(?S$u3Jm>O$lZWp4Xe#`_r6)8W zaF5W7cDdC(oNJedhwl4mbl*p(`#y%c?{oF?`tPM9)05A$ye}eIyoZB(jC|a-&dL9G z;>q^nROj(Uy*Ze?H&Ga0yFJKxii6JI%l8+B-FI_R`}ybX?b`MfY@ea!>0rC5AA6VY zA35m0vy=AKt$q1#2Vwj3FmaB);5`7bzxkhs7w6z_Tz`1@(D{R$|5^QAsNBiw9m0G; zy-|NC&o#+#q3lxO#W@rwo%@FGH`6$gNc%%F{?+}V|Db)+Ys)<~YJ?&xPe%`iJT*Se{ZY`d@iZxL`P`PqcnXl`+b)&I7U>;BJt;1cp-xco4c>grrn~f*W?G@(UtiFF5zTq)ZUZP*O%2)PF zvRuOXT)v1W{e|mf(*G}hU*5@HU5nvdYzcj@b=T0BHZK97O*|Ye6->I@V@gaA>YsCF72rfzo)ZJ$Xjhk*TwGRuDd{g zU0At?_NQ>(C!~LMu!mQoUaP#Np7QDF5AVU&pzC5ahob9%-ycO6?s*ImEcajI>XAR6 zC%||@d?&1vF`nc%!sLQotPS-Wq2Z)IyocxKEW-7K%RNlJhYYbthPz&T2kpl@$=+~= z^RZ-yeE%oxbupQ*tNXiE{;nmSiQ}r{jzJzt$Plk>xF{-ue9_3cSSw@ zr{&O?zP}^g6S~-!9JNsB4`u5xHq5bku|L|}Y zzp@4OxmW}4TK-M>y2Zt2w?et)KZ^DZ2XNQTs`7nBc)v&ci#M9CDBu5`y}4ob-V$c- z0KN`#u`ztSg?Smx+hl%bl3eyTvVF+aPmF3HJ^#6`V_8HjsG$oM*WI#3(93U={`*D`puCdzoA?( zAL9FRu>%SjryC6SWMf={Jed;*fHKuxY-%* zde{@ZJ{(MhcQP@LfO8rAJ&}XSb0wkcbT@_f&^-=~zE`F*o%bgO>lKaZnrtQfRvG5I z{*UN7*?rt~v6b9DH=Dc!{XOhEZjVNG>8f3iqIMhVI>|0*Ph4I&KfhF@`@;-$A^+TU zvvhjjCC{COy7GRCwcjDm!#G*RnL>Q~0-$R75#iLS;{xn7-#Uqf}!cLG5lFHaZS zu@l3&+3!8jbwUC6KSb_MgY`;k4YDtwCzM%?qF+}zdRQ${l8d+;bC8%f4|hpO3}D=QbT_?yQkxg$>sT{giRRU$&%Wk z3*#2o>t@x+o(?4MRET^wtzWPGzDc$N%ia3{rsrVNmF-X7bGcEL{k04q&T=1I$|cM9 z!6H2;J6K=X6VASg!e7P@?dh)L$L-mESRX#Gk>y<}%dZqbu=wXBSe!s@{ z@qFn_)Q>^$M@@E;#s`_sf1<|)Wl-aBY(2uo@_3TQ!P0zwQIKW2a^G0aE2LYC+FxO= z91rsO`3P&j=P}++;e8Ho$1e64^+!?gT;uco4)qh_{ydBa8?ioI>`)M0H>*S8bna@b zZ3pysu$v7p=K*4W*~Jb_6Z+51LD$1R9Ewk!#{PT|U7gM5iHG52Jn=nXYdpYnDNZPdFFq3Kpo{6q?*KAn)mJw6`Z zrOvy^^u#%sP=8Ff2hBTVI6I?Up2v}LJEQzCm4lSq8Rhl5TK1#8$aqd>>IU?8s&h7i zg+GQHbp@s3{0r8fI7j1A=WZ~(42SI<&+A|~c`nB;M?Ks82kS%n%XLLzoWu8TWPYu9m_O7v{0O>kI;Z1N_Zy_X!orDjLGYbZ%7;9sdUU$b z`zyFu9`<{1SY9HWxW9`m!dr~-Fn<^i<&S}jeC>0q9)7M4pZ`bx_-EneIg;@6qzSx# zE2#h93NOwl%5$$8T^H@)DXC?{FY??V4+FZZo)S&TIi&f?sm zOP!aM>0Qkq>ru8-8Sd}asNcnY`VL+9P09aleV9LaE>o6=on^UTIC0LvI{zs1BhMcc z#^U^>i_YD;)%TNScyW#r)|vdhP(itv!`T_-;q5Lw{+?4 z&3bM_+gZ53)jni-|J&_O>TSixRrroSjjvbp$8mPXSJ*Cui}gLm#?l}2Db^WaKktWN z{mA#PJhX46sr9|kS1`QXuPRI~_p7chmv$D^EB2{8OzvA9TbcH_KfMK0=fFuOnY`(l0Mrtjs3?hE1kJv?4L>R)a)o-Dtc zjd!!@$@U-me9G}cmYZ~?|NriJwU1|5U*RmzH{iWzlpo>ee865l4{)+8bnfZSohWxJ zd1d&n0EVx?zb_DapBn4m;Bp5O;X++(7bPj4IL|20Ke^O*N2EXAvqpVA=zdVR|A8~2 zorU{H(tI%7zj7h|lZIhBBHz+QJ4HE27rv{&_r)w0`}r>QyEh_VSO4w-uB+sCOys&< zGP+ov8!w9dg!_wpICy*vC-0xjc=CR(h$qgsW4VR<2v}Y%k}no!jl7Bl3y)vNNw&nup4Ak@iZS-^3w2@Fdo?{6PR>iE9&sMHV0z*H^4yfH7kU3A)ZeNX>0j79PRa{g zKS+7_`a$}K+5t~8?RQK0XBV&>t$nly;J0G!{9-3dj^z>_KXf0|+Gj(5?0@9%L&@|G z(eKD0qdq&M&zugS>Dd|O6=*&!>aKZ&V?4AcE9{=9&}o(^~J!_~GqU`ipy-E++16 zhR3t?i+g0&^C;v0TmF^jTKU0pZEy|7`o(g>_Kx9jULo(t~S1!Fl%bg>i|$ z_jGZ8oEOE>dkC4%9W_O{JyjcBaqkc3gW>l4({N%wB!4GPAtg#V6)rrO&-4KME1TJ2Nn5%~!B zx9kmXkD>9baZU8g7K?i~7GFz_C1oEkvHjTN->e+lm%UzbfBahdZX~??y*~|m zF$GcnmOeY9d<5Ai^DE<_Kjue%w^;hi?-ombg7>d*Pj(lEhyFJoT`Rrww>uPLdV*c7 zDL;o|eTP?k2ie6Uxjr|OzlSN)K{=L}TqmPHmLsN*{v!QweHJgH_vfoI=jgGW6c#@GJo|qdKK#7C zu**&NQ9N|-M4Ye3`H8fvuy`UrHy=;rtMGUtUHHyy4%UO!Zp6I@kGl6D$2)n>LyrGq z{eSKKZ2TS2xqj4dsP7j1+wtXleA(W@^^5aLZaS~zq2DXj=z9)2eZRn`QU^>^%_y75NE-YViy?1Tye(MN)p5=bOoA&cPOnx6>&M}nh>b;rNi{k>u zyU~2faYn|M{Y_~3S@rhMfM)iF9H$GiP zf&H$lKX+C;y-|5#^(^CGPriYlYjCqBWpUl&VUNQ)4etTWR+68mGuZR|ys^oe zbGesI=kg-#O?cnNSW))*Zgh*$@1fno9^m_e1@jYX5A5f1{Tk`lNxwn*P15fr{Y6NB z(L(kAe=R@PZs!HdH$41}mG8f=NA~;S_K5YMyl-Qr`%l9cHXcfSg~`S5wZVD8w%Bgn zbnetTZz`Yj>xGl+WAVIM>u1Trg>%SjupbFs&!Z3eV-F$L`PM#w{Cy~NaewL|{(joY z?&SAZTr7c~U;lsDd;2&WtNs6fU3dFtX3w74d-mKi(~KDzr4T~M$Ow^}j1V#yA%w>FpYzY}k6%4JU+eB# z*Sglt`@Qzw*Ibt&_cQ#Q9Nr(Q^@UGXay^DW*WvzM?0fjV?*D5!mS_FPpxj4?kN>kW zKfKRZ=~tdVe4MHKIovLl&f~-HyAB_JW!%=Em;Zd;ziQ8w>8$_L3x94uo^v68SF-fy z4_kl!aQ=9nT(}*oKmWPC>=8Au!@n2)^Y@yxpX&3K`;X68;rjmdd2#=81l#G>pL;y| zbC36r&pqLK{;FO7S^DMYtNqXQ*?NEC==}+PZ+q#V`|p2yo`2nMm*Pu5el;k&mZ4UhWq`$J^o+M zr_25ESJ(Bw?Wccz-v56dhsXE-YxB6h{2uP|bL_(H4Esy;F5>bo!-_bbffBpzhpYUAq6=y8k?XdEWo__;COHZ_oeV9)D%Osdl(@ zKe%;2cyvE_|FR$c+j_#k8-#z?@#8*b{!Ts>_y2I-@^>H$>+ZMdDz5C3DN;*y{?pXU z@$l~!;e5uqZq@Hem+hY_cR3z@j@7^VJ%;+^bX zAGrQrBYdAU??a}&3f~tUevVW4cg!o}S3V~xY(JIa_szNLJXb#V=*r{%>iJ2kea;{6 zng7qqU0#3x?!2mfc%Gl$2Z#Nyvj3N#|FK`*PhdH4?mYA{CE0FFFzMZ{k=H* zfd5^tZ>+q}6Zav=?~5!^B;&SdA>+;;_qm7b4{P{5;dofDJa0Jt%IE0*)$>fRd|%u@ zKc6)GJk!g6e{f}f`1xk_JMucQPNq@u-jGpLyx&g#E^F%d2VH*uPWb&nf0ZA8e@{4H zy=MsDFRWm__`9IB|6G5bJn!Z6RhBUS%JVsYycZ~3Z}|O2Dt`HR_1>Y&$A{lX6h7|X z<*WA|!4ly<(m(gZS0yU0+K2bg$iLIT`<$n!^g`?#SpKi_uO7~Py#E;Y6|h`bd*rG3 zm8#}}@yBx}ubdan_w%^R&s*Lu@8iI8jO6#Ee|_BR^8S^}$2FGsHT?VII>`HtE+5xv zqiXlRJKtmaISp5?gYfl)zqbj$fAGrpOoiv$mFeMm_E+z*3eT(Xc!b|ib>(}e!t>~_ z-dFWk=~uoVD?C5K&zqpehzlZse{uMiAphlxWN5PJWh9I4MjA8?@ibu@83<<}oP~e& z5UvNU53Mh?yU_sJ5apUdnT?JOTAi@Ni{@;*27Zk2(Q6*-5`>r8lt_{p<1U(jS;hS ze4f;s#3G%(N@|)|uj7ZMW{czEd009_7$)nF6Y97au}H_4N^L7vnU(mav6D!$RJnAi zF+ypasIAkRO6@6nNyT%Vbh-7`Q#eaMvEF**79j?T3o<=ToHiE0vKykQ&3bWvlGgrG zW5hfiU!>zpwXV0y@E2HvQQzvY8Y@y+sj9S@h=q~m2;cWM1p7{-x)0yD3d?9aC1fE~F> zh||zRIPY0;*dB~eYQKs4#>LreZ+)W&J~0j!6J_~WW1{iP4?dSa7!zVt%oybk0 zuAhWxZG=SEGeUHQ=HeHo!Q!<28!Y+*-~(;h>ln?CX3YeLjAFW5ctS%{Hlzhm3!{khp(r03aY<0N*d@8Ue?po7J6Js!vPcpR7YGoAHA^*pMr(`)PW`o?M8$+*v~ zZ#Z-KdB46f0PS;xy3RC_?mUh4RB6_BKJJZ&TA8)=xK`+Pss2p10?zPVLR@EEkokBn zj`8fhZ#L`%^XuvBTB+N&Teqi3mm96)+jYOZ zp!?HYrj9SKr!)rZl=Z!<^Vi&};um#4W$F4db$i~ylMz|I%B6I>KL6iz`!~IzjvtRV z46@wy`uc~Js`M(@Bc>nK^#!rxVtlD?Zv)-`g}Pr?>GPe@hf)MKlIY$(n*i+PCd`M>EpNEqKzc=R)W=&ozf8yP(Btxo z?uWHHza7>;kGo&zkAdA~{B_;mt?-G6V zu%|5Vs;@MEr_xe={1H8mv-S9Vt;c1(KK=$>?rJ^mXJHRn-y6DJsd}EK>FbQw^ZzjX z6w5uT`*T1a6@OOOAC%)9FzF{6TLH5_w7GR$e0flawpM*-B*wd=)l}N=5tdilr)q}R zRCd;DDmx4R348a2)!wAtI{~F1n`5>&!*+Q(K53jnI_-NkW3R<>KKrnpwnB(x>ww+& zj1Z0NrZV3U%HF}xo4F`A5ZYz65ck<#P5vd#7%2bZW{lm+Y5lGcEA95q^{8j9JyhE9 ze6zjN0ORx;(qB7EZRM0gE6u6aL0n(CJx`wJL#>9GXI_m@9$(v2t##|+=j@5P9Tmo- zu%AEJ6@~%5WOsF5JSuRVhh;u?$o9p-^mDy*`e~hBNBieG+CMiGtbdSGNBhTsGYaF^ z$ZjtE$62Sj_TSC5zb-R=d_{D_P#f#Z#PM5EPY?>vFR$mQ zYqZ0CzzJ85IEM9m4yyKL6Rm?-cP@8(>z6IK55_&wD*cexH_@{3ggVxz+L5dKDOdJW zhP#!)`Ptn)(W$pjh(7MA&dpdC#&!zb^3EqH4amCy;H6Im=76bk`p!L1#!tHq<9qb)MI1i?$2*=? zvffxvD>KrP^V5tqm42nQIrc4>x8?`<1)Ulr5Ep2a8k{+`Xw)mRq`JO{$_RJL=ir_9+T{YaU!Z7tV%nR5o?O?|tgipOhx^B*eS zR@#9wCnW7~nR7&!cS-wF=KKTW$m3r;rF4^4-&-pFp+3*ATKhQad~0<5*X#Hs%s19k zq1$&{m-p)YJpf7kV8>->f~y}xe%7U{proZDsoX5%*W=Oxc! zd)o}|t1H6$dSh6BAu_ybJ!fgX-mC0fLvL-_pS6tIW;M*480_z&@58>@yWSa(`925f z7qgkJv?-Np2xh_nh+ycZ)+(ML~{7~5A0?uu0QJPn`M_&KL4(ks(ruy6lT`k&*MwGQp$ zapUT`O6kXvd}FkI8YAu9oxa2NR~WZEq$@jgz^4DZ&f05n{SNY_JJy5rM+fW&;lF11 z)VhA%r#^qY?JE=y;`#@Q(XOvxA3j5z{rss>D89!&;8B;l4xc;8UU56F+qYNu?*%*b z68({~TP>pu=HPOX(=9^Pp&6=TIQHNzeo`?SOy%5wNq5Z^O z{dv5Xy#xIb@{gALjO+aB^H5X7=_ju9_mcaGJN!efBJ5jw_=nn)xAFL)dOi%bzd}3D zM;)-${7N@27GvD~UXylnxnF(0d(*EzcNs#BbJ&i4=ie*sIR4IDk9UR5@r;aCGxuG8Kz#|_S(X)&8E`s3ax$MYLvz5OHX z)IjJj&^R&LR{Mde@;os@X(xO#SKrI1>)af3Ty(jY{W#V73hVwvjQYOgr~FfIXQ*Me* z>t5Y6 z5$mPmdoiH7(i{Df5ybs0Z>hDDY&Inw`7Ua_pxI(8z z&wjN3r$yur_J4(}|Ef@Xs}@GHG4zKUgt$4hH+){}C&b%?Hp_P19#Z~3Ms(HVd%%^B z_1-sB-~6Zq^8i{G@u8vPt{t$~_9|?D;NDU&VAVKivFGvQuD_V6&CmVPays} z`h{_|FRQQ~fM3J+i`G`myMa)y$MaDYmJfEF<-_w(eP35$)x~wQoci9bLVwS8+O-k$ zWo>A$^amS5Q>{*)!C!<{>HGs0_oe6u`zY+rC+-85+MgQo`q~P^Zi4a$LWZr5Q|*rR z7?izl4V|f@X5mPe! zV!4;aHklMKtcntd*@RXQP$B%C{=YZ!$%JqJ6N!$Pm z<8#n9egr+n&vpI6XZY&*MU1f#3>g(*qOqes`rr5*Of%lO0sU`$24)%0G(i6wuY&cA zHycKY=EjE&Jz|})AKYks0d6wB1}|9*3!7ov{ucDuCqbWm8jP`j0z>viFwqu`@HYy! z1E$##V5S`nX4xUIj-3S7vs1x_vbHAj*yeTyQnF=Aj$}JK3n?A#>%cDd4PdU_80={` z2m8pg=h>|g&bMy`hsc%;x7qShHd{MJ)-%EGfZRgao+4RivCN%mcR~7WyE{17z6+dh z_X8K&`QQ?JC|Dv>mdi3LW%?R<>^fQVM%fRWWXre8YcG}8UM|nI)4mTi?6wQQJ@y1} zpFJ7eFKaj?Yp9grDj7Z|+jdgcdCH!Kl4s?$pO@EuNuEVG4JCRI&0+s!I_#e;rv$9ytN`mdFM$o6wO|uxBiP*83}!oTfjQ20u${9L z?C5*|c5yxebDht?p3Wh#kHc}#a}Fb%?|cIeaZZ54om1c_=Nvf3`30Qd{0#0acb*0>InRN@wH&lvt3Z$I70~C}0LHjBfg#s6Fwyl6Sl#s=nC99IX1ex* zS*}mPIwT~T09R}k#u zN&xd*)xmsMIyl62H8|XLEjY?m4;1Qxnlf<>+zu-MfeoayQW&USSJ=el}= z^Id(xg{}eM64zj`#5EjT?ivlQbd3YoxF&(?Tt(nU*9>rz=mS$>@?zfqPK5p07U!FGBg z*iK&r+ZGeSmV_dB-oyyjP(6Y@lP1HNGMpvL)RATC$zvPJW1Gl2o69;oMsVJCiCBr& z=0>~>_KbKH>=W?@m>01X%#SDoheW&!4v*Lcj*8d=j*0jLoDlIjSQzmYSQJqO7DpTh zXGZ)0&W<<(&X;FgD9^Y=wxmS1ZFvO8ah=TFD04T-+)|lRE>m{Ol-;uB`((;~nQ}APjh9+|Sw$CmH+vE_$+ zY}I*L=8`;CM9FK6Vr{-C))pgE5@kwtnUW?`GNV|3R+OC8QLHUnmdTN2+Q~87)m`1s)t%<2Pt5ews$}_TRqFWZ6YKfu6C3*J6Px(y6Px?#6SMvF zi8+4y#CCrA#EyRY#4djN#9TjpVo(20u#f)(Fwak)nD3`g9O9=>9Pa1r8s(=?9OI`? zoZzQVEcDYS7WwHDi~aP8GyU|5v;DLibN%#*^ZoRR3;pzoOZ@bSC4TzE<$n6am45of zHGcZUb$L6rr9*zsu1Y^=PL(Wk zO!n$Y*{i2yub!9XFUj&En&s_imXC>M&7o-4lPJ@x%k;Ep_G)G{do?SXy;>)ly;?7t zz1lE33u~lF^mSmitRY9%&`#FSQPz+v(|gMF;W9i*hR4X<3DF$uLV1>=X!dY%^bM$O zrp%oy%g>kP7s@)9$n=tE_Qpz?yGG`&lersZ?k1UA8qNMGmt}U!GP`A&J+jO`S>})| zQz^?-$uh@enX@weyiC6&(?yKzs~Gl`Cx&N_iIF`PBYRBdR+qVHGB-=+){(glWw?n9 zx0B(HvV0emhnzEGwwk?HGVcwHN1$|hN6t4u#8OP-YJ zr((F8&c<-LQTxNhP zE-SzlS0}&~S1-U7*D%1j(ImjR(LBJpksaXN$O&+6vbqsLDbqR3A%7k`~cV2kN`)2c!29`RDkPiOn~caLV)Y5Fu?Uy6yW+Q4sdRA(g63F z=$bIIa zAlFf4kTbI?$eDR8$eDRE$eDa9$oY9T$oY9b$oY9G$hj?IIZN$W&Qeb-XQnTfGczW( zIo4EWEO(MwvD{VGiRBKnUM$y6!&t7|=91a5JY!BQ&)zPUpCxLYz@r=14o~37qXY3PVop~YF znIB@ELqe=`lq@+$mYg6<7Rr)EvgBNuJ74B5k>L^j$3m0Alc8zgsnEmV+0bn8 zd}tncDfA>L;ueE;TnXrjTLJpwUIJs{)`Fq9jbLKjX0UqPTVPt;b}%z;CzuuY0az#Q zBd}iFXJEs)LtvA*!(j8cZ@}!h6JSoUBA1sW!5iE*p1{TLIOosDan4_g zqh%KHw9Ixq=f5YO^WPUw%N!F=%N&ZQWloHzWv(7i%bXTZ%bXcc%bXQY%Uma(KB8Vc zeMH0f?O>DmonZ6$55Vkr+UlHm+Uj=kwACHsX{)=$(^luk(^mJ4r>*W2Pg|WAPg|WI zPg^}Cp0;{;JZ<%;c-rbQ@wC+w;%Tc3<7uml;%Tdk<7umB#?w~Mj^|!zZanuw^W$l^ z7sk_WFNvq!E{UhzULH@oy)vG5drds;_PTi5?TzuY+neHPx3|XAZkNW>ZkNZ?Ztskz z-QFEfyS*o#c6(nu?e_k7+U-N}wA+>OwA)qjwA;txX}3?t({7)Nr`Li+U?8)+U=|a+U+_CwA=L( zXtx_C&~7(LpxthsK)aotK)aojK)c;8fp)uN0_}E}1lsM~1lsMM3AEdN5@@&c5@@&c z6KJ=GB+zaTPoUi%l|Z{aCV_T)LIUk}VFK-TQ3CCDaRTl3%mmu)*$K4Ua}#K{=O@r^ zFHE4_UXnn&U6Me%y*z<-du76Nn8|ArmV@gOR)HH6UI8~rZcX3}FHPWQy>iK&2^)~R zJ7H5(Q+$w6(h{SPunj5u65av#C%gw9O4tonChP^P5a}qm&?Gn3z9TR(kT@w3(xrqb7o{59O zK8eG@yu{I9e&RTANa7@Lcw!MaDsculCh-w)LgHg!Vd8wSC~*;3ocJs_GjSO>J8>mA zH}Pd~e&Va(!o)YgC5cOU zTu%~neMz)4F-f#Dp(NUw#3b68v?Thh%p@M0mBeG~$YbltV;jn2o5*9E%VV?Uu{rYC zc1g5R9g}FIx+Kv?XSqpm6t>tm7hc#H6)2PYIqWD)Tkuds4+>jQ4^AA zqY9H~qvp$&ER-!-BHK_R&$wLHvoeVmX-yKn-nyiB(I*>|c7a>vRg}tO%jK~<<*~cv zv3umP`{c3vlV}qTCGpcoWfH%es!HN_2*;B6eZ@&x^C?+#X0q&)WZ5Ul?9Y11?9V32 za$g~Hvt@3M%xx!gJ0`QYb7gK%ncGLE=O?qxLz3C%;mK_CsN_B1nB-5u3CW*>g|g-% z$>QX%kTNs53Y?vM9Gsi{12{kV47f1)Jh&wJSFj}6Y=*g!>;_jR`@l8H0dQS%Jh(Br z8n`Jr4cwY6cTLrJU7>2cuF~pcd39dh&g#6n-PPItJ=Hl|_EqO>X_CU((mbUmYRFEx z2Fyvhi0@e1rPOVP-*Hmffn8Gifw?IYz@91dz&??lX5M% zJmqF^WlA@2jcm!flzR}~m@*dJlrkIKnz9TmO?eY6Px%nsneq*|JH@yezvHANg8Ndg z1^1_9gNIUjfR!o3!K#!Q;IWjqz>_KGz*8v^_*wOAN-fx#ODUWWB9*;rr?NjisqD{~ zRHlbydSYrcQmUthz_ipPFf%m*%u3Bh4Ruo6fb~*u0~@Ax2Aia&BDZ;JF3ysZ+6yV| zWNjT~ZC&J9a^+cirgGH!q;k~qQaNh*sT{Q-sT{T8sa)fuQn^mYq;j23NaZ>$OyxQ) zO658&PUWnanaXuKJC*BnZYtO5{8X;fg{dnVp|?}pVcff1H5)C-y=oqK>?&SkR@&)? zUQw8KsF7C`rP1&2OyjqXyVLlc7?I50z+D$yG^-ZmN zw0ilr_V^T*-#OtAs& zrba+-qh=i_9;nl)Os8%U{U5+>9mxMj@pPR}Wj=L_nEAjAXb}DJ2-CB?GnPSFKb7UE zTg2K2RzO(}w-caT`V8EzAmc~1;x;=Ouc@_-)m%Jk_nj{0@H7|QEj zCezXXI(>!K9a@h-KW6_x+5V$C-Ewq0pse4~T2pHqtplMvJ|B8SjGHz{r_a#3LTkCq zpE+%Zj%T=3{Zx6KP|H~PAmh!9=cZ6)e?mDPt)cSzwGNc&Lkp-(U#8ODm??r{-&~AO|5OT4$?Xu%5qeeqguxMQ>e|1vLdRScRGKC)*V`pK;`_? zaf_y&;|yhe)Ggvj(RL{Nvvq{Zr^@r`_;ekg8mZQ^#+Qzx zGJZtoQ)T%mb^J1@jQe#Q%D5G+;#9^nbetNFbKMWr=~Sjq*KsQ2M|7MjkBiamhBDq> zD*9QcQ)N9+_U|&8zH}Uw>C|S%$)fE#oyv48pxX;&JVVE+j33c)s>~1Sc0d{D-;uFD zsp0r`BY7(0yNo(gBeI%J9jMDuS#Ft*QyJe5U52|>j_7nM)2Wtm$5bk>%L?iCLYY5M z$El1@hjLyl)4E;fQ{{P}&5YZpWyGm+)1h29ROV;K<9=w^sew?A({w1WkIMXII!=}K z>G*aXKceGQ=35D>ek$VwWgPYE_%i4Qv=@I;D`Jgn3evP@Yuyg5f#Z&7wUSl5HI(h! z4rRSZbh=ed^uQRK^GDIF<2IDC?`# z+WIQp|4^QP8FUwPyN**CugK(imyYw+ysRCJ-mMw$W|U1E3hj+Jb)eQ^#(UFd>2xa7 zsZ2kv`>7({5Db)Bh$F&xf-8 zb~B~LS~Hugc#hU`trb#-7F6l@aUD-@fxo}Syw8WSzACMmH#3g%T60>e{Bo&73o^4+ zJYQ>-)S(4AtyKC@sO&c=uWPwZU!~J4pt9ezdT&wj+FIK~;mg^GWK^f>zztytVIC$7T0W#Sxk+{$}jfz zRO^x&ku{~bHdKx$l*cn3k@ZY*d!0^YIyE9|OL56v>b$t+Q_Tk`+qo3V^_JdOX)CRH z&`HJvc9m&edasUa&A(5z-yW%Sxz?OfDqf|vc(jV=->)>MKxyU}rS@2*Ra(o( zsd)ZGUG4$u(1PV!4@225W0KNzt(8z|-zO_g)7pQEDwkiR>zk^ySZgIz+Pi5=Gof<+ zKD9dH)_;RgPT61Qo{#*{_@%ay_4#=Nk{Jd>hK+@}Qje zrCKYs@<|;`&(m6@wNz``ER~yV`w68*P|mkXD6fjZOYt3A#(w9peT2Kz^4GdyT$M zt@bOrKCP8&(Qf0r3AlM$YBm-9m8TVtAd&O1RBPTFDnB2}_7>@QiPloBX`58JY^`}( zi?pU~R`nKbQSB?ynzL11PdSwJ+uM}pOND)WOV_Kl_-*FH4sX}>K-vCMt(97F`?s3! zJJjdI%AG2XM~%qzlK0i|rCKYsmh4jP%>F>-r+ut6TWg8dQmuG2i>xnQYb&k&wU&IY z&!e>*%5{kkuX6m-w3dFM>ZuItm&_kpP*SP1=&;h#Dy4Zxb-LC{DCc|jH!3~tJEi#Y zLe^6bW&dWLRGRa>(&bvK&Z>S&zogpHN^1_3$BAEA55@<|c)8Z%-*o(Ur8fTBg83y- zmM_=wO#HnC)0b;CEJJJ;^CsdpdRZ<_YdMtTTctJMQO9ND?;}}XF;v=9tyLZsxA6op zIWM3rSA;hoabA>YT?*YUE=(-d@k*`ua3ag4Y0cJ}r`5*a%W%AwL)rd({Jo8ApVmyj zO3%h~Ksa7h`kx~F{nfR`xe3LoD!(LC<(F!$x>}_#ucfrSw$jXcN~^Ty*VpMc=ya`_ z4OP4Hwc2e|eva1VTFX1&ZPu_KRa)(iDxRq|yHL05LDdhHTE!IIFVj?ho>nnk#fzY; z;TKA@mTIlkDvDKpn$~Qsd0LCKmS`>2TKTXc_e0?{@sdyugBb$eF* zO5Lh;H|DMjDMz9F?7;ijpylxyae!^?_ zf@WQ_p?R};uQ}G7XFiK(!+c;KFprvN%?oD8O0())w^(;s{jI^)IIGYqvL3P?wdPq* zSiz`xE;o+i@bD zfD`YeIGIiZXP7hHndLl%C(FFmZycMwWp(}hv#0;{hkS)BG1E~zj>baEcLANZ1j|Q-uHa$sq}o~ z`O#x~J>Dd52k!uHiT73SR_{*lUhfy)AH3(iA|fgxKB7iMr-;`hK8n~MVMW%DY#iAx zvQuQg$f=R@Bj1kP5qTi;`^cXny}nf6{k}rqBfg!!FMSt$kx_xDgs7CLtE1{iwTrqV zYCzQ3sN$%FQO`uZ5Vbk#?Wny`hoeqJ{Tk)+NBNWe>Hd!Xe*QuJ`}|}5h5l*&nf_P& z8~x?}3jb&RL;f@VU;GKt*F-mt&WY|4eRp(zbV2lk(KDjwML!e$LiEeguSUNS{Z{mj z=-tsDN1u*99~}`>J*GxXc1&K(;Fy^)kH~1D>EiSU=c2czdv0@UGy1;E>>b!70Iqf{zDZ z2(AnMJ@{qtMDRk;8=DfF5nDU9QEZRczOe&iN5mGyPK&Yt<;UUg z%f#by&K6*|^%^E?(J%O`PH3*yiTD)30y*$L9@B&J5yHa$dLrK0F&TfKJQYs}n~rr< zjNcRjMgmq~GX7Gjy13Cu6HSbCahs7LJ~J{!rBPEHGqQx&tSchSdLq)SFMMVLkzzI! znPwwV)4WmKYBm<_&8Ffu^Cr>3Y$iII&BYyN3vs8}QuHv}ivH$pVu0B}3^colLFOIe z9y3=AG5d;p&HiG9IY^8#@4;Un4i*oZBgDhz{bHtBAZD9m#awf|c-)*Io-ikhh2|tY zv#U@nHm8VZ%&Fp8bB1`%oGD&3XNfiDqhhT&PrPbAF5WVq5Zlf9;!AUZ_{w}z95tU7 z$ITLP!d!-@6}=!%nQO#F^JVe7`HJvZuL{4lK}1^{@qDk>#I<-7N?mJ{sAp{v&8)4W zjkOa`5ZNm_Ss#g9>nqX6suX>#!(xE-wHRz25yP!2G1~e@+;5!~1=b}o#uB387x=43 zev*K3+-%BOs*^!}HWF2ScLmUs72TBYl`<0%!Nr>`T>T*XK0et73@6(0j{ z%j37`dS1uwh4F^^d?T^TVZ1+fxzs4Fn{~aFr7C^PWTlZimA?A3(%Uy8l z`EC2Da=W@Kor>KD&r|WFieF!#bjxt1v)@(vq1M{Ezt7cC=`HFiU4ymCdM@d5sk;A{ zVzV z|IuFQ2YUR@exu^w>2ZGN1r{=JnR#Jpwt*ttr# z;`$grR;aY*4@$3jUFqrDls={N$K%@!mj6;~^93qitn;6or{ecv-m~0{rAn*m`~n@n zs)I@&?=xh%gU_pY^T(79)z|U7PXC8)|EriEtoNatl%CnBw52Y0PWQ(hx?X-8!}1OF zb*<6u+oRi4tjmqn@%QGc@-ONBbS+cyo%NK4HYt5y=dZg}#WVEvEYS5;*T=mJ`^NJh zb18jKpZ{^){;ill%%6mHL(SILKeAM%ADgN4xW2yl7gcU4Mx#=iRF6IWtY^i+bGN*Zp^@M5W)O+qq6(-&^|ltM$6c z()n&3ck6yi(D5Pq{D})yeG&DQ4%w;ns6IYQ>rg#D-{^7KrH^l~^RLn4e;(gzu^+bR zcGb}HwU55eCVCwlg&k(O4|RXu(?`V*>iXmLI4^)bqg@Kysb~I)C-Tt zw406ortEFeKa`%?pw7QV>$C$Zz4md~IFw&~3{Sy<-h=ah2km`Gh##RpApR5dm9h9V z2eoIx#*fCG9-k^bg7IKK@qE0##c$%NUdT7_Ef)13&>(aG=5-?Uy)&v@HvC>H;^FI? zF#=EjK)gHr=u2K)$ARl`v=njl0>)(#~)g19k%oFNJoUax10LGt6f6*37e?g_c zpweH+bgW-0{RNf&f=YiurN5xkUr^~UsPq?9`U@)k1(p7SN`FD6zo61zQ0XtI^cPh6 z3o88umHvWCe?g_cpweGZ=`X1C7gYKSD*XkO{(?$>L8ZT-(qB;NFR1hvRQd}l{RNf& zf=YiurN5xkUr^~UsPq?9`U@)k1(p7SN`FD6zo61zQ0XtI^cPh63o88umHvWCe?g_c zpweGZ=`X1C7u1pP7gYKSD*XkO{(?$>L8ZT-(qB;NFR1hvRQd}l{RNf&f=YiurN5xk zUr=*&oc@Aw`U@)k1(p7SN`FD6zo61zQ0XtI^cPh63o88umHvWCe?g_cpweGZ=`X1C z7gYKSD*XkO{(?$>L8ZT-(qB;NFR1hvRQd}l{RNf&f=YiurN5xkUr^~UsPq?9`U@)k z1@#o{6qWvhN`FD6zo61zQ0XtI^cPZfKha+>PJcnAzo61z$aMG%D*XkO{(?$>L8ZT- z(qB;NFR1hvRQd}l{RNf&f=YiurN5xkUr^~UsPq?9`U@)k1vLlu^L8lhSU0F&YXm+w z^g=x4Aw1;4-O7zf(s?au^E%!_$6xwIrMq>! zv(DeD*TccJs$D+Tz)>RGj{hexnckNFmZ+gk7RvHX12C2*1zx!&s+O51wi? z4dvXZe+BfT_Zx_Z_j7OI zdbc574eOm+@}L^m&UtFw!sB@5ek#20N?DD*$8ooyAE_61Db3gEkGECvX*xa_?PIyy zVHc?Hp3U+o+BzM|?q-wwaBqWpcxKMoD|Yq+03ggs+BYGEF8zm*Q< zJ~aAzHLnNNQ~C?~_ebPM_fz%u)cf8k__ggE(#5Cv&IY>bebp|HZqLdK>bP*bu53@Z z9k1+D<-+Z2*g)0CapL+8??3PTQN>3!SM5l9LG3$tZdUuzJvzU3UsaC3!f}37|4q%4 zpKnpeZR~=%e?RU3s}EZMt@vH#@B2iZ_eJyruZ!PfL?J&s5BnFX{kM(z%Wc>*9ZBpt;A;y!~^fC@;B{NdO(ls0IY9bXBX5< zJ*SWRMC)Yy>PoxcNB2|x{n(SBzEyj%MxZ-dsrt6Uj*mgS%K#PMrrT3IU-fU3FY(k> z43z!?^MD)7IAbEP(TbHDxIL7vdu}DqVv1Fdoi7vlV-9#4l(K7OVIItp@xO^D|~B z?XUF+{43Mv==|@o-WcE0R9)|rOO-x)pBl&a(O%ktYvB*s|20tm9VkEkl+vA;=ZxQS zT4^`TcgF9Xsk9&ZpU1_bUZ#iVd3Zg1fqBUM@aNgD4P{5e$MO6Naa<54iFQMnO5e1V zPV*>j5}~v}mn+xh&gpV5=yDJ1a;tQ?^SWGZM;-r>F1JCK`%IThvs8Z2rSvCV?lWBu zZa}s#N0+-%mrM4l^ozP2?axwNPx$lv$C%gj2TMxf7m?0>e;FDxLTMoy!2UV@G(J-x zeMxIIPnIVrU7WAx?@2xXZ`h#XKjH$pE|w2h%JaR6;}^W7>YIT1UW)k32bJ=??;;*s zr1Hb%uKd0vY;Pja-rXqQZK^6?19pe)ycc$d8lFFQA)n*U`l$5J%zy4{75}7zE?=qQ zskf-_pP#6Yy#~q;YoXRlO?*z`I`VJF_a;ccI0T>Fp&|TZdf1*X$M+v!BP{~{oabSG zA49x!iYgcOA6?)__`OU6>>uTN$9bt?e-bXod&D%y#IK;!K~w%R>JhWtHc}n|P5e&k;0}RD z-7cie22H$2%8iscZv6F{_#0^Ad7ECOJm!u-%3RRIjp31CvWNn!iDY$*g&)d8;Vw7Bi!O^iW@~6u(4+HWQseJl!8`A-aJ#i|!zP(FL@(L29_%f#>C z3Sk%~T3}(1@i}PX+zxm|;I#sx3N%rd7yJn~TbZaa3Op~OLA;p_`~~+Ln5Z`nyd)C9 zU-9NIymb_B*f4R96i^sffd=lf!5TF(K+C8J+D0wVF=~S@<66*-`*2J=m$feF#ha$E zqKyV%q|pfU8I8dxqbcY&nt{mH0jm2O~;~6m9cn)l3 zECp{dmVvE}6=06>BG|@Q1>S0`2HP4hgYAs9V0&Xdc$={S>|neGb~N4qZ#OoBos2DD zXJZ@K#dsU+YLtO@7~8>a#ttyocn|DuRDgFHyTBgC2VhU*L$H^z7re{(80>9)0`@UJ z1N#~Wz`KouU_avvFwgi3>~9%yd9UN^KCf2xNfdz&GjxpTeSi=jBGa|w9Mie-~ zhz2Jb0q_AM7Mx_nfrUl_IN3-7A2h0gQ;Za_$hZoeYNUfRj0_V`=LWH&jhYD01hI0B zS_sbtv2yW_2iz3|nz%3YT5!H`9a0v6rg+k*i||vRDHa;_!9_*`@M)tF(ielKSYk8= zpD~((&l=5;{v3#RZ5u5RUJ9Dxd7~x5%Ro~sH(DXQ0yM=7Mr(v$1WmEhXoK)75bujM z+9JFfG{qXDJ;E=8rg+8Zfbd!ny=UHzZ~NJ$4_6Rd|3&H!NztXT+O4Z;psk0M+fgdMQvAbc$dJ77JA@O2<8fHe={ zdLS%-^#sB-mZ2{X_+rW0#+hBXE47|e5>}-7icCkJLyIOm}JFJhvZq_GYuJsw%-8ul?X&nT6SYLoWt*^jd zc!v=zfOQ1yZ5;*sSl@zut>fU`)(Nnm^*xwp{RsBAPJ;uiGvGk$9GGwY3=Xm`fcIDz z!NJzA;1KI~aHxgFEbg@|aG2$Q!!0+6cSwQvS&`sKD+(NCMT4WQ0C>L@3l>;$;20|b z9BU%`tPF6HRTC_H#jWdVx<`y}_rfzTiTuAGip2u)=Ow1Hr}CAaDupXocOd zhJw#p!@%dP5nzcm5?pGH2A{VIz-880aJe-eTwzTFU$7>DFItnqmDUt+l{FQ7$(jzX zwq}59tcSsuty$nJxMvpDz?uWDvmOK2;~rXA1M3NJgS7zMhb4Xj1r>(*lM4cuc3 zYhXPGZnl!EM$m@GWaK_%`mxHO2eZT70X%3&c~Btn~>09W=#< z)&_+4fOvnk^%}w-fu{JxdIRB4K~sE&`*~q=tS#W@);92<^)`6eDg(c^wu47-$1iM= z^&WT>Z_Y5qx7IH3nDqg8-1-naiF<-g@xApi_=EKc_@nh1c*;5ep0*Bx|FFIQ&sbl9 zXRX8FIqL}clXVpQ+4>edZyg6OSSP?=tna~#){o#N>ooYQbq4&+ItTu4{R|5G0%+J5 zLDT*fwCvwO+cs?MzHAG0*$(Ko-Jr+zf?hikjIg7?NIM$z*#R)xj>Y%XF(B5y9S3%^ z6TqIh(-|w;t_I#^r+~fftH3^XI@s6F0PnVIg8gtuG*+}-8|-gi3l6Za0|(l5!F;*{#6!c5840?z6_6vD<=Wc6+q*9S~l_ z?f|}P-wwWKcLsOjerywOeCP(gZ+8cG**(DBxJw%|#O@9L-R=v1X!is6*!{u1_CW9> zdl2}sJs8|)4+TH5hk>8kBf!t>k>GxNGfJ@4O7&?yLnnIqSjB&IYiH^BUOIc>}z|*$j4bwt%_LHn6+%Hh8B~1{OQp z!NtxFaJBOuxW=gfUw3waTbvKjhOHo0wDTdtZ-E$DXD`CkOFaItM1Xeg;!q7f>=4#Qwo`5#clt zI|SFS2-gO&Lva0$@U$)7I)B~{}aJdn_5yXDL#kZF=0pZzQ zkqEa2;n`jMy{iofpYDoAxE%-&j`ubh;&u?D=88qQGl)@h#Ub1k#HhIv5bg$Ig}Rau z9spv6x~d_Z4`PM7QV_le#0qs?h42s%e$$l>j&WsxlU+5z*{)j1odd#KxoU%lUDtwN zyRHL|xaxx6xaxx^Tn)gJu14VZuEyXGuBJHlM-W!d)eQ8yTOcI@#H@C=L^vMAtai6T zI1xmjyIUii3}RNh+aO#W#3;DiBAg0h6x{6*P6P4D&fNjw8X!K|x%u|COb~tR?u>8~ z5PL0mSMVlxH>5NJvDb2UN4N!uy_UNN!Yx7UtlYi89CvS|v;ncRa`#2JEr@-TyC1?G zL988je}p@MSUc{42zLR|=k7t^0QX>|3*yp$l5FP?PbA z5PlPc<#F>j&#fRVkNXX<)V&!jb8kWVJ0PrtdmH$T`)#Cr3&PjC%fRFA?MV3!#C&$| z08hH#1HX4yfT!KNz<;Z0h+6Z0R`+W_yl+tvpA;TRh)_tv$!V9M1``jpuvtR?m-MThD2*o#zbL-g6Gj z_56%;bq8USJr@w}0m7SmE+X6ugg5v6ig0fb-rVy$!hJz_bB}>v&ijGz<{k^-{vhV9 z$3b`?hjMdLj`X3S!=Rq7WViV%~b95gq|z#(Dw>j{-4cJ+TPi z55mHD;t(DKV)l9x5FQ6&XYNTtcmjx>xu+V!4}jQ*ds4t6&s9j73StNDNk@1(2p{Ch zKzIg-9k{0^!ViPkfqQBpJPX7Q+*2FjM?qLK&$S580kH%3z(R}1K<@4wg|5Ru><$CM|d>|59{fG@XH`}P@dZn zUJGI$<>`#@dJt>G(-q;@L97u^H*k}uJNTBT2h!gLu_8RZz%oy7@EuQIaKEP?au0ym zC3^cK90THWw09uFK@fWq?;wOjAgs4{Fv9U5thaY4!igZPw|5xA$snw^cLc)KL0E6^ zNQ6^CSa0uWgwsG+Z*Kv@H9%Nz?^uL0LHJYec<@^9M6ix`5_p|=GI+gr3Ru@W6>Q?2 z4mS190B`a>3^w!50-JjuMLjJ**mmz6gj<4GYu?8YZUthkdFLVA8pK-jK7nu>5Npl5 z0O7VE)|&SzgxiBy3z3V!L6M8W?;@W8PeeWko{U_IGT(#ncah7$A0te~9GvVs;R=ZNjkfsxq|$DSUs-N*y8a)= z-UQCEtg0V>VQ89RM4ZlsA|UbuMWm^H`5{Zzs!Z25l~gZ`7*ffrs!XSnkfgf0Ktve% zA&!Xr`5+)7BC^RQA_5{Hn~2Enu&OY?h`TtX{Qe=hU%PdpcUq4;|l{@#Yazs29XQ0sSnp6A^Pcq(=s?2&(Y z=W{21>BQGgbnfz$yIgznyLWy1-OgUK`Xe9tk$<{-=^i)6z1TDF_Rjwc|1sEkpMUE4 z*ab(+jlJO1KO6MIQ}2YQ5@|0w_24%t^x{+P4-;C7z2wvm&PS2^(o^3&NhlV3`KjNG zlN*b@>eMv?ort~u)Q|nV(%x{YDzr@OO{aeHt+I_Bd&{XWeLF{|UYO)XngFAoSi-k2UW5POS=5jJ^NVEAS46{lKZKkv__O z_|(&G)DRyHppT#0{wisYirsSRnJ5Fa?bs&`%EUf<>SZq>Ef)LSsn47ubRu@^slR-% zLSH=f*9P5o>Ve1`<-UCCNB>Bnublc>NddmPeCqGMrnGOJy4B+Q?y2X?+hVcrpL#p? zpBeUtr()Q7CKQXm8E2vhoruRx?qvK?l8;#In)nYSEwR`=;*XGbWMc97$0g=WEFGV_ zov{>S_lhsV)8Q&W_crKJvHQkX(md9@6uV#i5M@Q^0r98EJ2J7KiRV$KcShMiIR4S! zCKQW3H2%0}5xR41I{t@f5hoDeZ2VtPM|bgdV)OAw{Jlbp1{Grui+>0^*mptLhsOu+ zfe#X(N5;Q>QlU(I@uw8Z#p}i`#9#9lN?VGb`ZtA2@hOAO#6R^6rLD%_V$gd0dU!)I z=Ii4>Z%{e@gPzj1;-4|-T>KULO1ls*z>kU{Ziqj|pvMGIHGbM?wfNUiAC#-d|IQ#k z{v*gaX}j^Szf_@S{Ld`J#rX3K+K>OGrKJ=9eS;nsPd-LN^yA<8MTHLHo%bqq7=MaE zNAdUmrqZ4eKXJ1{PmIr4>Yo&U&%2cNw|5$5*X1o)Q0F(@J}0{H0G<=vnbE*A;qpeE$6kJtw|v&~xLDFuCW)f6ky6#9w`1 zm3v|Qy=UJ_rwk3uhvKj>D4ULH>y^vd`fE$pk}&wH(MUlV_W zL9dIye@SVtkKcD$p*O@o4$lMT?Tzst823%_A2se<;$JcDTjP&4+S}rX2E8Nxuh(nX zcg8%K zrxm&--mn_{Wc=`NmGr~^KtjY z3kkOGbow38^%9!(}@RLN`E}@*$EACuf%n4R_NY|XZ*85_f1rO zhtP@G{Sr&op6{P{=VO%nfW(C5=w}jV2TFTT;)73C=)s8>eomo>B>vfG4^6z!Xp@Qi zVJ>A_rW5afze2N#HyAXZcu7ZTi;3h(g&vl8^|cB;Jn_|^ROpe3*W6p7OyWqHW zGpLaG8-tb-UofbYs2X%8Q7~vV@kE2x6F+V_x;}y9^^(4F;@evaZ6*HR+RM4bePN$w z>MtZd0KYYs&<%;Z?Wo*i5~Z6IswOTPR7>2pqO^MAn-;=Pd~8=~yNR>Eq);>Q>2E1? zF>%dz6xvVR+n`Ru$K1pBJ}&VOuTiL?rgT(iRb|Q9|7;G!|D6wMw_X&xw{io8N zn79t}8)JD=;>|{Ta^gP?x+(EmNgu|)#KRjZ_q4JSyv;bTPZSJ#L&CSP zZ%nKh^rpmzEta<=-fYlY6R-ZZzV~g3=Nj~m#IvklzBBPegWjEZsX^~eyw#xhB~}c2 ze`3y{4IVpiBq^& zhqd~TiI@GW%6%^JR)cO${ELlTUrhWLPRLO1w#1UrzMS}k(Y}&+yFp(|-1mhV%hwaL z27M#p8}zNjJAO~O-%h;TpxYClHR!vEe>doRiLbA#-1ifI{2vPaAi;firr?K(L#y*x z@)IU^Rq{7X7dVmZ8+0=H0-Ua7h^v!NHt3q<%@*SB$x8;^BYD@dzT?{Dx2*rhlh3mE zCX?6Nd(+8ZviJUY@*dW9@0I-XU(~SoPTtpO_f5XfX!lE=eu#4KpS<)?g&vUX!xx^Z z`kCa$U6uBrp$8{__udLUBzex{9-4fmL6ga!_>yv`lmEv?<=Nz~8FxOpWYA*r zc?LZ!`4xj6p1jdQJTkd*o5qq!PTxNXx{k z$yW#zi`A0f>Z@Em`Bi(bpZuQbD!a)K*gKlZ+w2_|lb^7#`^j%u%$?-5Kc%reF8MCw z_LG&5DD5Em_?IYjn9RIVp`&ENzVX!L zt(Ly0CI8gY_w*#3s-)CzPX5Y2DD;fvYfmZk%;ft&q|mdH11rC0C;!93J}3Fprei)g zc_&NX^OMi}OAYaYyqF3b$#3GlfNEU=ncvG#}s;FviD_$-jv+FU7@!mKQyDzTa!;W z?%R^TXwW;7^Pg7kJCpY@=-tU@S&MjY^0GniOKuwU{^YDdA4q-|p89NmA54DIpbsar zpVRn0ntY%^A5XsMzm#@MvibvsKAF7R|551E$$x#SLZ40k@t-O5kIAPR^tt43TRGpF zyuZyPUrgTgEtR`1`QQzy?V?HYql#O|K@R*ke1v3sQ6@xPRNZR$fYh2p7KTboR#zWzX^rBgRO zK%pN`{pOlN_e%ZBTNS!@s$tN5Q_q}G+Wk^rveE4RsqcS5X%9&K=oc0Gnbe(O6=B{U zl)Aq`4^BPSYT+TNds=BcH1!25jmgv-O*5KKE&Lk8o`}t+J|X#t#pY8l+E&_P06i@A z`uiyD;i(7v3OzD_GO70pHx|pKUUY`sSgerRmYio|OQ{ddl9q{;Qdf&yCUz$En=+PU zVymgayOg`0x~;3w^{EHkSD|uhyQ$Dt>fbEvxzr19QQC#nGo?>wVmGAD{G!qxlggT0 zHMJ`vS0+|VdG@w?>K1#4pGw#}c2nm}u9^CV(JrR$C8d#x?WbZe_ClT zPyL#Vwwc%~Q@>}>t5R1R_cf_smY$r6y)Jc&abKTWH0~Qx7p$D$nEHKt@0(IrTm8Nz zby?mPi@i1Vr;>tL>}{!AgmxnKj?~MfznzG^Gxa)&B^G;k>QPT&s$#MCre15U{g%`N zq&{M?Po`e|8_NB3>bIqYVzJMrcBF)$xut%~xSvbC)u3Bb1DiFznEIn1YS`OSAC&aL zGM4%SOVw9WoekxFEp?MYUr+t}q|&~Tx~8Mhw^HA2EA;Kuk92QoeJd8bD!py7oJe0|v7Ag7rENfSOW$bu zy(axz(uS~dO`kOGJ<>mG+-uW!v676ZKQFC47E7ji^99Q^ot}_36pQ_MI{$K|-79^& zr1V7W-s!hmYr1dx`O*?&vHPWOm0FF(?w|hDPilw|c({nQE zKQt(pp0b)Qq;E3XQu>=8)>umE2U;zhN#81M7n)o8u0~r=zsqRXryu=v4N*?N@A(RC zr9Ug}G!{FT{?Zm{Ct?@UKfA5m8`774SE0wG%l})UYWmMb4w_rK0n0bbzMf8fM7e(Y zMjPdK)6X0zt(ks_K^N0M^{YzTPtU(fp-#GD?d5Ul+hHqZeEsyg%}fXBlctRvrmy;d za*xt)lK3*QC#3K5dD1emC#GK~rJIR8DV?nRt7hv(R~33%`g$vu zr>FnZddkh|uUZ{FBmF}Q`^@yTg?(1~)YmlZv(sG*`<(Po+@`eWrmwl5LeEeCw59$9 z>CInL+6&VkmRapY>_zFjS?Rtweb!3%CF!pi?WO6D8uaq?ccqR_#9o5qsF02cpr?dSDvZ%9APVt!-#J5s;D{n@*~3*veBebmW6z;EW{EAX2=`6u|z zoqRKX^C$lbzlD>3gWuxGkKlLdDZ*0q*&C zxC7*AIAaV`(uky#IKiVjp}SvA3h9 z-+{ls!rwdb_b&Xs8-MS?-+S@**Z6xM{{F^G;j~T4`&;~d0DpgnzYpT?L)cmTF#bM* zUB!>$WY))UqUz%~Pxbfsy9Ixrz)7l4;_p*9A@yneeFlG@#os?*5Ah%I_fObG{2b2b zd>*HbZpGgh@b^XheF=ZJ;SA6}BZXha-@oAREBN~=Qu{Uh{a^fj9e@9dzi;60oA~<{ z{{9Vr-^Sm+O1)RE^_f7`1>CI{u6)S$KU@$N`HXZ{|hm_0jCuTciOt@hC9XY ze8Zg{dg6vVU5~#%Iq?SXPw;%?$=mUF!=1`^ebQB#t8c!leAk<=dgzIpuX^Oko3HvM z;H}sVce>%4+MSC(`lPG=`p0g*>Ymr$eARufz2(lY#S`DszUn*p`+xYm)2SQo^qp&O zxD(+&f&bh)H2F2``dmGA{&0M?zabk!WRGuUjW2j0H|@Wzkh_Mg_??n z0uqJ-Vxa(;^mJ4jNGJ`&qyd@qOjH_3C=JA<0h#n{0L@K!m0qpg-|6)BH#>vcz@M5A zn1Du@lM4Y8&6k2LDySbi^#ATa<{aTlCDyP~P(XcWmCL>t~Vp#{YIyo8C@Z`k# zC^j{O%|@|BB8+~mGbrtMTmC+(-*0TS8-6b;Cv9fZ+lO>{fUMMdjme42QEX}mn~h?N zM8Z4(39Ao?PIvte*63PKFxgnXEs0{1RhXE_ zXBKAWbMuSE>8aV7iHYLu)Kn%jJyV#=&n{#pvf1MFOfEM+F`1n!PUWWNGMUM#OtFwz zC`@{Dke;7eC`{!ir)C!BC#G_l{PfiHe7=yK%+D6G^HWnZnZ;sua&n?rn3$ehoLzv_ zY_>SFIG>*^hBc^t)>}JhwQAcf|FM%^rq`<-ZFD*D^8fBZt?;-(^>oks6$siqs4cD|JAtlT$&2u9C@JdIYnSLKbgu>@q zjanDHEsz-0uOINqsw}k!fX?-r17E>PN1wUgQI{+vFmqr)O@J_?V26bR#4-vfl$nXj z05KUrZcfNZwrv#R__LhPO`$o@&Q4`=ncPest$8{(J+U}3SDc-ho|~SW$j-7s&(F#j6a2<8_Gnq46VLGJUPkCo+ ztpmSufbrC4fSDh<6! zv>;taJdm(xJ`}VlocT z49)d3k-~;#SlB=;IzU>%QQ4`eED)0g6jt7JR0fF2019PhqB1~C1`r0zxfySAdOo{Y z%unTu`NC{wqEMJv$Yy8eCKl)B=Vyu-n+l7wnQU>fFi~8boSRuJ&P*5PW~QfS=jJ90 z)AM28Gc(@&%*4#h1ml}u$QJSwbAYGwi-kfiGc%i?FU~FEJyY3ic5Y#Mab_{QP@F2{ zCJK`a^RtT+nQRzWsk~l|pb?NI47Akmj1Y4(W9>4GPue9L;RxwMlp@V?X1uk{jJ384 zu0f5n!p1g(MmFPJwz@^Ux=5IqwaT7#l&M)Szc^he&SmCjrxtUIQ?ql^EWyltZgvLq z!{X%ZWPUN9UCaZSUO;6PCox@2Ph-+poS9#kn3?tFi}S_F+~m~M;`IDPZhm2AdSPNQ zGcl3Lp=9SXnS5q`egZLPb5oNOg<^hsaeAsyn1Nb0m&?u|f+95i+F){SyW7q5cDE;I zXNPE;yW7W5=8$q*Ey>UT+;TY|axx*94MC~LVKf(_QWdit01)HofNupj%V~0>(>iKl zRG-A9A&QMtcA=~dv4;o@UFn1ZIzo(7AYn=eAg6Qy6s02!&fyD~_UAcI$Cr)G(pn|I zvUGl7&Z}0j5*Re=qL`N2%|Yd;>zA94_a8nN6lNv_rJRP*T!>0J&5ak4B|vh$iJ1|z zcVlvLK6t_8Mu)s$v1d@YKZAOkrYvay~OTQ<%Zpr%;@po1LF6%+Afs zVI{TbEi7cGiYWcu90uvhxyk9N#r(|T>@*fqsHDt7K0kqx8}*i-m|mFAF3h8@7v?9Y zCT23ZVqtnQ$Z}YYiyr!vYd#Zmi_r=S<)w&1lnr)qyucQte?>+CeK%pj$3dBCKu9}EQLKosEFQgw4FYr_Hc zCu9~2)O;!Ht!J;R7S@(m3l(%F!3+$Sowl+t=BkO|(Jt4}vjJ#HMIz2w-9dTv!N)QJ z6=?_~-t=33txs0I+3!Nf4kx&idq5*;gI>+_QKs2$bPf$E*L%L- z2DR^iYF+Yeq0u=2_57U*MtOm&0|&9qk-OwFRtkW6r@c|iRq};0NL*&;_G)b`D|24? zsE^h9X%4{6_O5$Q{ix?ms zo9mlKqI5{hW!7?ql@-XiIa7MhQ1l9L8vag3bLu2iqfY-H9j z9*83JikBlIMoV z(%dn+u9Y)6Hp@bFYprm8qaX;!zm;4m@1g%{kIVZzwS(3`h$S#w>$U;bYt`DjAaAs4 z1DcZoHkvS(a;68&_*C}gOt3NLbtr-@{i7A*m7qa=x%>3-+ z`~*xnP%tJIXNuXG*%>UG=CZlzJT&)(=}D;H#f91V?96mAJ74hTusX_3PGHuZ&(Gv1 z78Vv}FnLeqbGgZEF;|?- zDsY6WT&R{S>zl-uRtu}u)%CLlOpz|q)lxnWBr;hQONMj05=6(z(&`2nWejP>mCO<< zVlA^;Fx#t-gbFGO^m;qM8NO12Tz*wDgx9aF=ax6uK^h%?5hLZ+H%mx-@ZmUAdN)bhj$+Gll zaC22DP(@ZFNVZg2&1{s`itE+Y%z16#B6TjaxmH?RstQtCD^*I+)db-HkS`UBGMr>C zL4&0EpSJ$>_PNy}T3;R8FS{+j=y9o4^fqYD15#P47MS16N-59g3W~PdAon&#kF4Zm z?6LG!vxn-@Cwe@mtGgASYU&Vk{T`nyxOTWr)Zk3lkW_cr1 zS@t%TFO*BU%*we^9vG@tifb5KDXcAl$ssOk;Vnf5J!jNanzOe>th&k=HR~!>jB#VK zE)uciMg$|c>Z4-S9ey!orbogUu3^j;ry@!U763}b%u|HYx$HN0_XbPYBy8t5N~j+g z{kJSwtJAhk!3;JCm1wEX^y-Q;Z$n6FzqacS$!;_aXXyk80|tnukZZqe@1Va&<(G}^ zTywCOVS^irFKC8JWvnA4#yvs;+UYe`u`c3DLqiVJ5RboB+aG=xlcd6oGsLVI3awVN z+cya&WQf2ZLj+glVOt2Z5Hb9RFB~Jf7}x+JVj*e*W$eyFVTiQgpm3EqoOg)(wSDDS z3|x4@#G^E3ZHOSX7nP9hYA7fErtIqtMWx0dB@OQ)42cCb)(>AgN*k(KlXEp=sHIF7;}SCcFto@-8oRG?*A#$hZ|FLk+S28@iTPB*d{fxFdcf3nu1t z1fD;{)}@VGf>M`@>nY5t4jqG?%Eh@WogB+WVLXXEX>1lDYw4nm7%I;Z$8St07Jm6j>BL)Ky(@7`i%yVmVdD3L__?!%F4Wno{|~>$eJJjcv7h z0cE|u0=<}t>95sLkn1_V(PMTMK#+5#wUzayb!Xiwt%v2kz7oM;i`uM^$+nx>0(fjm zt8R^D&}xZ>DnnUN2KKA_*a`0)Wmh*mvq~;w6;aq^Q#ZBT2vAA!uIyH^2riKItxAY# zbAh!Bt;ABbwSm6pVA$%1weOA0Cf11<25c2?DmAoTM;|KJjdg6PFuF<=i#Zz$5V?CV z%_3xOtgI_21+%h#4&=&SuX9+qT=%=QIK%p|yeWmAFG-qKv6R?ET~^EIR+(O1fdJ5z zsr*X&5p#pHPGDh!<+EiE>odW)E;$cs8UHs*=oS?$UUMs4xFWBcrCb@s%Azlp3M=_C zm*p5NxFj#@+J2)%h)GZ=2jMlYpoK4)Rcr(6U=TSvqG5R$&K}LD4lEcQ&txy4@gpiN zpsbjD_&&Z2BWT&nw3{%uhzY(`I|2bs9xp?pxO?RWTC~kIZRaAupkYG}69uT0rODft zZ{E3OEGdyfWOyZ$J0p-w43^XzSThER%M7F0Vbqq$Lm}L-gh;|>TE&8{;^meLxii;o z6qd9vD-KsLLs`+mi*x1WLLo%+!zheT!c~JxH3x$*7Q+aP0;uLUGsQ}`QAd^; zDK^$oEtyh9O)HNsY@+o7gW008wOPonASCRE1t4o?uR+b30mTt${emF}k+O@gV69mw zt~yjE6h*ay8N9HHc1B~_Mg}$LtrieOK`by8uvW<-r&6k{z;c3ufvml>y0le-JqZL3 z5dv_&z`Rvn%WS|HC()y;qS<+f)Sx^@Ii-m-A{POe%Cjg455wT*1sL$l7!ioO9F+-L z2Zl!A=`PDg^RnMMYwPcP?wmm-Kw9+Z)X}Z~l}DdrNS!D}-+;eg-527}rp-AUR5xlp zES?6~d@QwhIxc=LF-z@6v&Yq(M9AF+Xu$QoN=NrB&dC^y<>*Rhm*R@+i-~jY25U!H zLmNaAVPu1dS)mr9^V)fKJ)oG$Kz9(TMl_A``JkDt7mH|t=f&!AUaY71?bY$qIeG6LK?eR*e0x;}T}$&oT<{KeCGT)6`U_rA_Kp)2{spPv3(}78+pFV8+L1ECb_6=xk&@9ofQRi! zsbM?1;5vy2q8(irQY}?HY*iPct;!`4&gX0%4z;{FRI?W5%+X!OkUX}kp@dzz!7wxb zZL7NA9oMS#4ce+MSgX3=U7}NFwJL>+EpK=sV(Ck>lxk?hrYh`~9CfgPO!h{m)!nOk zswXek`iim>77yxs{btR}VGp;rRNLRzxH!6T&5#+uhO&Jy@cYUGU4dN@WejC3G21mS zGmTB_9-cGyoYiO6o)x6E(`+bl#ow*96jZNN+U2l1>pAuSW2nN7{X91J9R@MHgRjlk z1~qA40+0e-46eL_Vx)zkOGTvJ35eorHpEQ;Ia4MqxB@Ud7r%lmbpw#63IfDNu>kM7 z0BFLk?OOe!hE|)R>|HaBq4I3jh26Hu!B}_Iphf$>U|%JzWY=G^*3c_xkpY zwBSe{Fn05a>X)Z&uanfu9rTrm#wN@v>@*q*8DU|;^}WYr3elBSgMm>7^3+rd$eLJ1 z{h)DMJ@+m~@yz26l(F7Ivw-Dg+pBNuI3SZV+{?@ZZF&kGXdyZ^Glb48451>tk?94Y z=O}IjOuoXYbRq&0B7#c*!E20#?HUF}%<=i=wpVT72THN)Q6#9ZMBUrV*CnURjXIqe z{GQ*g`$WvmLP7DdAV}W{KC7HA6=Yi@36&-sfP45`hE@Ce1Jv*UEu?<1-PHFi`EXrs z)?qs7?DlHiJ&@T(ky_4&vQvtPj*(*3lm>{e?zMIduqFlNsD;LY>AR1nBk{X+W|W0- z)Nxn)*B>CF@=?3)721t_2M-omtv4W?+3qM{t{f|%!OL{1)!DAKGA(oigwmrAfl(43 zGzi#ez!cB8HaiDx2a5rnbW{r;%&^%=9ZDk}VU!$Bk2>t456 zA3$kQcBvsF5gs^Ouv%-Qnj7W4+GM_2+XYd}h(lbVUGFqd%3GDnK;N@A<|#k23%{oO)>PK>wms)c%1? z6z+wchM%RsjwSA(D<0S-oQ~-42jjhQIm^_W-C7IInEOrf(;gLp(+{U1bHUp5cdQ|d z%JD#q-=kifL&ac70Kwi82I4*&ZBHm8;}xJFbp5SfQ`@Ht(Yz5Ohu<<3#n;Eg07E7w z7@X^1L$vWzbBP8GnE|SR32>3DEotdvyV#gF8r#w{c#_8$dGu1a zWN8wur_$cpH$IZvIH>!aOY29=`?WgMs)K-gUBAo`pyM|&{pxq>>_ z#+bz_>EWnlFQ9YAMfa??YW+T*-8xcQYes@qwt}vNumEM3>eYV+w^PQut`iUw z3gk-kBG=VU%<6&zHfur>*RHjo!HD0UZVcen7yaJp^>&2lBG|wH4ONCszVB$Vhl2*O z#gT;5Hqt{{6lamMmRbjWZD@JF-Gm(J6&wuQ?p)?EKg?Co(Kub9Fcp^AIsGF#E_gHy zcN78k5!``vDNri6W%>p;9Z>3{V{(}Dqyuv};7L&>q462i#pWB%Ur}!C&6#$CyH{QC zR&m~~=MZKBlU5J(I^NQUxdPDT06KCI1xs%I%)Tv>+xyLB^ccTa-EQVuJyc}FYxZ^T zRtl)Z-iE@hLAyCu!$>0fkF{-8H66(*N6J)dBBHY%1!&BXe{w?CuE(*i$eD7SJ2>^_ zL^9J38hdxZxpFjD6ba9G1R|N4E50eYi9PIc-Fzod?%w;Oy!HDi}bozrjY)GTrQ95#m7_-e?C%A&H@An**ow=^r z50Kd?G8aK)*~|F{YA#wJJHgt}iESa-=x}9@OpOS?1cgK9kwE1I3w>Nng|foO z5EXI|$fmHS-yb5o^A|d;hpgS+4o9PiFcYprB1Z;94^MBLSFAdxN+dlD?k3D3BD7MB z`%d@47=b|p<2;O>#U=_C1Wd$TdPO+`-|3wHWwZ+rncpxMK+o}DTD0>eUO#{^OBq{V zIEhsmW;*{e0w{&+v|$QYc8xfGvij4(uWb%t7~9Mzu@J%BVQw;Sn2IFf(|y z*^lDnM=C!eDKA;+bh^~R_A$P@1;Od)%BU0~r!lx6O)KH9T||qm~-u zG%RCsdw%^Q^}YUHr*({o>+R!#S<>TF(R0Vi(#^-orGD;U{{Rk1ST~GwSN!%kaZQAE ztu)T1ZZJ;8+@8U@DAQ`z`r}-U5xyt1EF8m^CCqp*jN0g3SjUaCM4>x|uD1JQ7~)BC z9K8qof9K#B4m4H0qC`!u$E4u^BY%4^&M4u?NRRhFjI-9T+#IKx;$zFvalV$H`bUj% zi`crv?5pX zyu3jHNfDCEtx!x+A0kH&^23@0Il%0@_Ob-Rt=jfqw7FJU>KH zhvH@*V+8CF`#VdmewH=nLxtqdk2Vteo|vz*kyX?XR_bc)vSDm!A%?3B90SVKQ5YQS zC`1n{vI2;Z=Dr53l--(d1vMDJ6$q9ULDyT26~a5+>knY75~IKl3Dxa`9UA+g)#y}N zKIjQ!Q|&S|KFf{;qno5NGTKQ`jpEQjgQ3vFf)AR5zXOez;|e;f z8C?y>O9H=5j+G)rA`B_)<{=H$q`B0Mz+on)j^IwSAP8q!jc^$jZ%H@p>j2pg46MQu zMiSnMJ>xyvSFtCx51VWDC?NQ~9t#yL?tM*9QF9h>Zbm>3jRK(H>0&J~j_(FAmZ(D8 z<%{<_odIfMS16K{A&ND~VKEZX&WDNpp>T{F@9&C^8Hs(AX7L|KmYy^m19CAGV;+Sh z3E$@V4S|~Siw=w6*^7echPNS7!CZILzy`l{kk2lP_U!Imcm?)Q!S?B z8OZZE1M6|>6hm=q?pAAEd6Sld!7^S&X z(S>S``>qXj#v;2J#xMkr84G+|59I-Evh4d8Ir{5%tjFH6PdW=&fNGuFtqnve zC|_CWEF)$?(I^5KDG6XsW+DK8;no4-(=FU0E;sPddc~}QIsP0r9fg(^{XoDyJrRb< z7JC{(k!pjYianD;8yB(xB8h!bkbV@A=|afW9VbBP)h4#64#EIYT==!i!~6)|hOkD7 zdkF=QJ(|2bkS!!eQt1fD1R2=2XLX<~TR9iGJh0@r-z~MJ82}Gw{3Oam9vjx2p zWEmm5?hJzJ*X6u2p~As3qi}S;ga=8LTBRzFmZ;dCKFo(q5vG6{YU5<8h3V4{rZDS2 zkTU>1G}r|4+PPN%vhYpGUY$8run#>2sc&xe`GC16;?uB-{Z+}D?6r+LH8`&B z8^gvC^=fcTD4yeP4UTz?UxQ>LM<4USJOgq{r!w+;0Gr(GL*Pk+SK!HKhFUCGzM z$)K+9*xA7e>VE&Qw}azBbu=G|h`WPhj`%w`@}@aFI2=U_?d&*@2PeU%oo}_=+A=t# z5ak!zgC4Fl#ngF4F|;=`RWUOz@a7dSS2^{N5;h4v}QiR-5Ukb)$=J}>?I=Z=44E?&@T|ogA;e=wE2bG|y1Clr14<4boO#HAQs+===nm!pO_)mo zEcY)0WWvwwVTT?In~R99jRo%|LUMZ8VBAZKkvzCVa}%g!7!@E3aa(~pjHy_n`WPi( zk_rj()@Ea{7Y08Uq86SmpE!>IEeyAjjj$2hmDq=2L=9fAjl^EohnjQc%0MW3NA_-! z$YCE08V0=vxF>`nIv7I5aaq(O^uStIWsrzblE_6wm=%c06d1UwVc#(tM+9SKi59Id zDD_#d^pue_9q#X7ThWkaKf~ktk_q9KM2Qe^zjhIxC#qh0a0TOjB5sjJPKC`xVfT+4 zVi|Y!1iUCl2qp7;WNDOC`;gFQ2lC+3T%l^y`TluB-o4UBA`UCEorD>{`HM+3rT*~Q zVC+lVX<#;HHac`WCV@>x_66y4NP^}xRu~6?452t5m8Z0>i<%-Q*~GQJG-xEJ< zC)_z~8^~l0HF~2<$!HE`%<+3J04*v~2ym*wvw zH}F<2rNn?w5M$>0ju08^(3xhXMl5WBm=>}#9JBUESfM#BV4$hE0O|xa6pS9*GR{;w z5`twd?ZNQ=2(FWoF&Q{R_b=^N2*+6-g)Zh;BS%r5%8}NB5`^8@rEA<>+S@C%_X0Lc z2-#Tn_jj21QM$v!>^X`jq1t=Bb}^824|u*quGiz?H)vivE}i3}@Rj8u zdu3+6--E-WPJjnJTwN}pIy!8GgvuUvYaLT=kQ6x?WCdF0$vj0}se}|(9u0lUXVrz6 zNyFkbOhc;2Xec$-phklW${dIVn$q_8&OWCCuYva|#JAJhF7vtoq;TO=56B^gYZ4u! zMf-Y3g~WY62;AD?UWK5vKyz>v#0>Mw2+4e(8mNWC0*IirO$c3kp@1xv;kL-uEG$MQ zJt3elzF`X6i3qniUmtWUKE9HHE?_k6NKsmIUtF*;7&cLYB8H_!vx_@n>CD{{3MR8C z3ioE5Lo^;!#g&sQX9rgsMx;OyPShg7?CF>hZji7C3A2F>#GZl-L|Kfmm})CMT(8gB z1r?9oM-ko@JH3EXFx)E;ObR8ygr`Q>kQ>3thyOAxlh7|C^d;=Q=mmRGstz{xA_mpt zRuXfyAxEzS?jF{0wE$WkWo(Mb(Q{geh&y1qa}q*e(uWAuh8?32wj6?G83du%ttJ9u z)zwWvVG7iREg+#~j8Lk5F;D~&x}>5rPr236*CEklXOHCN)_HA5mO0(g%~^sg&Fvl> z{#6j=C=PnK+aO5xntZ@#9k)nhF%1QFAmVvv&=V4cD)@>|D>&jWWLWaXX#FbO-Fy#9B7Tud{O-%IR@7-z z@3>r|Mk5(BT_V7#2nYgolN&~oHaa}_TEtpAACOi`mvLTp@fOE515AhiMl&$t~07`zy)b70(-GG!mf zwk_JrP^3B|?1N8z9wvN2ZJo-bf=iu7aSl2oy~BJ$iCdiI*9KoY03dq)C)?8r2Dn znUq+3d&*KpD9jcOAoSd!ZyaG^U?r(QQ_#jC%^*P#v{z_P7$93h+TNE3UkkFp>b@u- zT^#5tf&E3nttf|9XTs1eF&GS3zF20-Q~Nc$r=UIgURi)bJ;EUVWwW zEe}(iAYHthM7YpmcqWv`Y?p(H%j0Y#XFa?!hC&d^UE~XNv`*~v1A?ajPVR^m3jFM&iq7Zwi6T31UG(zws83r76!9ECaDlFStIl|2E7Ug+yiNoGR&KGaI2Jq z!yn(xQef7(nuU!iB$}in)s4lfSH;XWW4(dy)k;j6$1_e{&0?9veS_itDHM7J(@2jB zGn2iLx9YvYHbd;V+s{3kPsF35&?7^t?4b9!gARst!RRDa8KTfhYM7#Hm0?<`U#zt( zj#aE&jy6&J@Ui5tO{Ebd&}rL^;Qj#qPBEJq~@z{JDC9$7HahX)~hDW$y;#6Y~ z@7?ra)xk3}EsnE>%tVpd2$GE=8NDbV!q)Q`n96#!F=~XsBBgN`o5%-zHxB_rEy6jg zOSD%I)aq6j(K-|!x_J_$GW9fY-#lJqqlpcL4{tQf92yuG32hJK$= z=K9&V;}98fHEz>0!0VL;8e4u8T|;7OtC_RMibpK z3x`YDhf*SkyGy>pOb4SwM?S~x6s2MU57{L&Wn90Y1UWct2N{&Y&`aX5<|H_^lrd$(~y9VLSkDY#Mf$HSlX%36hw39f!GT_i8sj8+U(V2Rfg1KEoI}wa0V+3pIP6T04D7a=KNQ4Z! zLllwekBUSI=%%n5Sph&?S3iz`7>5Z=C_`|U3#%k2x7W28a#*-ZiD&EpJvAu|A+?~? zJzX%e8R82&?iv(K5!-$Pex@OXmT*j`J-6E&Vd<%B9EPQ1ei*{eO!l|hJ?Bx_V5<%# zwrDknNt4}gm=nmz-h6<0Tew*O2Y{*fpljPkw{6XZQnp9u+yMJn2gr_FC;`7>c)RYb zG%rSyllQj|c6Vhg2nxb|7&8nyGB$+_XmhOX;qb2DD^1wqLRp-Tg)u$QCPT*hHoV25 zjfNC6W{7M^t#EHnSGtGrZVee2S6umoMD#{xMEWp+kW+!e1ltW~2AE%evp^Uwio<1QF^PhgoASAgmqPhli6~A*Z&cx6ocXmk4k4d?s@L1c7 z-rs=h+_3vlhh>bdW<26!nWl!S4Ll5Eb)l=+kSxbl)Q>47vSd*iXyKUuLb5iW5ONOe0xwR9G6(|CmH`jSn3Vf?ZL!~9!23TayOWjKd5FPHGu zo_*gX@5(X*9~vC`jtzF9pnJ3K>QmDVc_l1VRr?KTTWuT{!hF)mVc!xhayW#GpBb;U zBT=C#VGV#oAkiC#WH+(N+iAl1%_t-hU^8)qYo&*3fMqlqOieYzM;b7*y3-AQ=qr#t zvgtRA^(wDdkSBE%G_X2O?||CX2Z?1WcYz2M_F;-D?87ul1wl4DN3~Xfl?T2bVk>Mh z!z7I_kl*MW!qyd_`A%auf?{%O@3cCHQ4$U^;;0ZZ!PLtO0u1}FZN4!elrJ6ya2^|n zQC!m&5s+b4lof@rbWmUk8~)-BSr&V{64gO6N`Y7uRpWdZX=Jcbq8T9+8L>M^=CGDj zCSnc%eTB6Xr8d;&tq4oSlu@{=%XL1=s9vH0Ln6*L`%oYSEcI!p$JSXNi$(6ldFSNE z=kFQrwek`w6AfXxnhJ{~8Y*GuLwnt&-x)=f7^Sda?1SEtl)ku!iZHu@1njieM8`Lm zQM)}R_a19H@+i3k;}#61U)D^W;Nm~VPc>hg$y zsn4pH=V|IEwc!9vLexNvgsu%wcxsQ9pbp$kGe(>g)_zp!IBbH z$b}Buhdf8!KRt8u3}V~ZJL+?{N(j~N5QbZK2DoEISSTf`*W!R31h#Ahj-tZA!B9Gi z3Jm|7NP)Ql6{W6pxr|OEaA{v12Vc0*5nQ}lbP9sOhH=1QMxI@a$|@ooFV+XSU>7P2 zT{n*f<&rjnk_(-E162^AR`)OgVbEEJ>RxyvND?(;@s9yPV{ zAhE{Q#5FsI0&+(<62w)O(43wbUPTbxNCeM_8dqIjwa;IQukYY=T_1~8+@An=hxQ*R z`!Xg_6HqS{N2xS-c5t9}zz6GR!^bec0lh;od|DICUHp<~N5?q74-;^#T8SuoEls%` zt{l?Q@yOFl<5*I<1NT3W2wqmWEQ#^?;35`wQ2a1mXj8ZalI<> zBWoLU%wa0U_s!Qq<0-A%aI8%&351SMg5w;U1Tu${K+13uND-ej)QJzc zx`&^B^$@>ESD}NXVJ4{$c5qoDI*}x_Qrne;^7-iI?xXR*&LdWw)UD;3K>>6ft-c#V zz=$JH9NgmSI22NkFXf>iuIu`ELG?yHf;(6MVS_Z^+VvX!K^G6~)=O$&7sfV6KMT9F z4w}HN`*8=bj8lr(jdK=HU7VA^olHKRkROraTmkenBP5x6iadQNmcUtEFpcfQAZJD4 z5LGAxo+U)7+UJLO?C%5a7LM>h)5wSSJWty)&7}bccG{AJDwdl9q0$gl-QU`2;>1#y zOu46t06ML{j5~R5DQ^^gzj*&S8MOITe4mpFj3iM?)h1n|m_ESvK1>mtJm1NZRL1}p ziOVtCwtTeD=rplA5xkk<43)FSEF-x9OwH89dV0nqB;Z=KdWh+epFQZ~HaFfF#UPCU z3c0v$50*bLt*BkyOM4rqYn!vxJJ#dDnjZcS(rCgZ13iw>j=T6pH$zpQZTg2?WUlvw zqNkxoh!E2~_93B=)TKqUKhQQ`_|Xa$-s)mSVPKw&?SJt8eW+1e9OAr5;A$(efv!x4{NG(zKf6Gd%*CgkZ+ zX2sb_Rns-TJ5!@53OdR)7tSy$XYE8$DY1(4!E%p}qNq|_(CUnsFv9lQ0pl1dI;PDa zI3;awF=u1=^MI$yk zf}xfj2qU}Fq>LGnND#9fng9>7qLruxEL&IZ+8TTzXcCwB)MCFE9~xCjdE01#H98l5QVPXrIQ5s~2Xojy0Q$0)392C#nL6R7qBZ$n1(k4u|PL42^RL$3P!4 zDdkEI_u%7XpN6wd5kYh(uGtS_#CT67R$GM}5D8cuxCD{2aFCFmgTh?z752LWY~6t- zt1qi3DI!u`DjZ##SeNqBJOyGE3BYK@>0gE{h2)H#5qot7SOKU`na!2b+R-O<@;2u= zMWbsWr8M!$XKcqQa$wKxeZ?(aZ2pHh3Oc}>*sG#N(?zvEgj?wGy{n+g&>RL#4~%fiwe;|rdYY(#buFAUV-0f*8!Zn*yp2* zCgGv6AVHvsJgUv9vBM)>zw zqL=C89yeM_d8(72Ew+n90+MX3h%q=It#xz_WPxA-(9o=7TwH^A2rbitlnA!1QK8hi zh)FF`RrW8`f#T8|lq>9yxbFL+w+u(h$3xoTj0cypVe%nYOOuW_UZyU0dZL8T$c18` zc#lv_M)ov^WFnM2PDt$H+_oH{h|ssXLalTnG>tk!=vR9WU@W`Lm_1#WeB5DRwtmvQ(C^|+(wj0HPr?~y3) zLh)f>Vgu&iC`~i~Zf~#$V#U2H&%Nz^d1j!(@v|>rF|G{0G2d$f!A-#q4C^nqe}ovI zd}aCqX6Wr;O&*S!zVBdUANK^JnTT%ZH?Xu2FK3{=iy*tX zja&Z#%2Zd-Z9KUdj4q2%8ZmSAu}$nbFI|uK5^>keH9kuh8^aJ8gP}i0l#(5lltdjP zif?f=wxIh)-o;2qNQ`oXBoU6#uyPuTiAp8=PB@fpItq%;?Iez_HbgyVDC;q}jz1t# zaT&vLOH&}Q6kZk(&{*cOgi#OefX)fxI6C4Ov&IL3(843SazJ(#C7S;Nq8h3Ll!?ax z%CRY+RXU>-?yq||-i;;0N)yc+7&Cy43WKEN73EUIZ-j%AG}s6_)IcM2i6Vk)BaINm zKUobjv?p>(vP-Gq;tIH3J?IYN5Q)ZoXy|RZ`=X_n112R|wUTuzKza<-lT~z0=#)QW2P133xC7 zqtz)}7sv{SY$RGqJ1jGl@BpXy#A>jPi?W(pywLB(8AzA(a#@z}7!Bf=QV9&&UVeLb zYk-g#7riyulK{=gJz*G}xQJ7@-q~-ocBiLKIE4E>db{3ZtoGbZ9<+H&RE|L$biT4C|T0!GsGy zh})uA0?LUbfvhy3?8@>nps|RfG^|I01ruM*ZaCfwvbDzf{gzi+!9w-oX{i6fZE*e5 zm%+fw3J%Jsb&TnJRxu&eaMy|6E{GdR-5qWWWV!DrF_-;ptrQ4oe`f(;RcR$%n^$hgCI`aPSMo$Pm#pjWl3^&uBh7S|Dj+egV6$U@Yc4I{iE0uDam>I6R`pT+kABGM7Gx*f85^_CpO zsc!2_fy-ToSa>OcuMQ?lNmGci@MOzQZc`nm3r7EjV|eO!c?<(ZK0+1C$0$+WJ0_}C ziBcPn0#jvk2lq?j&e!2o%2}o^ubv!Yv6^eUekd!s4ACItG{Fs%1!KO)S(@!}I&wWu zL=wh{VxJi&yIhQOG~HOi!9ah7blOZX%+;hG%R*|8r6a+|(k0Eua$K^>_0kA4{^Us6&~cRxno$Q-cV{I2!L58JQfTu~CdhtOm1Ds>|4rxRyhZfiST!gt^J| zN~yl0h$a7ueCFedOljp;db#H8ieZB+9xLIvVSaWw4cLZ=*Tw$CK2~`AWQ-1iEdX6x zanMIysB$T5A4ng81Eh+}(eTXyld06&UKZ+skLR{MH(^@9GGcNLs|2`z7O;f}t}Yy4 zz5v*l2h)^00#1Mnxd73Hgk!;OB}w3u)dnjkY~esKIO$Yt2sEq^r=%IeA<9?i>WH!^ z`4Dj?a?tn447L!6EJ>pS&CL3waT%&HE@7#z5H!OOVP1v^=13Nmkt_y6a8(O~)1NuS zcxqFzZiLELh$B)cSnkqv7UK5O5h??QGAp&ib_AmXS%^ZtgWeV57ohoe4i%?Qq^K@+ zDFR;5*c?=_b>Ry%bZY(f&V2Tk0A zkG_FB)b}+5TxY^bsM1Cx(p3 zH0exYg#IW2)jcH87FSP`-m@od;0E&RaRI_al=@=5GB(PDC1@D=5tNk};RLgPgf>)C zVVsfCF)Ty2dXAw=QSS!qtVkKMZs?N{qBanQ!I5xoOqzraFv^u}$DYF2%t4j3cK9ZI za-iPiISAk|jD;xkiFPUL_29~aksA!8i8{Z^P^f|F6T1e8lXXR_0WV!Z_c1CfY@Ax% z856|&!%&QCy$suV5VM0BpM&9t3CCQA(K;{U?xV*JXJpJF*4;QD@|y_n0n zyAi>dWVNZ#y9xfzJh$nJ-gPjC(-9i?GzcGVZ4rzwiJW`EOPb*+7(JD_;||4y_pEdK z)Xs)SKMf8op?f6uNiz;0clB`+8e9*by5@N>2sHMin9ZKLM`hmG&J=7%8cq+LeQ-=x zN@x^5t<&y^C{Ip)9@L!^U?TbJ$CLbsCwJVvFHdjhuH`p6qUH*JluZP}nFP`N2G!bfnVi^o$(n6{J{p<=p>#-M#J(}Nov#yhDE)@bw-bS!%g zB%?H@eMt=y$Fb05scMX}V5u7=wXAc^*dT^HEW&Z_%*z^Ix(dqBA3IK?X=ki|$tPw4;`_cU%%!5a`|gbB!?#(t%u z2Qp=xXY0obKwU+I;+FX1oKl;emjV0Lh8oI4;4EZ47@al z`(MbB>ZPu%aoov+}nxJ!V}l%vM;P{19K!92UZ zvq^nDPQG0IdFJz1?-?u7KMHa3j*u*SeA{xsTm49O?P&7qG&scP*yV+rE;Vir{XjOzCH%$q2LfIr)3$a`5H!rZ9vS~K>Ahe z+$z}EzW~#heL6~{Mo_3h(vl)%8x}?NIEKwvg*(Vs2zRW&@Euu^kc@I{YSN(-6BrtC zMAqHG79lagwvD4s-uk61ltVAfyX8u!L@VFX8<%D2f?@xTg&;6|deT)uxrT2aXkCcS zDn!*hrFan^OVay``lm-M3D9s{1RRw|rilm_3-S)$naw zPsCh{jh9eXAQmfi*;-FIb{CHe$kzxwqy!5E(^*R!x}X@1a1WY*7_a+sq^hI1UhJjK zTm<-1E=&YL@(^I)&|nXcdBWNOwvZ-4hQZ|3+*J^>HGEh)=vIeKEUN+Sb?{x;R8#)ge?VQrEBf0Vld15V=p7H=8R_BSE;z!B%g?2& z`^Q>mz3cj?lzZs)AuRMtd2Wh>7-VHxjI-BW$p@4xf^7K)N;P1ahC@vuPwi4huptBX zr7<$zb{rW63vwj5${E4e_b{cHKrhLj8WW{P47O-ue5=^xhiqg@7E9tdT{Y}sI^N=9 zWKMY%lPdrRTmFW^MR|zgSRQY43e!!9Z{QH&-r(Sd(dtspPEwRoCmJAOeFUUFqSX`x zq|rJVVj#gmtqd`=UWQ028<6^R-({Ml_@$i3{hDzahu4tFBZ-5a469|^!#H8+FvXcHu+Z8Ob^4%YSnKx(ekbMZ0bqhC_VZ|u?aQ9Tu zwT?Vw2JK@>7{q~AATZlC-@$lMF@}ZP7Q&D*MmHqs^@-sGKP^ovE(#6zwG?sZRKQ_o zR8b@g_rBtn#u*fc_)(m;Q&X6B#5L-Q>VT+37z9rX;BJOJy*(b2J3#C#Bq9T+2S{#o zG({CWkyYG{r?~oCIBJNQ>xC1eqlFW4uy|aMDCy$oy1gn~v$~!XIi7(V#y}DC!63%M zff9R>@Hw3Dphpy)&ZW$uI!K2+P`R=kY{=GnR;29%!bSY8;iQlU-!c5UV|O?@Bll-Z zL|C4Rf1FZa6vFKV91S7Qqg|M1c$G$$CmTuQ!E5Z_?4n5l;hNn1!nf=C?v4C<-wP@ zV|bn&PnR+;;LazNqXM8X%!CaG`$kg_*L5CQk#K6@&|@n?a5jt~(wMG}&2=12>F2S# zgNVc-U41pZU#Nzch(E%w!di~6R68DQ&}tGI<(P}K$*KL(5N;LY%NT~S0C1*>pCU5~ zJN+<)-~EaRbg_$v3}7yhkEls5IW(d-!mP);bLzC^8g~l@)>0c@wual?0usuNWU!N< z-J()t0mg4}I*MNVhd3&@h1?M%#ZziW8TyLwtFJD=iqE@UxM`;9zVvz99g9#n&Khc~ z2E(ur@##9nFT~+%A2KRSxjP!OkDf(447w1dNFfS8IXS*(WEQt9Yk6TmuKLki0oWXm zr&sCSh#iv=ab481v%3gvM3)g&tc89<`+yT*Jz$MtrYeiCz`K&1gmh-cIYbp_;pnh3 z#Fa2Zl&TvpT(mgSgfT?~1CoqY4r7@JI~@C@JVt34>cyr!N_Q(Kj<=C0w2Y#J9hPJT zJ5pLb1n4kUQV$@08Cuj7Y2T7kjMU413$Br2rb3b? zGQ@FK%7nN01zU-Qnh{~U&()#k%j?i3s3o0!hheoU3&tKcQ|LcmYaifXGyULt{N`NG z)(~u+(o}VXa1B;SW`?&m>~$UBj!kkBM3jgix)XMu$MQDhBiAFG3qu@MdN62Q;$Bs- z(Sj?1WV{Ut%lP~>PJ!v6?NuylQHOkS1+7;Oaz|*Za7FDQ3jXR>adMCXqTZl}KpQbg zrVE}ck{g5>DLk)bfRn;Edxq4c-wW(^&dy0PyxYo=5(S~7ki$Pn`IW%DpdfN&ic%Agkf z-5x*9t~7S1CEhfOAyaff$Ji*r(!zBM z8l(zoP0%Q(IFw^V9pX#@cI)h2QKZ^-WZuM#_fZsHWPp}n_JIXVchq{^YtRAB8Hi{Qz=bc%xh}Ji3i**m=Vbz@0|nxGSR}jNV1;ATyE&*?hjJzbZF70Fo`6+p!B$NRkGCIg_Cl!|v?FmuLOcZ92vJ+dJ`%3Q^1 zRK_H`=h$$R6&bD=1&Kp?1cmOW*S%vZ8lZjQvrK$$p-u8>KEed$fQym4z>yN%8w4$o z_EI&9N;zX|z!(A@qQISRPbuG*5{F{J8>0Vz^4=F%P2569g z2ndV8zVIL^hS(PtBVvIic0rKV%8PmQJcN01dIpQ3ps0I>Qb7)*qFsawOpq9iDH&Fv z6qAT9$|hWp3+2cbY*Pu9qEciP7)uFNfn&I$jVW0c^ZTE3@ArM(GYfz$$Vn;txP9-r z=iYnnx#ymH?(;jY*F;U%wEwDHVbvFvQVY0$y5?hW-BP7CZ%(Q`YNHqnhIA3Ha%8;v8cu<+DMjVxy67u?(00(noyyBWH(U)SQwgkv}2ht1`s!=(r973wGtzj zZ84)gwI7EIFeOpj{*~@xIH3VeF35fmi8U2Q~M+w?1Tej>(Zwe!fEk?|M7Mdv@kFt@7 z7X<6;`U2UmXlY;8Wb}e;h@a8RMDv{Q4AVuElJM}K8CKrNxg$soCJ0PY{4)(%332B# zdD~sgiSv(4tf%PyDmL>XUGpWo)n(qPna8I##UU#o6cqF9d*?uFS*-YRKVL~}*rto~EFTWtJ#Xc8 zMk5Yai&jtC+^GA7Zv zCM^%l#sJi1frS*D`^*_C$5ujE|IlJcqiz1qD(#Aag6DGhg{)4`-zN z1QUZilw+s^-dZJyi*^2n;! zUhp_cZp(xfc%4^k-{6YRTkei{cx5-tjK!38QH4-xWiW+_qE1*mK9(X~0?Vtfb=19A z)LE`-_)4HEVawwN%9iajm_K)tg?AC2MHy{b5F4|RoVfcZ7aQRs0V??kUhSC!aABR> zg8c5b*HN&14TWV1p1{VQO#5sbSo@$WoM7a%6}JhMuQxwu#8&KUV`q73$@^6YhzF6| zP6m5gAUJ!%YN>UM=od9yXJ88?-Cni$PS^r(Uaofn!}nRUlx)S>4sB>yE!KL` z`utp2Zit^Mh36jMV2}Rlv1ojo2x=;BS9LVY(CbqU#OI?13oIFkCoag-cMg*!eJG!b#OojQ8g} zcx^XG4U!5ib_yB*GS&BYLo;bk5z$0;Qh#bmmg( zoT-oSRRIfd^IWj}$Qa*q*SbyWpJldB2W`g;TROJFllntfPDRL? zVw^3_>0(P5NYHmMCk+^HwFK)DXDgas^m(rErfc~@9@{~I^D?|cx-jDBAnAdCpdfMu zmy+;FL}J?jGY+3*8EC!Ey2jKTD+soJ>(#lRt-+Wu`hymU3TMLC zMKxH3cP%1dFCx!d9!eAboytQ&C%aiQtxU2ty@Go1@YT|K0xy# z5IZy60^{j3(-Q6rPrcV2j1A}O#JZH)0rJbK2K1-GcyL}C-XLo^@7j|FVu00&zYFX$ zYF$UWZD9b5lV}HRT7=sCv|p6*TBpsDLK~p$hAQC+E_Tj3Tl8J-2UtJ4aCtRNc!q`a zeAa$yCIu{yY&`c<=qiywivj(pU zmaLd%5n!sJv`Y?!8g)QY#sn-E=1!=xlKC*X6411+lLl0H++j$270deJWm;3dyW-EU z&uD=lhlahCPm$8#+|1RYgT}V_HSK~&-7G4#ZeTxrT40S3UxsM#vvG;8>YZ=z+l^ z7b`hhWJ!)6(<~=BZte+lbupRio?!x%y(JhPmopskLFtU~IvCHZ?WU}3iCY1CXMlMv zH-Fr3x+ef^|0wtyj&uGATZ7+%mL)Bl<9Sq9v}7#kz|qI*KpIS7I$)q!zcY^L2ctPl<+ZNR(5qQ zQnz=Q;5c<5D0T$aq))vu!3eRYHG|(C)D3^moI;D%Xe zAwz4T>~k&NO1bc4!;bfxr5}>aOy@($gDg)@SmmL)s`{o5ZQ${2u-FZ`x54-7L`A1< znLSd88)rh}=1b=mRz4_MZL1O_`NObz@TIjJj=hl>>T6$vo_%yZe9^|*n?Vp&mE$3& zkTIKPjz3BJYn_>>Tr5^t2<1u6pe#*=c$0!T7av3jJ;}W^L`mI2?_x_;NJQ;4g9TWe z$O6hfReu(38JbUVlZ~(wVvsdkNK7MPrHq6$>}?>BKd49}q;a{7^rS%w$0W07W$b-| z3~F0?J|{CEHOL+LHW2mb1c7DdO+3~e@pc1MH$+UkIccFOA6#SZh6`d)-|tBg;DZJS zgwIY9r116(4a^bvGXCqnQR}JwF=G39&a+Q)WcY9 zqPT|v7%w`?$jc4w;c|lM!jPvoaR|U}R~I2ni?oFuIovxBI9TR-cG)}|8mvF0U`llStAJT~*p2IkLzXdG)H7*| z@J|!zgFr@ED)`}>Rp@oj3FrY3CU?lc2?Tv11~1L${EJ#GYo9?pHpMMtPql{_+2q0G zN9RMpJINV*eopz%Y5$pLRC7Do29MzNE|ol1pFU5!hca}RIC%AS#avJqC_|7TJ>d8i zjbv_dy`gz-2y&@C_-yOdrFm{niDupG3(+D>HWy*TGW^k5y2>S!L3;WtfEcrF-jo>-Ju z#Jqma)4b^u50B_+HJ;Q~?i~HJU#laxRV<()bzQ{*c3;JO>BW>KrOaLjwV*PhOC&&8kLOTa_Ce=Q^;vqS1N3G_%|2FT*s`pRbT^Fq~5X+5`3aiK%UW=Z%3}rVaEFUvZ z&F2%C09@5aOg4Bb(SE|>ocTpXFn;3H!QeSbv9QgA%?JIP%8aIB^JtahHOyxSOQJW| z`M$AP+vk?%<�Q$QrG!1cj(vNR~%ioVHm)It4uz^t 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 literal 0 HcmV?d00001 diff --git a/bin/log4net.dll b/bin/log4net.dll index ffc57e11254ad9530867b35d15aaf38eb4747d8d..ac06f4c5ac6e48ae2c911ac50d63e124e00634fd 100755 GIT binary patch literal 266240 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

/// Integer containing the data to pack /// Number of bits of the integer to pack + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public void PackBits(int data, int totalCount) { - while (totalCount > 8) - { - PackBitsFromByte((byte)data); - data >>= 8; - totalCount -= 8; - } - if (totalCount > 0) - PackBitsFromByte((byte)data, totalCount); + PackBits((uint)data, totalCount); } /// @@ -120,6 +134,7 @@ public void PackBits(int data, int totalCount) /// /// Unsigned integer containing the data to pack /// Number of bits of the integer to pack + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public void PackBits(uint data, int totalCount) { while (totalCount > 8) @@ -132,6 +147,7 @@ public void PackBits(uint data, int totalCount) PackBitsFromByte((byte)data, totalCount); } + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public void PackBitsFromUInt(uint data) { PackBitsFromByte((byte)data); @@ -140,6 +156,24 @@ public void PackBitsFromUInt(uint data) PackBitsFromByte((byte)(data >> 24)); } + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public void PackBitsFromInt(int data) + { + PackBitsFromUInt((uint)data); + } + + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public void PackBitsFromUShort(ushort data) + { + PackBitsFromByte((byte)data); + PackBitsFromByte((byte)(data >> 8)); + } + + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public void PackBitsFromShort(short data) + { + PackBitsFromUShort((ushort) data); + } /// /// @@ -192,9 +226,50 @@ public void PackFixed(float data, bool isSigned, int intBits, int fracBits) /// public void PackUUID(UUID data) { - byte[] bytes = data.GetBytes(); - for (int i = 0; i < 16; i++) - PackBitsFromByte(bytes[i]); + if (BitConverter.IsLittleEndian) + { + PackBitsFromByte(data.bytea3); + PackBitsFromByte(data.bytea2); + PackBitsFromByte(data.bytea1); + PackBitsFromByte(data.bytea0); + + PackBitsFromByte(data.byteb1); + PackBitsFromByte(data.byteb0); + + PackBitsFromByte(data.bytec1); + PackBitsFromByte(data.bytec0); + + PackBitsFromByte(data.d); + PackBitsFromByte(data.e); + PackBitsFromByte(data.f); + PackBitsFromByte(data.g); + PackBitsFromByte(data.h); + PackBitsFromByte(data.i); + PackBitsFromByte(data.j); + PackBitsFromByte(data.k); + } + else + { + PackBitsFromByte(data.bytea0); + PackBitsFromByte(data.bytea1); + PackBitsFromByte(data.bytea2); + PackBitsFromByte(data.bytea3); + + PackBitsFromByte(data.byteb0); + PackBitsFromByte(data.byteb1); + + PackBitsFromByte(data.bytec0); + PackBitsFromByte(data.bytec1); + + PackBitsFromByte(data.k); + PackBitsFromByte(data.j); + PackBitsFromByte(data.i); + PackBitsFromByte(data.h); + PackBitsFromByte(data.g); + PackBitsFromByte(data.f); + PackBitsFromByte(data.e); + PackBitsFromByte(data.d); + } } /// @@ -289,7 +364,6 @@ public uint UnpackUInt() tmp |= (byte)(UnpackByte() << 24); return tmp; } - public byte UnpackByte() { byte o = Data[bytePos]; @@ -341,7 +415,6 @@ public string UnpackString(int size) bytePos += size; return str; } - public UUID UnpackUUID() { if (bitPos != 0) throw new IndexOutOfRangeException(); @@ -390,7 +463,7 @@ public void PackBitsFromByte(byte inbyte, int count) if (count > 8) //should not happen count = 7; else - count = count - 1; + --count; while (count >= 0) { diff --git a/OpenMetaverse/Capabilities/CapsBase.cs b/OpenMetaverse/Capabilities/CapsBase.cs index bdb049f3..2107c52a 100644 --- a/OpenMetaverse/Capabilities/CapsBase.cs +++ b/OpenMetaverse/Capabilities/CapsBase.cs @@ -34,30 +34,33 @@ namespace OpenMetaverse.Http { - public class TrustAllCertificatePolicy : ICertificatePolicy - { - public bool CheckValidationResult(ServicePoint sp, X509Certificate cert, WebRequest req, int problem) - { - return true; - } - - public static bool TrustAllCertificateHandler(Object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) - { - return true; - } - } - public static class CapsBase { public delegate void OpenWriteEventHandler(HttpWebRequest request); public delegate void DownloadProgressEventHandler(HttpWebRequest request, HttpWebResponse response, int bytesReceived, int totalBytesToReceive); public delegate void RequestCompletedEventHandler(HttpWebRequest request, HttpWebResponse response, byte[] responseData, Exception error); + public static bool ValidateServerCertificate( + object sender, + X509Certificate certificate, + X509Chain chain, + SslPolicyErrors sslPolicyErrors) + { + //if (m_NoVerifyCertChain) + sslPolicyErrors &= ~SslPolicyErrors.RemoteCertificateChainErrors; + + //if (m_NoVerifyCertHostname) + sslPolicyErrors &= ~SslPolicyErrors.RemoteCertificateNameMismatch; + + if (sslPolicyErrors == SslPolicyErrors.None) + return true; + + return false; + } static CapsBase() { - ServicePointManager.CertificatePolicy = new TrustAllCertificatePolicy(); // Even though this will compile on Mono 2.4, it throws a runtime exception - //ServicePointManager.ServerCertificateValidationCallback = TrustAllCertificatePolicy.TrustAllCertificateHandler; + ServicePointManager.ServerCertificateValidationCallback = ValidateServerCertificate; } private class RequestState diff --git a/OpenMetaverse/Imaging/OpenJPEG.cs b/OpenMetaverse/Imaging/OpenJPEG.cs index 37bc4491..71c8c804 100644 --- a/OpenMetaverse/Imaging/OpenJPEG.cs +++ b/OpenMetaverse/Imaging/OpenJPEG.cs @@ -25,14 +25,13 @@ */ using System; -using System.IO; using System.Drawing; using System.Drawing.Imaging; +using System.Reflection; using System.Runtime.InteropServices; namespace OpenMetaverse.Imaging { -#if !NO_UNSAFE /// /// A Wrapper around openjpeg to encode and decode images to and from byte arrays /// @@ -96,73 +95,45 @@ public override string ToString() start_pos, end_ph_pos, end_pos); } } - #endregion JPEG2000 Structs - #region Unmanaged Function Declarations - + static OpenJPEG() + { + DllmapConfigHelper.RegisterAssembly(typeof(OpenJPEG).Assembly); + } + #region Unmanaged Function Declarations // allocate encoded buffer based on length field [System.Security.SuppressUnmanagedCodeSecurity] - [DllImport("openjpeg-dotnet.dll", CallingConvention = CallingConvention.Cdecl)] + [DllImport("openjpeg-dotnet", CallingConvention = CallingConvention.Cdecl)] private static extern bool DotNetAllocEncoded(ref MarshalledImage image); // allocate decoded buffer based on width and height fields [System.Security.SuppressUnmanagedCodeSecurity] - [DllImport("openjpeg-dotnet.dll", CallingConvention = CallingConvention.Cdecl)] + [DllImport("openjpeg-dotnet", CallingConvention = CallingConvention.Cdecl)] private static extern bool DotNetAllocDecoded(ref MarshalledImage image); // free buffers [System.Security.SuppressUnmanagedCodeSecurity] - [DllImport("openjpeg-dotnet.dll", CallingConvention = CallingConvention.Cdecl)] + [DllImport("openjpeg-dotnet", CallingConvention = CallingConvention.Cdecl)] private static extern bool DotNetFree(ref MarshalledImage image); // encode raw to jpeg2000 [System.Security.SuppressUnmanagedCodeSecurity] - [DllImport("openjpeg-dotnet.dll", CallingConvention = CallingConvention.Cdecl)] + [DllImport("openjpeg-dotnet", CallingConvention = CallingConvention.Cdecl)] private static extern bool DotNetEncode(ref MarshalledImage image, bool lossless); // decode jpeg2000 to raw [System.Security.SuppressUnmanagedCodeSecurity] - [DllImport("openjpeg-dotnet.dll", CallingConvention = CallingConvention.Cdecl)] + [DllImport("openjpeg-dotnet", CallingConvention = CallingConvention.Cdecl)] private static extern bool DotNetDecode(ref MarshalledImage image); // decode jpeg2000 to raw, get jpeg2000 file info [System.Security.SuppressUnmanagedCodeSecurity] - [DllImport("openjpeg-dotnet.dll", CallingConvention = CallingConvention.Cdecl)] + [DllImport("openjpeg-dotnet", CallingConvention = CallingConvention.Cdecl)] private static extern bool DotNetDecodeWithInfo(ref MarshalledImage image); - // invoke 64 bit openjpeg calls - [System.Security.SuppressUnmanagedCodeSecurity] - [DllImport("openjpeg-dotnet-x86_64.dll", CallingConvention = CallingConvention.Cdecl)] - private static extern bool DotNetAllocEncoded64(ref MarshalledImage image); - - // allocate decoded buffer based on width and height fields - [System.Security.SuppressUnmanagedCodeSecurity] - [DllImport("openjpeg-dotnet-x86_64.dll", CallingConvention = CallingConvention.Cdecl)] - private static extern bool DotNetAllocDecoded64(ref MarshalledImage image); - - // free buffers - [System.Security.SuppressUnmanagedCodeSecurity] - [DllImport("openjpeg-dotnet-x86_64.dll", CallingConvention = CallingConvention.Cdecl)] - private static extern bool DotNetFree64(ref MarshalledImage image); - - // encode raw to jpeg2000 - [System.Security.SuppressUnmanagedCodeSecurity] - [DllImport("openjpeg-dotnet-x86_64.dll", CallingConvention = CallingConvention.Cdecl)] - private static extern bool DotNetEncode64(ref MarshalledImage image, bool lossless); - - // decode jpeg2000 to raw - [System.Security.SuppressUnmanagedCodeSecurity] - [DllImport("openjpeg-dotnet-x86_64.dll", CallingConvention = CallingConvention.Cdecl)] - private static extern bool DotNetDecode64(ref MarshalledImage image); - - // decode jpeg2000 to raw, get jpeg2000 file info - [System.Security.SuppressUnmanagedCodeSecurity] - [DllImport("openjpeg-dotnet-x86_64.dll", CallingConvention = CallingConvention.Cdecl)] - private static extern bool DotNetDecodeWithInfo64(ref MarshalledImage image); - #endregion Unmanaged Function Declarations - + #endregion /// OpenJPEG is not threadsafe, so this object is used to lock /// during calls into unmanaged code private static object OpenJPEGLock = new object(); @@ -191,9 +162,7 @@ public static byte[] Encode(ManagedImage image, bool lossless) lock (OpenJPEGLock) { - - bool allocSuccess = (IntPtr.Size == 8) ? DotNetAllocDecoded64(ref marshalled) : DotNetAllocDecoded(ref marshalled); - + bool allocSuccess = DotNetAllocDecoded(ref marshalled); if (!allocSuccess) throw new Exception("DotNetAllocDecoded failed"); @@ -210,7 +179,7 @@ public static byte[] Encode(ManagedImage image, bool lossless) if ((image.Channels & ManagedImage.ImageChannels.Bump) != 0) Marshal.Copy(image.Bump, 0, (IntPtr)(marshalled.decoded.ToInt64() + n * 4), n); // codec will allocate output buffer - bool encodeSuccess = (IntPtr.Size == 8) ? DotNetEncode64(ref marshalled, lossless) : DotNetEncode(ref marshalled, lossless); + bool encodeSuccess = DotNetEncode(ref marshalled, lossless); if (!encodeSuccess) throw new Exception("DotNetEncode failed"); @@ -219,10 +188,7 @@ public static byte[] Encode(ManagedImage image, bool lossless) Marshal.Copy(marshalled.encoded, encoded, 0, marshalled.length); // free buffers - if (IntPtr.Size == 8) - DotNetFree64(ref marshalled); - else - DotNetFree(ref marshalled); + DotNetFree(ref marshalled); } return encoded; @@ -285,18 +251,12 @@ public static bool DecodeToImage(byte[] encoded, out ManagedImage managedImage) lock (OpenJPEGLock) { - if (IntPtr.Size == 8) - DotNetAllocEncoded64(ref marshalled); - else - DotNetAllocEncoded(ref marshalled); + DotNetAllocEncoded(ref marshalled); Marshal.Copy(encoded, 0, marshalled.encoded, encoded.Length); // Codec will allocate output buffer - if (IntPtr.Size == 8) - DotNetDecode64(ref marshalled); - else - DotNetDecode(ref marshalled); + DotNetDecode(ref marshalled); int n = marshalled.width * marshalled.height; @@ -350,19 +310,13 @@ public static bool DecodeToImage(byte[] encoded, out ManagedImage managedImage) Logger.Log("Decoded image with unhandled number of components: " + marshalled.components, Helpers.LogLevel.Error); - if (IntPtr.Size == 8) - DotNetFree64(ref marshalled); - else - DotNetFree(ref marshalled); + DotNetFree(ref marshalled); managedImage = null; return false; } - if (IntPtr.Size == 8) - DotNetFree64(ref marshalled); - else - DotNetFree(ref marshalled); + DotNetFree(ref marshalled); } return true; @@ -387,15 +341,12 @@ public static bool DecodeLayerBoundaries(byte[] encoded, out J2KLayerInfo[] laye lock (OpenJPEGLock) { - if (IntPtr.Size == 8) - DotNetAllocEncoded64(ref marshalled); - else - DotNetAllocEncoded(ref marshalled); + DotNetAllocEncoded(ref marshalled); Marshal.Copy(encoded, 0, marshalled.encoded, encoded.Length); // Run the decode - bool decodeSuccess = (IntPtr.Size == 8) ? DotNetDecodeWithInfo64(ref marshalled) : DotNetDecodeWithInfo(ref marshalled); + bool decodeSuccess = DotNetDecodeWithInfo(ref marshalled); if (decodeSuccess) { components = marshalled.components; @@ -500,10 +451,7 @@ public static bool DecodeLayerBoundaries(byte[] encoded, out J2KLayerInfo[] laye } } - if (IntPtr.Size == 8) - DotNetFree64(ref marshalled); - else - DotNetFree(ref marshalled); + DotNetFree(ref marshalled); } return success; @@ -586,5 +534,4 @@ public unsafe static byte[] EncodeFromImage(Bitmap bitmap, bool lossless) return encoded; } } -#endif } diff --git a/OpenMetaverse/Imaging/TGALoader.cs b/OpenMetaverse/Imaging/TGALoader.cs index 7f73f4ff..2da7e357 100644 --- a/OpenMetaverse/Imaging/TGALoader.cs +++ b/OpenMetaverse/Imaging/TGALoader.cs @@ -29,8 +29,6 @@ namespace OpenMetaverse.Imaging { -#if !NO_UNSAFE - /// /// Capability to load TGAs to Bitmap /// @@ -634,6 +632,4 @@ public static System.Drawing.Bitmap LoadTGA(string filename) } } } - -#endif } diff --git a/OpenMetaverse/Login.cs b/OpenMetaverse/Login.cs index ccf9dbcb..2e56b489 100644 --- a/OpenMetaverse/Login.cs +++ b/OpenMetaverse/Login.cs @@ -30,6 +30,7 @@ using System.Threading; using System.IO; using System.Net; +using System.Net.Security; using System.Xml; using System.Security.Cryptography.X509Certificates; using Nwc.XmlRpc; @@ -1063,6 +1064,23 @@ public void AbortLogin() #endregion #region Private Methods + public static bool ValidateServerCertificate( + object sender, + X509Certificate certificate, + X509Chain chain, + SslPolicyErrors sslPolicyErrors) + { + //if (m_NoVerifyCertChain) + sslPolicyErrors &= ~SslPolicyErrors.RemoteCertificateChainErrors; + + //if (m_NoVerifyCertHostname) + sslPolicyErrors &= ~SslPolicyErrors.RemoteCertificateNameMismatch; + + if (sslPolicyErrors == SslPolicyErrors.None) + return true; + + return false; + } private void BeginLogin() { @@ -1112,10 +1130,7 @@ private void BeginLogin() #endregion - // TODO: Allow a user callback to be defined for handling the cert - ServicePointManager.CertificatePolicy = new TrustAllCertificatePolicy(); - // Even though this will compile on Mono 2.4, it throws a runtime exception - //ServicePointManager.ServerCertificateValidationCallback = TrustAllCertificatePolicy.TrustAllCertificateHandler; + ServicePointManager.ServerCertificateValidationCallback = ValidateServerCertificate; if (Client.Settings.USE_LLSD_LOGIN) { diff --git a/OpenMetaverse/Rendering/Rendering.cs b/OpenMetaverse/Rendering/Rendering.cs index 4c662e5a..f0ca7502 100644 --- a/OpenMetaverse/Rendering/Rendering.cs +++ b/OpenMetaverse/Rendering/Rendering.cs @@ -303,20 +303,14 @@ public static bool TryDecodeFromAsset(Primitive prim, AssetMesh meshAsset, Detai // Decode each individual face if (subMeshOsd is OSDMap) { - OSDMap subMeshMap = (OSDMap)subMeshOsd; - - // As per http://wiki.secondlife.com/wiki/Mesh/Mesh_Asset_Format, some Mesh Level - // of Detail Blocks (maps) contain just a NoGeometry key to signal there is no - // geometry for this submesh. - if (subMeshMap.ContainsKey("NoGeometry") && ((OSDBoolean)subMeshMap["NoGeometry"])) - continue; - Face oface = new Face(); oface.ID = faceNr; oface.Vertices = new List(); oface.Indices = new List(); oface.TextureFace = prim.Textures.GetFace((uint)faceNr); + OSDMap subMeshMap = (OSDMap)subMeshOsd; + Vector3 posMax; Vector3 posMin; diff --git a/OpenMetaverseTypes/Color4.cs b/OpenMetaverseTypes/Color4.cs index a3432e8b..be081432 100644 --- a/OpenMetaverseTypes/Color4.cs +++ b/OpenMetaverseTypes/Color4.cs @@ -69,9 +69,7 @@ public Color4(float r, float g, float b, float a) // Quick check to see if someone is doing something obviously wrong // like using float values from 0.0 - 255.0 if (r > 1f || g > 1f || b > 1f || a > 1f) - throw new ArgumentException( - String.Format("Attempting to initialize Color4 with out of range values <{0},{1},{2},{3}>", - r, g, b, a)); + throw new ArgumentException($"Attempting to initialize Color4 with out of range values <{r},{g},{b},{a}>"); // Valid range is from 0.0 to 1.0 R = Utils.Clamp(r, 0f, 1f); @@ -282,8 +280,8 @@ public float GetHue() { const float HUE_MAX = 360f; - float max = Math.Max(Math.Max(R, G), B); - float min = Math.Min(Math.Min(R, B), B); + float max = MathF.Max(MathF.Max(R, G), B); + float min = MathF.Min(MathF.Min(R, B), B); if (max == min) { @@ -441,12 +439,12 @@ public static Color4 Lerp(Color4 value1, Color4 value2, float amount) public override string ToString() { - return String.Format(Utils.EnUsCulture, "<{0}, {1}, {2}, {3}>", R, G, B, A); + return String.Format(Utils.EnUsCulture, $"<{R}, {G}, {B}, {A}>"); } public string ToRGBString() { - return String.Format(Utils.EnUsCulture, "<{0}, {1}, {2}>", R, G, B); + return String.Format(Utils.EnUsCulture, $"<{R}, {G}, {B}>"); } public override bool Equals(object obj) @@ -478,7 +476,7 @@ public override int GetHashCode() return !(lhs == rhs); } - public static Color4 operator +(Color4 lhs, Color4 rhs) + public static Color4 operator +(Color4 lhs, in Color4 rhs) { lhs.R += rhs.R; lhs.G += rhs.G; @@ -489,7 +487,7 @@ public override int GetHashCode() return lhs; } - public static Color4 operator -(Color4 lhs, Color4 rhs) + public static Color4 operator -(Color4 lhs, in Color4 rhs) { lhs.R -= rhs.R; lhs.G -= rhs.G; @@ -500,7 +498,7 @@ public override int GetHashCode() return lhs; } - public static Color4 operator *(Color4 lhs, Color4 rhs) + public static Color4 operator *(Color4 lhs, in Color4 rhs) { lhs.R *= rhs.R; lhs.G *= rhs.G; @@ -514,9 +512,9 @@ public override int GetHashCode() #endregion Operators /// A Color4 with zero RGB values and fully opaque (alpha 1.0) - public readonly static Color4 Black = new Color4(0f, 0f, 0f, 1f); + public readonly static Color4 Black = new(0f, 0f, 0f, 1f); /// A Color4 with full RGB values (1.0) and fully opaque (alpha 1.0) - public readonly static Color4 White = new Color4(1f, 1f, 1f, 1f); + public readonly static Color4 White = new(1f, 1f, 1f, 1f); } } diff --git a/OpenMetaverseTypes/Matrix3x3.cs b/OpenMetaverseTypes/Matrix3x3.cs index 4ffff538..a807808b 100644 --- a/OpenMetaverseTypes/Matrix3x3.cs +++ b/OpenMetaverseTypes/Matrix3x3.cs @@ -108,7 +108,7 @@ public Matrix3x3(float roll, float pitch, float yaw) this = CreateFromEulers(roll, pitch, yaw); } - public Matrix3x3( Matrix3x3 m) + public Matrix3x3(Matrix3x3 m) { M11 = m.M11; M12 = m.M12; @@ -157,25 +157,25 @@ public float Trace() /// Z euler angle public void GetEulerAngles(out float roll, out float pitch, out float yaw) { - double angleX, angleY, angleZ; - double cx, cy, cz; // cosines - double sx, sz; // sines + float angleX, angleY, angleZ; + float cx, cy, cz; // cosines + float sx, sz; // sines - angleY = Math.Asin(Utils.Clamp(M13, -1f, 1f)); - cy = Math.Cos(angleY); + angleY = MathF.Asin(Utils.Clamp(M13, -1f, 1f)); + cy = MathF.Cos(angleY); - if (Math.Abs(cy) > 0.005f) + if (MathF.Abs(cy) > 0.005f) { // No gimbal lock cx = M33 / cy; sx = (-M23) / cy; - angleX = (float)Math.Atan2(sx, cx); + angleX = MathF.Atan2(sx, cx); cz = M11 / cy; sz = (-M12) / cy; - angleZ = (float)Math.Atan2(sz, cz); + angleZ = MathF.Atan2(sz, cz); } else { @@ -185,13 +185,13 @@ public void GetEulerAngles(out float roll, out float pitch, out float yaw) cz = M22; sz = M21; - angleZ = Math.Atan2(sz, cz); + angleZ = MathF.Atan2(sz, cz); } // Return only positive angles in [0,360] - if (angleX < 0) angleX += 360d; - if (angleY < 0) angleY += 360d; - if (angleZ < 0) angleZ += 360d; + if (angleX < 0) angleX += 360f; + if (angleY < 0) angleY += 360f; + if (angleZ < 0) angleZ += 360f; roll = (float)angleX; pitch = (float)angleY; @@ -209,7 +209,7 @@ public Quaternion GetQuaternion() if (trace > Single.Epsilon) { - float s = 0.5f / (float)Math.Sqrt(trace); + float s = 0.5f / MathF.Sqrt(trace); quat.X = (M32 - M23) * s; quat.Y = (M13 - M31) * s; @@ -220,7 +220,7 @@ public Quaternion GetQuaternion() { if (M11 > M22 && M11 > M33) { - float s = 2.0f * (float)Math.Sqrt(1.0f + M11 - M22 - M33); + float s = 2.0f * MathF.Sqrt(1.0f + M11 - M22 - M33); quat.X = 0.25f * s; quat.Y = (M12 + M21) / s; @@ -229,7 +229,7 @@ public Quaternion GetQuaternion() } else if (M22 > M33) { - float s = 2.0f * (float)Math.Sqrt(1.0f + M22 - M11 - M33); + float s = 2.0f * MathF.Sqrt(1.0f + M22 - M11 - M33); quat.X = (M12 + M21) / s; quat.Y = 0.25f * s; @@ -238,7 +238,7 @@ public Quaternion GetQuaternion() } else { - float s = 2.0f * (float)Math.Sqrt(1.0f + M33 - M11 - M22); + float s = 2.0f * MathF.Sqrt(1.0f + M33 - M11 - M22); quat.X = (M13 + M31) / s; quat.Y = (M23 + M32) / s; @@ -252,9 +252,9 @@ public Quaternion GetQuaternion() public bool Decompose(out Vector3 scale, out Quaternion rotation) { - float sx = (float)Math.Sqrt(M11 * M11 + M12 * M12 + M13 * M13); - float sy = (float)Math.Sqrt(M21 * M21 + M22 * M22 + M23 * M23); - float sz = (float)Math.Sqrt(M31 * M31 + M32 * M32 + M33 * M33); + float sx = MathF.Sqrt(M11 * M11 + M12 * M12 + M13 * M13); + float sy = MathF.Sqrt(M21 * M21 + M22 * M22 + M23 * M23); + float sz = MathF.Sqrt(M31 * M31 + M32 * M32 + M33 * M33); scale = new Vector3(sx, sy, sz); if (sx == 0.0 || sy == 0.0 || sz == 0.0) @@ -276,7 +276,7 @@ public bool Decompose(out Vector3 scale, out Quaternion rotation) #region Static Methods - public static Matrix3x3 Add( Matrix3x3 matrix1, Matrix3x3 matrix2) + public static Matrix3x3 Add(Matrix3x3 matrix1, in Matrix3x3 matrix2) { return new Matrix3x3( matrix1.M11 + matrix2.M11, @@ -299,8 +299,8 @@ public static Matrix3x3 CreateFromAxisAngle(Vector3 axis, float angle) float x = axis.X; float y = axis.Y; float z = axis.Z; - float sin = (float)Math.Sin(angle); - float cos = (float)Math.Cos(angle); + float sin = MathF.Sin(angle); + float cos = MathF.Cos(angle); float xx = x * x; float yy = y * y; float zz = z * z; @@ -331,12 +331,12 @@ public static Matrix3x3 CreateFromAxisAngle(Vector3 axis, float angle) /// Z euler angle in radians public static Matrix3x3 CreateFromEulers(float roll, float pitch, float yaw) { - float a = (float)Math.Cos(roll); - float b = (float)Math.Sin(roll); - float c = (float)Math.Cos(pitch); - float d = (float)Math.Sin(pitch); - float e = (float)Math.Cos(yaw); - float f = (float)Math.Sin(yaw); + float a = MathF.Cos(roll); + float b = MathF.Sin(roll); + float c = MathF.Cos(pitch); + float d = MathF.Sin(pitch); + float e = MathF.Cos(yaw); + float f = MathF.Sin(yaw); float ad = a * d; float bd = b * d; @@ -388,8 +388,8 @@ public static Matrix3x3 CreateFromQuaternion(Quaternion rot) public static Matrix3x3 CreateRotationX(float radians) { - float cos = (float)Math.Cos(radians); - float sin = (float)Math.Sin(radians); + float cos = MathF.Cos(radians); + float sin = MathF.Sin(radians); return new Matrix3x3( 1f, 0f, 0f, @@ -400,8 +400,8 @@ public static Matrix3x3 CreateRotationX(float radians) public static Matrix3x3 CreateRotationY(float radians) { - float cos = (float)Math.Cos(radians); - float sin = (float)Math.Sin(radians); + float cos = MathF.Cos(radians); + float sin = MathF.Sin(radians); return new Matrix3x3( cos, 0f, -sin, @@ -412,8 +412,8 @@ public static Matrix3x3 CreateRotationY(float radians) public static Matrix3x3 CreateRotationZ(float radians) { - float cos = (float)Math.Cos(radians); - float sin = (float)Math.Sin(radians); + float cos = MathF.Cos(radians); + float sin = MathF.Sin(radians); return new Matrix3x3( cos, sin, 0f, @@ -431,7 +431,7 @@ public static Matrix3x3 CreateScale(Vector3 scale) ); } - public static Matrix3x3 Divide( Matrix3x3 matrix1, Matrix3x3 matrix2) + public static Matrix3x3 Divide(Matrix3x3 matrix1, Matrix3x3 matrix2) { return new Matrix3x3( matrix1.M11 / matrix2.M11, @@ -448,7 +448,7 @@ public static Matrix3x3 Divide( Matrix3x3 matrix1, Matrix3x3 matrix2) ); } - public static Matrix3x3 Divide( Matrix3x3 matrix1, float divider) + public static Matrix3x3 Divide(Matrix3x3 matrix1, float divider) { float oodivider = 1f / divider; return new Matrix3x3( @@ -466,7 +466,7 @@ public static Matrix3x3 Divide( Matrix3x3 matrix1, float divider) ); } - public static Matrix3x3 Lerp( Matrix3x3 matrix1, Matrix3x3 matrix2, float amount) + public static Matrix3x3 Lerp(Matrix3x3 matrix1, Matrix3x3 matrix2, float amount) { return new Matrix3x3( matrix1.M11 + ((matrix2.M11 - matrix1.M11) * amount), @@ -483,7 +483,7 @@ public static Matrix3x3 Lerp( Matrix3x3 matrix1, Matrix3x3 matrix2, float amou ); } - public static Matrix3x3 Multiply( Matrix3x3 matrix1, Matrix3x3 matrix2) + public static Matrix3x3 Multiply(Matrix3x3 matrix1, Matrix3x3 matrix2) { return new Matrix3x3( matrix1.M11 * matrix2.M11 + matrix1.M12 * matrix2.M21 + matrix1.M13 * matrix2.M31, @@ -500,7 +500,7 @@ public static Matrix3x3 Multiply( Matrix3x3 matrix1, Matrix3x3 matrix2) ); } - public static Matrix3x3 Multiply( Matrix3x3 matrix1, float scaleFactor) + public static Matrix3x3 Multiply(Matrix3x3 matrix1, float scaleFactor) { Matrix3x3 matrix; matrix.M11 = matrix1.M11 * scaleFactor; @@ -518,7 +518,7 @@ public static Matrix3x3 Multiply( Matrix3x3 matrix1, float scaleFactor) return matrix; } - public static Matrix3x3 Negate( Matrix3x3 matrix) + public static Matrix3x3 Negate(Matrix3x3 matrix) { return new Matrix3x3( -matrix.M11, -matrix.M12, -matrix.M13, @@ -527,7 +527,7 @@ public static Matrix3x3 Negate( Matrix3x3 matrix) ); } - public static Matrix3x3 Subtract( Matrix3x3 matrix1, Matrix3x3 matrix2) + public static Matrix3x3 Subtract(Matrix3x3 matrix1, Matrix3x3 matrix2) { return new Matrix3x3( matrix1.M11 - matrix2.M11, @@ -544,7 +544,7 @@ public static Matrix3x3 Subtract( Matrix3x3 matrix1, Matrix3x3 matrix2) ); } - public static Matrix3x3 Transform( Matrix3x3 value, Quaternion rotation) + public static Matrix3x3 Transform(Matrix3x3 value, Quaternion rotation) { float x2 = rotation.X + rotation.X; float y2 = rotation.Y + rotation.Y; @@ -598,20 +598,20 @@ public static Matrix3x3 Inverse3x3(Matrix3x3 matrix) return (Adjoint3x3(matrix) / matrix.Determinant3x3()); } - public static Matrix3x3 Adjoint3x3( Matrix3x3 matrix) + public static Matrix3x3 Adjoint3x3(Matrix3x3 matrix) { Matrix3x3 adjointMatrix = new Matrix3x3(); for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) - adjointMatrix[i,j] = (float)(Math.Pow(-1, i + j) * (Minor(matrix, i, j).Determinant3x3())); + adjointMatrix[i,j] = MathF.Pow(-1, i + j) * (Minor(matrix, i, j).Determinant3x3()); } adjointMatrix = Transpose(adjointMatrix); return adjointMatrix; } - public static Matrix3x3 Inverse( Matrix3x3 matrix) + public static Matrix3x3 Inverse(Matrix3x3 matrix) { if (matrix.Determinant() == 0f) throw new ArgumentException("Singular matrix inverse not possible"); @@ -619,13 +619,13 @@ public static Matrix3x3 Inverse( Matrix3x3 matrix) return (Adjoint(matrix) / matrix.Determinant()); } - public static Matrix3x3 Adjoint( Matrix3x3 matrix) + public static Matrix3x3 Adjoint(Matrix3x3 matrix) { - Matrix3x3 adjointMatrix = new Matrix3x3(); + Matrix3x3 adjointMatrix = new(); for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) - adjointMatrix[i,j] = (float)(Math.Pow(-1, i + j) * ((Minor(matrix, i, j)).Determinant3x3())); + adjointMatrix[i,j] = MathF.Pow(-1, i + j) * ((Minor(matrix, i, j)).Determinant3x3()); } adjointMatrix = Transpose(adjointMatrix); @@ -634,7 +634,7 @@ public static Matrix3x3 Adjoint( Matrix3x3 matrix) public static Matrix3x3 Minor(Matrix3x3 matrix, int row, int col) { - Matrix3x3 minor = new Matrix3x3(); + Matrix3x3 minor = new(); int m = 0, n = 0; for (int i = 0; i < 3; i++) @@ -694,47 +694,47 @@ public override string ToString() #region Operators - public static bool operator ==( Matrix3x3 left, Matrix3x3 right) + public static bool operator ==(Matrix3x3 left, Matrix3x3 right) { return left.Equals(right); } - public static bool operator !=( Matrix3x3 left, Matrix3x3 right) + public static bool operator !=(Matrix3x3 left, Matrix3x3 right) { return !left.Equals(right); } - public static Matrix3x3 operator +( Matrix3x3 left, Matrix3x3 right) + public static Matrix3x3 operator +(Matrix3x3 left, Matrix3x3 right) { return Add(left, right); } - public static Matrix3x3 operator -( Matrix3x3 matrix) + public static Matrix3x3 operator -(Matrix3x3 matrix) { return Negate(matrix); } - public static Matrix3x3 operator -( Matrix3x3 left, Matrix3x3 right) + public static Matrix3x3 operator -(Matrix3x3 left, Matrix3x3 right) { return Subtract(left, right); } - public static Matrix3x3 operator *( Matrix3x3 left, Matrix3x3 right) + public static Matrix3x3 operator *(Matrix3x3 left, Matrix3x3 right) { return Multiply(left, right); } - public static Matrix3x3 operator *( Matrix3x3 left, float scalar) + public static Matrix3x3 operator *(Matrix3x3 left, float scalar) { return Multiply(left, scalar); } - public static Matrix3x3 operator /( Matrix3x3 left, Matrix3x3 right) + public static Matrix3x3 operator /(Matrix3x3 left, Matrix3x3 right) { return Divide(left, right); } - public static Matrix3x3 operator /( Matrix3x3 matrix, float divider) + public static Matrix3x3 operator /(Matrix3x3 matrix, float divider) { return Divide(matrix, divider); } @@ -875,10 +875,10 @@ public Vector3 this[int row] #endregion Operators /// A 3x3 matrix containing all zeroes - public static readonly Matrix3x3 Zero = new Matrix3x3(); + public static readonly Matrix3x3 Zero = new(); /// A 3x3 identity matrix - public static readonly Matrix3x3 Identity = new Matrix3x3( + public static readonly Matrix3x3 Identity = new( 1f, 0f, 0f, 0f, 1f, 0f, 0f, 0f, 1f); diff --git a/OpenMetaverseTypes/Matrix4.cs b/OpenMetaverseTypes/Matrix4.cs index a7f3f145..18d2efe1 100644 --- a/OpenMetaverseTypes/Matrix4.cs +++ b/OpenMetaverseTypes/Matrix4.cs @@ -185,25 +185,25 @@ public float Trace() /// Z euler angle public void GetEulerAngles(out float roll, out float pitch, out float yaw) { - double angleX, angleY, angleZ; - double cx, cy, cz; // cosines - double sx, sz; // sines + float angleX, angleY, angleZ; + float cx, cy, cz; // cosines + float sx, sz; // sines - angleY = Math.Asin(Utils.Clamp(M13, -1f, 1f)); - cy = Math.Cos(angleY); + angleY = MathF.Asin(Utils.Clamp(M13, -1f, 1f)); + cy = MathF.Cos(angleY); - if (Math.Abs(cy) > 0.005f) + if (MathF.Abs(cy) > 0.005f) { // No gimbal lock cx = M33 / cy; sx = (-M23) / cy; - angleX = (float)Math.Atan2(sx, cx); + angleX = MathF.Atan2(sx, cx); cz = M11 / cy; sz = (-M12) / cy; - angleZ = (float)Math.Atan2(sz, cz); + angleZ = MathF.Atan2(sz, cz); } else { @@ -213,17 +213,17 @@ public void GetEulerAngles(out float roll, out float pitch, out float yaw) cz = M22; sz = M21; - angleZ = Math.Atan2(sz, cz); + angleZ = MathF.Atan2(sz, cz); } // Return only positive angles in [0,360] - if (angleX < 0) angleX += 360d; - if (angleY < 0) angleY += 360d; - if (angleZ < 0) angleZ += 360d; + if (angleX < 0) angleX += 360f; + if (angleY < 0) angleY += 360f; + if (angleZ < 0) angleZ += 360f; - roll = (float)angleX; - pitch = (float)angleY; - yaw = (float)angleZ; + roll = angleX; + pitch = angleY; + yaw = angleZ; } /// @@ -237,7 +237,7 @@ public Quaternion GetQuaternion() if (trace > Single.Epsilon) { - float s = 0.5f / (float)Math.Sqrt(trace); + float s = 0.5f / MathF.Sqrt(trace); quat.X = (M32 - M23) * s; quat.Y = (M13 - M31) * s; @@ -248,7 +248,7 @@ public Quaternion GetQuaternion() { if (M11 > M22 && M11 > M33) { - float s = 2.0f * (float)Math.Sqrt(1.0f + M11 - M22 - M33); + float s = 2.0f * MathF.Sqrt(1.0f + M11 - M22 - M33); quat.X = 0.25f * s; quat.Y = (M12 + M21) / s; @@ -257,7 +257,7 @@ public Quaternion GetQuaternion() } else if (M22 > M33) { - float s = 2.0f * (float)Math.Sqrt(1.0f + M22 - M11 - M33); + float s = 2.0f * MathF.Sqrt(1.0f + M22 - M11 - M33); quat.X = (M12 + M21) / s; quat.Y = 0.25f * s; @@ -266,7 +266,7 @@ public Quaternion GetQuaternion() } else { - float s = 2.0f * (float)Math.Sqrt(1.0f + M33 - M11 - M22); + float s = 2.0f * MathF.Sqrt(1.0f + M33 - M11 - M22); quat.X = (M13 + M31) / s; quat.Y = (M23 + M32) / s; @@ -286,9 +286,9 @@ public bool Decompose(out Vector3 scale, out Quaternion rotation, out Vector3 tr float ys = (Math.Sign(M21 * M22 * M23 * M24) < 0) ? -1 : 1; float zs = (Math.Sign(M31 * M32 * M33 * M34) < 0) ? -1 : 1; - xs *= (float)Math.Sqrt(M11 * M11 + M12 * M12 + M13 * M13); - ys *= (float)Math.Sqrt(M21 * M21 + M22 * M22 + M23 * M23); - zs *= (float)Math.Sqrt(M31 * M31 + M32 * M32 + M33 * M33); + xs *= MathF.Sqrt(M11 * M11 + M12 * M12 + M13 * M13); + ys *= MathF.Sqrt(M21 * M21 + M22 * M22 + M23 * M23); + zs *= MathF.Sqrt(M31 * M31 + M32 * M32 + M33 * M33); scale = new Vector3(xs, ys, zs); @@ -343,8 +343,8 @@ public static Matrix4 CreateFromAxisAngle(Vector3 axis, float angle) float x = axis.X; float y = axis.Y; float z = axis.Z; - float sin = (float)Math.Sin(angle); - float cos = (float)Math.Cos(angle); + float sin = MathF.Sin(angle); + float cos = MathF.Cos(angle); float xx = x * x; float yy = y * y; float zz = z * z; @@ -386,12 +386,12 @@ public static Matrix4 CreateFromEulers(float roll, float pitch, float yaw) float a, b, c, d, e, f; float ad, bd; - a = (float)Math.Cos(roll); - b = (float)Math.Sin(roll); - c = (float)Math.Cos(pitch); - d = (float)Math.Sin(pitch); - e = (float)Math.Cos(yaw); - f = (float)Math.Sin(yaw); + a = MathF.Cos(roll); + b = MathF.Sin(roll); + c = MathF.Cos(pitch); + d = MathF.Sin(pitch); + e = MathF.Cos(yaw); + f = MathF.Sin(yaw); ad = a * d; bd = b * d; @@ -491,8 +491,8 @@ public static Matrix4 CreateRotationX(float radians) { Matrix4 matrix; - float cos = (float)Math.Cos(radians); - float sin = (float)Math.Sin(radians); + float cos = MathF.Cos(radians); + float sin = MathF.Sin(radians); matrix.M11 = 1f; matrix.M12 = 0f; @@ -521,8 +521,8 @@ public static Matrix4 CreateRotationY(float radians) { Matrix4 matrix; - float cos = (float)Math.Cos(radians); - float sin = (float)Math.Sin(radians); + float cos = MathF.Cos(radians); + float sin = MathF.Sin(radians); matrix.M11 = cos; matrix.M12 = 0f; @@ -551,8 +551,8 @@ public static Matrix4 CreateRotationZ(float radians) { Matrix4 matrix; - float cos = (float)Math.Cos(radians); - float sin = (float)Math.Sin(radians); + float cos = MathF.Cos(radians); + float sin = MathF.Sin(radians); matrix.M11 = cos; matrix.M12 = sin; @@ -933,7 +933,7 @@ public static Matrix4 Adjoint3x3(Matrix4 matrix) for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) - adjointMatrix[i,j] = (float)(Math.Pow(-1, i + j) * (Minor(matrix, i, j).Determinant3x3())); + adjointMatrix[i,j] = MathF.Pow(-1, i + j) * (Minor(matrix, i, j).Determinant3x3()); } adjointMatrix = Transpose(adjointMatrix); @@ -954,7 +954,7 @@ public static Matrix4 Adjoint(Matrix4 matrix) for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) - adjointMatrix[i,j] = (float)(Math.Pow(-1, i + j) * ((Minor(matrix, i, j)).Determinant3x3())); + adjointMatrix[i,j] = MathF.Pow(-1, i + j) * ((Minor(matrix, i, j)).Determinant3x3()); } adjointMatrix = Transpose(adjointMatrix); @@ -1260,7 +1260,7 @@ public Vector4 this[int row] public static readonly Matrix4 Zero = new Matrix4(); /// A 4x4 identity matrix - public static readonly Matrix4 Identity = new Matrix4( + public static readonly Matrix4 Identity = new( 1f, 0f, 0f, 0f, 0f, 1f, 0f, 0f, 0f, 0f, 1f, 0f, diff --git a/OpenMetaverseTypes/OSUTF8Constants.cs b/OpenMetaverseTypes/OSUTF8Constants.cs index 5840a8f8..25213dd3 100644 --- a/OpenMetaverseTypes/OSUTF8Constants.cs +++ b/OpenMetaverseTypes/OSUTF8Constants.cs @@ -130,9 +130,9 @@ public static class osUTF8Const public static readonly byte[] XMLelement_sale_info_Mid = osUTF8.GetASCIIBytes("sale_type"); public static readonly byte[] XMLelement_sale_info_End = osUTF8.GetASCIIBytes(""); - public static readonly byte[] OSUTF8null = osUTF8.GetASCIIBytes("null"); - public static readonly byte[] OSUTF8true = osUTF8.GetASCIIBytes("true"); - public static readonly byte[] OSUTF8false = osUTF8.GetASCIIBytes("false"); + public static readonly byte[] OSUTF8null = { (byte)'n', (byte)'u', (byte)'l', (byte)'l' }; + public static readonly byte[] OSUTF8true = { (byte)'t', (byte)'r', (byte)'u', (byte)'e' }; + public static readonly byte[] OSUTF8false = { (byte)'f', (byte)'a', (byte)'l', (byte)'s', (byte)'e' }; public static readonly byte[] base64Bytes = {(byte)'A',(byte)'B',(byte)'C',(byte)'D',(byte)'E',(byte)'F',(byte)'G',(byte)'H',(byte)'I',(byte)'J',(byte)'K',(byte)'L',(byte)'M',(byte)'N',(byte)'O', (byte)'P',(byte)'Q',(byte)'R',(byte)'S',(byte)'T',(byte)'U',(byte)'V',(byte)'W',(byte)'X',(byte)'Y',(byte)'Z',(byte)'a',(byte)'b',(byte)'c',(byte)'d', diff --git a/OpenMetaverseTypes/Quaternion.cs b/OpenMetaverseTypes/Quaternion.cs index 848c20c2..7bf9d918 100644 --- a/OpenMetaverseTypes/Quaternion.cs +++ b/OpenMetaverseTypes/Quaternion.cs @@ -28,6 +28,10 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Globalization; +using System.Text; +using System.Reflection.Metadata; +using System.Runtime.Intrinsics.X86; +using System.Runtime.Intrinsics; namespace OpenMetaverse { @@ -44,6 +48,13 @@ public struct Quaternion : IEquatable /// W value public float W; + public enum MainAxis : int + { + X = 0, + Y = 1, + Z = 2 + } + #region Constructors [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -78,7 +89,7 @@ public Quaternion(float x, float y, float z) Z = z; float xyzsum = 1f - (X * X) - (Y * Y) - (Z * Z); - W = (xyzsum > 1e-6f) ? (float)Math.Sqrt(xyzsum) : 0; + W = (xyzsum > 1e-6f) ? MathF.Sqrt(xyzsum) : 0; } /// @@ -106,29 +117,61 @@ public Quaternion(Quaternion q) W = q.W; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Quaternion(MainAxis BaseAxis, float angle) + { + switch (BaseAxis) + { + case MainAxis.X: + W = MathF.Cos(0.5f * angle); + X = MathF.Sqrt(1.0f - W * W); + Y = 0; + Z = 0; + break; + case MainAxis.Y: + W = MathF.Cos(0.5f * angle); + Y = MathF.Sqrt(1.0f - W * W); + X = 0; + Z = 0; + break; + case MainAxis.Z: + W = MathF.Cos(0.5f * angle); + Z = MathF.Sqrt(1.0f - W * W); + X = 0; + Y = 0; + break; + default: //error + X = 0; + Y = 0; + Z = 0; + W = 1; + break; + } + } + #endregion Constructors #region Public Methods [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool ApproxEquals(Quaternion quat) + public readonly bool ApproxEquals(Quaternion quat) { // assume normalized - return Math.Abs(quat.X - X) < 1e-6f && - Math.Abs(quat.Y - Y) < 1e-6f && - Math.Abs(quat.Z - Z) < 1e-6f; + return MathF.Abs(quat.X - X) < 1e-6f && + MathF.Abs(quat.Y - Y) < 1e-6f && + MathF.Abs(quat.Z - Z) < 1e-6f; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool ApproxEquals(Quaternion quat, float tolerance) + public readonly bool ApproxEquals(Quaternion quat, float tolerance) { // assume normalized - return Math.Abs(quat.X - X) < tolerance && - Math.Abs(quat.Y - Y) < tolerance && - Math.Abs(quat.Z - Z) < tolerance; + return MathF.Abs(quat.X - X) < tolerance && + MathF.Abs(quat.Y - Y) < tolerance && + MathF.Abs(quat.Z - Z) < tolerance; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool IsIdentity() + public readonly bool IsIdentity() { // assume normalized if(W > (1.0f - 1e-6f)) @@ -139,7 +182,7 @@ public bool IsIdentity() } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool IsIdentityOrZero() + public readonly bool IsIdentityOrZero() { // assume normalized if (X != 0) @@ -152,27 +195,42 @@ public bool IsIdentityOrZero() } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public float Length() + public readonly float Length() { - return (float)Math.Sqrt((X * X) + (Y * Y) + (Z * Z) + (W * W)); + return MathF.Sqrt((X * X) + (Y * Y) + (Z * Z) + (W * W)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public float LengthSquared() + public readonly float LengthSquared() { return (X * X) + (Y * Y) + (Z * Z) + (W * W); } + /* is slower + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe float LengthSquared2() + { + if (Avx.IsSupported) + { + Vector128 q = Avx.LoadVector128((float*)Unsafe.AsPointer(ref X)); + q = Avx.DotProduct(q, q, 0xf1); + return q.ToScalar(); + } + else + return (X * X) + (Y * Y) + (Z * Z) + (W * W); + } + */ + /// /// Normalizes the quaternion /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Normalize() + public unsafe void Normalize() { float mag = LengthSquared(); if (mag > 1e-6f) { - float oomag = 1f / (float)Math.Sqrt(mag); + float oomag = 1f / MathF.Sqrt(mag); X *= oomag; Y *= oomag; Z *= oomag; @@ -202,10 +260,10 @@ public void Invert() if (len > 1e-6f) { len = -1.0f / len; - X = X * len; - Y = Y * len; - Z = Z * len; - W = -W * len; + X *= len; + Y *= len; + Z *= len; + W *= -len; } else { @@ -217,13 +275,7 @@ public void Invert() } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public float Dot(Quaternion q2) - { - return (X * q2.X) + (Y * q2.Y) + (Z * q2.Z) + (W * q2.W); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public float Dot(ref Quaternion q2) + public readonly float Dot(Quaternion q2) { return (X * q2.X) + (Y * q2.Y) + (Z * q2.Z) + (W * q2.W); } @@ -262,7 +314,7 @@ public void FromBytes(byte[] byteArray, int pos, bool normalized) if (normalized) { float xyzsum = 1f - (X * X) - (Y * Y) - (Z * Z); - W = (xyzsum > 1e-6f) ? (float)Math.Sqrt(xyzsum) : 0f; + W = (xyzsum > 1e-6f) ? MathF.Sqrt(xyzsum) : 0f; } else { @@ -275,16 +327,16 @@ public void FromBytes(byte[] byteArray, int pos, bool normalized) /// /// A 12 byte array containing normalized X, Y, and Z floating /// point values in order using little endian byte ordering - public byte[] GetBytes() + public readonly byte[] GetBytes() { byte[] bytes = new byte[12]; float norm = LengthSquared(); if (norm > 1e-6f || W < 0.9999f) { if (W < 0f) - norm = -1f / (float)Math.Sqrt(norm); + norm = -1f / MathF.Sqrt(norm); else - norm = 1f / (float)Math.Sqrt(norm); + norm = 1f / MathF.Sqrt(norm); Utils.FloatToBytesSafepos(norm * X, bytes, 0); Utils.FloatToBytesSafepos(norm * Y, bytes, 4); Utils.FloatToBytesSafepos(norm * Z, bytes, 8); @@ -304,15 +356,15 @@ public byte[] GetBytes() /// Destination byte array /// Position in the destination array to start /// writing. Must be at least 12 bytes before the end of the array - public unsafe void ToBytes(byte[] dest, int pos) + public readonly unsafe void ToBytes(byte[] dest, int pos) { float norm = LengthSquared(); if (norm > 1e-6f || norm < 0.9999f) { if (W < 0f) - norm = -1f / (float)Math.Sqrt(norm); + norm = -1f / MathF.Sqrt(norm); else - norm = 1f / (float)Math.Sqrt(norm); + norm = 1f / MathF.Sqrt(norm); if (Utils.CanDirectCopyLE) { fixed (byte* d = &dest[0]) @@ -348,15 +400,15 @@ public unsafe void ToBytes(byte[] dest, int pos) } } - public unsafe void ToBytes(byte* dest) + public readonly unsafe void ToBytes(byte* dest) { float norm = LengthSquared(); if (norm > 1e-6f || norm < 0.9999f) { if (W < 0f) - norm = -1f / (float)Math.Sqrt(norm); + norm = -1f / MathF.Sqrt(norm); else - norm = 1f / (float)Math.Sqrt(norm); + norm = 1f / MathF.Sqrt(norm); if (Utils.CanDirectCopyLE) { *(float*)(dest) = norm * X; @@ -387,7 +439,7 @@ public unsafe void ToBytes(byte* dest) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public unsafe void ToShortsBytes(byte[] dest, int pos) + public readonly unsafe void ToShortsBytes(byte[] dest, int pos) { ushort sx = Utils.FloatToUnitUInt16(X); ushort sy = Utils.FloatToUnitUInt16(Y); @@ -413,7 +465,7 @@ public unsafe void ToShortsBytes(byte[] dest, int pos) } } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public unsafe void ToShortsBytes(byte* dest, int pos) + public readonly unsafe void ToShortsBytes(byte* dest, int pos) { ushort sx = Utils.FloatToUnitUInt16(X); ushort sy = Utils.FloatToUnitUInt16(Y); @@ -437,7 +489,7 @@ public unsafe void ToShortsBytes(byte* dest, int pos) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public unsafe void ToShortsBytes(byte* dest) + public readonly unsafe void ToShortsBytes(byte* dest) { ushort sx = Utils.FloatToUnitUInt16(X); ushort sy = Utils.FloatToUnitUInt16(Y); @@ -466,8 +518,10 @@ public unsafe void ToShortsBytes(byte* dest) /// X euler angle /// Y euler angle /// Z euler angle - public void GetEulerAngles(out float roll, out float pitch, out float yaw) + public readonly void GetEulerAngles(out float roll, out float pitch, out float yaw) { + const float halfpi = MathF.PI / 2f; + roll = 0f; pitch = 0f; yaw = 0f; @@ -480,7 +534,7 @@ public void GetEulerAngles(out float roll, out float pitch, out float yaw) float tZ = Z * Z; float tW = W * W; float m = tX + tY + tZ + tW; - if (Math.Abs(m) < 0.0001f) + if (MathF.Abs(m) < 0.0001f) return; float n = 2 * (Y * W + X * Z); @@ -488,21 +542,21 @@ public void GetEulerAngles(out float roll, out float pitch, out float yaw) if (p > 0f) { - roll = (float)Math.Atan2(2.0f * (X * W - Y * Z), (-tX - tY + tZ + tW)); - pitch = (float)Math.Atan2(n, Math.Sqrt(p)); - yaw = (float)Math.Atan2(2.0f * (Z * W - X * Y), tX - tY - tZ + tW); + roll = MathF.Atan2(2.0f * (X * W - Y * Z), (-tX - tY + tZ + tW)); + pitch = MathF.Atan2(n, MathF.Sqrt(p)); + yaw = MathF.Atan2(2.0f * (Z * W - X * Y), tX - tY - tZ + tW); } else if (n > 0f) { roll = 0f; - pitch = (float)(Math.PI / 2d); + pitch = halfpi; yaw = (float)Math.Atan2((Z * W + X * Y), 0.5f - tX - tY); } else { roll = 0f; - pitch = -(float)(Math.PI / 2d); - yaw = (float)Math.Atan2((Z * W + X * Y), 0.5f - tX - tZ); + pitch = -halfpi; + yaw = MathF.Atan2((Z * W + X * Y), 0.5f - tX - tZ); } } @@ -511,9 +565,9 @@ public void GetEulerAngles(out float roll, out float pitch, out float yaw) /// /// Unit vector describing the axis /// Angle around the axis, in radians - public void GetAxisAngle(out Vector3 axis, out float angle) + public readonly void GetAxisAngle(out Vector3 axis, out float angle) { - Normalize(); + //Normalize(); float ww = W * W; if (ww > 0.9999f) { @@ -527,19 +581,19 @@ public void GetAxisAngle(out Vector3 axis, out float angle) axis = new Vector3(-X, -Y, -Z); else axis = new Vector3(X, Y, Z); - angle = (float)Math.PI; + angle = MathF.PI; return; } - float sin = (float)Math.Sqrt(1.0f - ww); + float sin = MathF.Sqrt(1.0f - ww); float invSin = 1.0f / sin; if (W < 0) invSin = -invSin; axis = new Vector3(X, Y, Z) * invSin; - angle = 2.0f * (float)Math.Acos(W); - if (angle > Math.PI) - angle = 2.0f * (float)Math.PI - angle; + angle = 2.0f * MathF.Acos(W); + if (angle > MathF.PI) + angle = 2.0f * MathF.PI - angle; } #endregion Public Methods @@ -572,7 +626,7 @@ public static Quaternion Conjugate(Quaternion quaternion) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Quaternion CreateFromAxisAngle(float axisX, float axisY, float axisZ, float angle) { - Vector3 axis = new Vector3(axisX, axisY, axisZ); + Vector3 axis = new(axisX, axisY, axisZ); return CreateFromAxisAngle(axis, angle); } @@ -588,8 +642,8 @@ public static Quaternion CreateFromAxisAngle(Vector3 axis, float angle) axis.Normalize(); angle *= 0.5f; - float c = (float)Math.Cos(angle); - float s = (float)Math.Sin(angle); + float c = MathF.Cos(angle); + float s = MathF.Sin(angle); return new Quaternion(axis.X * s, axis.Y * s, axis.Z * s, c); } @@ -598,8 +652,8 @@ public static Quaternion CreateFromAxisAngle(Vector3 axis, float angle) public static Quaternion CreateRotationX(float angle) { angle *= 0.5f; - float c = (float)Math.Cos(angle); - float s = (float)Math.Sin(angle); + float c = MathF.Cos(angle); + float s = MathF.Sin(angle); return new Quaternion(s, 0, 0, c); } @@ -608,8 +662,8 @@ public static Quaternion CreateRotationX(float angle) public static Quaternion CreateRotationY(float angle) { angle *= 0.5f; - float c = (float)Math.Cos(angle); - float s = (float)Math.Sin(angle); + float c = MathF.Cos(angle); + float s = MathF.Sin(angle); return new Quaternion(0, s, 0, c); } @@ -618,8 +672,8 @@ public static Quaternion CreateRotationY(float angle) public static Quaternion CreateRotationZ(float angle) { angle *= 0.5f; - float c = (float)Math.Cos(angle); - float s = (float)Math.Sin(angle); + float c = MathF.Cos(angle); + float s = MathF.Sin(angle); return new Quaternion(0, 0, s, c); } @@ -651,22 +705,22 @@ public static Quaternion CreateFromEulers(float roll, float pitch, float yaw) throw new ArgumentException("Euler angles must be in radians"); roll *= 0.5f; - double atCos = Math.Cos(roll); - double atSin = Math.Sin(roll); + float atCos = MathF.Cos(roll); + float atSin = MathF.Sin(roll); pitch *= 0.5f; - double leftCos = Math.Cos(pitch); - double leftSin = Math.Sin(pitch); + float leftCos = MathF.Cos(pitch); + float leftSin = MathF.Sin(pitch); yaw *= 0.5f; - double upCos = Math.Cos(yaw); - double upSin = Math.Sin(yaw); + float upCos = MathF.Cos(yaw); + float upSin = MathF.Sin(yaw); - double atLeftCos = atCos * leftCos; - double atLeftSin = atSin * leftSin; + float atLeftCos = atCos * leftCos; + float atLeftSin = atSin * leftSin; return new Quaternion( - (float)(atSin * leftCos * upCos + atCos * leftSin * upSin), - (float)(atCos * leftSin * upCos - atSin * leftCos * upSin), - (float)(atLeftCos * upSin + atLeftSin * upCos), - (float)(atLeftCos * upCos - atLeftSin * upSin) + atSin * leftCos * upCos + atCos * leftSin * upSin, + atCos * leftSin * upCos - atSin * leftCos * upSin, + atLeftCos * upSin + atLeftSin * upCos, + atLeftCos * upCos - atLeftSin * upSin ); } @@ -676,7 +730,7 @@ public static Quaternion CreateFromRotationMatrix(Matrix3x3 matrix) float n2; if (num >= 0f) { - num = (float)Math.Sqrt((num + 1f)); + num = MathF.Sqrt((num + 1f)); n2 = 0.5f / num; return new Quaternion( (matrix.M23 - matrix.M32) * n2, @@ -686,7 +740,7 @@ public static Quaternion CreateFromRotationMatrix(Matrix3x3 matrix) } if ((matrix.M11 >= matrix.M22) && (matrix.M11 >= matrix.M33)) { - num = (float)Math.Sqrt((((1f + matrix.M11) - matrix.M22) - matrix.M33)); + num = MathF.Sqrt((((1f + matrix.M11) - matrix.M22) - matrix.M33)); n2 = 0.5f / num; return new Quaternion( 0.5f * num, @@ -696,7 +750,7 @@ public static Quaternion CreateFromRotationMatrix(Matrix3x3 matrix) } if (matrix.M22 > matrix.M33) { - num = (float)Math.Sqrt((((1f + matrix.M22) - matrix.M11) - matrix.M33)); + num = MathF.Sqrt((((1f + matrix.M22) - matrix.M11) - matrix.M33)); n2 = 0.5f / num; return new Quaternion( (matrix.M21 + matrix.M12) * n2, @@ -705,7 +759,7 @@ public static Quaternion CreateFromRotationMatrix(Matrix3x3 matrix) (matrix.M31 - matrix.M13) * n2); } - num = (float)Math.Sqrt((((1f + matrix.M33) - matrix.M11) - matrix.M22)); + num = MathF.Sqrt((((1f + matrix.M33) - matrix.M11) - matrix.M22)); n2 = 0.5f / num; return new Quaternion( (matrix.M31 + matrix.M13) * n2, @@ -720,7 +774,7 @@ public static Quaternion CreateFromRotationMatrix(Matrix4 matrix) float n2; if (num >= 0f) { - num = (float)Math.Sqrt((num + 1f)); + num = MathF.Sqrt((num + 1f)); n2 = 0.5f / num; return new Quaternion( (matrix.M23 - matrix.M32) * n2, @@ -730,7 +784,7 @@ public static Quaternion CreateFromRotationMatrix(Matrix4 matrix) } if ((matrix.M11 >= matrix.M22) && (matrix.M11 >= matrix.M33)) { - num = (float)Math.Sqrt((((1f + matrix.M11) - matrix.M22) - matrix.M33)); + num = MathF.Sqrt((((1f + matrix.M11) - matrix.M22) - matrix.M33)); n2 = 0.5f / num; return new Quaternion( 0.5f * num, @@ -740,7 +794,7 @@ public static Quaternion CreateFromRotationMatrix(Matrix4 matrix) } if (matrix.M22 > matrix.M33) { - num = (float)Math.Sqrt((((1f + matrix.M22) - matrix.M11) - matrix.M33)); + num = MathF.Sqrt((((1f + matrix.M22) - matrix.M11) - matrix.M33)); n2 = 0.5f / num; return new Quaternion( (matrix.M21 + matrix.M12) * n2, @@ -749,7 +803,7 @@ public static Quaternion CreateFromRotationMatrix(Matrix4 matrix) (matrix.M31 - matrix.M13) * n2); } - num = (float)Math.Sqrt((((1f + matrix.M33) - matrix.M11) - matrix.M22)); + num = MathF.Sqrt((((1f + matrix.M33) - matrix.M11) - matrix.M22)); n2 = 0.5f / num; return new Quaternion( (matrix.M31 + matrix.M13) * n2, @@ -792,7 +846,7 @@ public static Quaternion Inverse(Quaternion quaternion) /// /// Spherical linear interpolation between two quaternions /// - public static Quaternion Slerp(Quaternion q1, Quaternion q2, float amount) + public static Quaternion Slerp(Quaternion q1, in Quaternion q2, float amount) { float angle = Dot(q1, q2); @@ -810,10 +864,10 @@ public static Quaternion Slerp(Quaternion q1, Quaternion q2, float amount) if ((1f - angle) >= 0.05f) { // slerp - float theta = (float)Math.Acos(angle); - float invsintheta = 1f / (float)Math.Sin(theta); - scale = (float)Math.Sin(theta * (1f - amount)) * invsintheta; - invscale = (float)Math.Sin(theta * amount) * invsintheta; + float theta = MathF.Acos(angle); + float invsintheta = 1f / MathF.Sin(theta); + scale = MathF.Sin(theta * (1f - amount)) * invsintheta; + invscale = MathF.Sin(theta * amount) * invsintheta; } else { @@ -824,13 +878,14 @@ public static Quaternion Slerp(Quaternion q1, Quaternion q2, float amount) } else { - q2.X = -q1.Y; - q2.Y = q1.X; - q2.Z = -q1.W; - q2.W = q1.Z; - - scale = (float)Math.Sin(Utils.PI * (0.5f - amount)); - invscale = (float)Math.Sin(Utils.PI * amount); + scale = MathF.Sin(Utils.PI * (0.5f - amount)); + invscale = MathF.Sin(Utils.PI * amount); + return new Quaternion( + q1.X * scale - q1.Y * invscale, + q1.Y * scale + q1.X * invscale, + q1.Z * scale - q1.W * invscale, + q1.W * scale + q1.Z * invscale + ); } return new Quaternion( @@ -888,7 +943,7 @@ public static Quaternion Normalize(Quaternion q) float mag = q.LengthSquared(); if (mag > 1e-6f) { - float oomag = 1f / (float)Math.Sqrt(mag); + float oomag = 1f / MathF.Sqrt(mag); return new Quaternion( q.X * oomag, q.Y * oomag, @@ -898,38 +953,210 @@ public static Quaternion Normalize(Quaternion q) return Quaternion.Identity; } - public static Quaternion Parse(string val) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + + public unsafe static Quaternion Parse(string val) { - char[] splitChar = { ',' }; - string[] split = val.Replace("<", String.Empty).Replace(">", String.Empty).Split(splitChar); - if (split.Length == 3) - { - return new Quaternion( - float.Parse(split[0].Trim(), Utils.EnUsCulture), - float.Parse(split[1].Trim(), Utils.EnUsCulture), - float.Parse(split[2].Trim(), Utils.EnUsCulture)); - } - else + return Parse(val.AsSpan()); + } + + public unsafe static Quaternion Parse(ReadOnlySpan sp) + { + if (sp.Length < 7) + throw new FormatException("Invalid Quaternion"); + + int start = 0; + fixed (char* p = sp) { - return new Quaternion( - float.Parse(split[0].Trim(), Utils.EnUsCulture), - float.Parse(split[1].Trim(), Utils.EnUsCulture), - float.Parse(split[2].Trim(), Utils.EnUsCulture), - float.Parse(split[3].Trim(), Utils.EnUsCulture)); + while (start < sp.Length) + { + if (p[start++] == '<') + break; + } + if (start > sp.Length - 6) + throw new FormatException("Invalid Quaternion"); + + int comma1 = start + 1; + while (comma1 < sp.Length) + { + if (p[comma1] == ',') + break; + comma1++; + } + if (comma1 > sp.Length - 5) + throw new FormatException("Invalid Quaternion"); + + if (!float.TryParse(sp[start..comma1], NumberStyles.Float, Utils.EnUsCulture, out float x)) + throw new FormatException("Invalid Quaternion"); + + comma1++; + start = comma1; + comma1++; + while (comma1 < sp.Length) + { + if (p[comma1] == ',') + break; + comma1++; + } + if (comma1 > sp.Length - 3) + throw new FormatException("Invalid Quaternion"); + if (!float.TryParse(sp[start..comma1], NumberStyles.Float, Utils.EnUsCulture, out float y)) + throw new FormatException("Invalid Quaternion"); + + comma1++; + start = comma1; + comma1++; + while (comma1 < sp.Length) + { + if (p[comma1] == '>' || p[comma1] == ',') + break; + comma1++; + } + if (comma1 >= sp.Length) + throw new FormatException("Invalid Quaternion"); + + if (!float.TryParse(sp[start..comma1], NumberStyles.Float, Utils.EnUsCulture, out float z)) + throw new FormatException("Invalid Quaternion"); + + if (p[comma1] == '>') + return new Quaternion(x, y, z); + + comma1++; + start = comma1; + comma1++; + while (comma1 < sp.Length) + { + if (p[comma1] == '>') + break; + comma1++; + } + if (comma1 >= sp.Length) + throw new FormatException("Invalid Quaternion"); + + if (!float.TryParse(sp[start..comma1], NumberStyles.Float, Utils.EnUsCulture, out float w)) + throw new FormatException("Invalid Quaternion"); + + return new Quaternion(x, y, z, w); } } - public static bool TryParse(string val, out Quaternion result) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static bool TryParse(string val, out Quaternion result) { - try + return TryParse(val.AsSpan(), out result); + } + + public unsafe static bool TryParse(ReadOnlySpan sp, out Quaternion result) + { + if (sp.Length < 7) { - result = Parse(val); - return true; + result = Identity; + return false; } - catch (Exception) + + int start = 0; + fixed (char* p = sp) { - result = new Quaternion(); - return false; + while (start < sp.Length) + { + if (p[start++] == '<') + break; + } + if (start > sp.Length - 6) + { + result = Identity; + return false; + } + + int comma1 = start + 1; + while (comma1 < sp.Length) + { + if (p[comma1] == ',') + break; + comma1++; + } + if (comma1 > sp.Length - 5) + { + result = Identity; + return false; + } + + if (!float.TryParse(sp[start..comma1], NumberStyles.Float, Utils.EnUsCulture, out float x)) + { + result = Identity; + return false; + } + + comma1++; + start = comma1; + comma1++; + while (comma1 < sp.Length) + { + if (p[comma1] == ',') + break; + comma1++; + } + if (comma1 > sp.Length - 3) + { + result = Identity; + return false; + } + if (!float.TryParse(sp[start..comma1], NumberStyles.Float, Utils.EnUsCulture, out float y)) + { + result = Identity; + return false; + } + + comma1++; + start = comma1; + comma1++; + while (comma1 < sp.Length) + { + if (p[comma1] == '>' || p[comma1] == ',') + break; + comma1++; + } + if (comma1 >= sp.Length) + { + result = Identity; + return false; + } + + if (!float.TryParse(sp[start..comma1], NumberStyles.Float, Utils.EnUsCulture, out float z)) + { + result = Identity; + return false; + } + + if (p[comma1] == '>') + { + result = new Quaternion(x, y, z); + return true; + } + + comma1++; + start = comma1; + comma1++; + while (comma1 < sp.Length) + { + if (p[comma1] == '>') + break; + comma1++; + } + if (comma1 >= sp.Length) + { + result = Identity; + return false; + } + + if (!float.TryParse(sp[start..comma1], NumberStyles.Float, Utils.EnUsCulture, out float w)) + { + result = Identity; + return false; + } + + result = new Quaternion(x, y, z, w); + return true; } } @@ -937,9 +1164,9 @@ public static bool TryParse(string val, out Quaternion result) #region Overrides - public override bool Equals(object obj) + public readonly override bool Equals(object obj) { - if(!(obj is Quaternion)) + if((obj is not Quaternion)) return false; Quaternion other = (Quaternion)obj; if (X != other.X) @@ -954,7 +1181,7 @@ public override bool Equals(object obj) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool Equals(Quaternion other) + public readonly bool Equals(Quaternion other) { if (X != other.X) return false; @@ -968,7 +1195,7 @@ public bool Equals(Quaternion other) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool NotEqual(Quaternion other) + public readonly bool NotEqual(Quaternion other) { if (X != other.X) return true; @@ -982,7 +1209,7 @@ public bool NotEqual(Quaternion other) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public override int GetHashCode() + public readonly override int GetHashCode() { int hash = X.GetHashCode(); hash = Utils.CombineHash(hash, Y.GetHashCode()); @@ -991,9 +1218,19 @@ public override int GetHashCode() return hash; } - public override string ToString() + public readonly override string ToString() { - return String.Format(Utils.EnUsCulture, "<{0}, {1}, {2}, {3}>", X, Y, Z, W); + StringBuilder sb = new(); + sb.Append('<'); + sb.Append(X.ToString(Utils.EnUsCulture)); + sb.Append(", "); + sb.Append(Y.ToString(Utils.EnUsCulture)); + sb.Append(", "); + sb.Append(Z.ToString(Utils.EnUsCulture)); + sb.Append(", "); + sb.Append(W.ToString(Utils.EnUsCulture)); + sb.Append('>'); + return sb.ToString(); } /// @@ -1001,12 +1238,20 @@ public override string ToString() /// decimal digits and separated by spaces only /// /// Raw string representation of the quaternion - public string ToRawString() + public readonly string ToRawString() { - CultureInfo enUs = new CultureInfo("en-us"); + CultureInfo enUs = new("en-us"); enUs.NumberFormat.NumberDecimalDigits = 3; - return String.Format(enUs, "{0} {1} {2} {3}", X, Y, Z, W); + StringBuilder sb = new(); + sb.Append(X.ToString(enUs)); + sb.Append(' '); + sb.Append(Y.ToString(enUs)); + sb.Append(' '); + sb.Append(Z.ToString(enUs)); + sb.Append(' '); + sb.Append(W.ToString(enUs)); + return sb.ToString(); } #endregion Overrides @@ -1089,6 +1334,6 @@ public string ToRawString() #endregion Operators /// A quaternion with a value of 0,0,0,1 - public readonly static Quaternion Identity = new Quaternion(0f, 0f, 0f, 1f); + public readonly static Quaternion Identity = new(0f, 0f, 0f, 1f); } } diff --git a/OpenMetaverseTypes/UUID.cs b/OpenMetaverseTypes/UUID.cs index c3ac220e..c4d0f507 100644 --- a/OpenMetaverseTypes/UUID.cs +++ b/OpenMetaverseTypes/UUID.cs @@ -41,8 +41,6 @@ namespace OpenMetaverse [Serializable()] public struct UUID : IComparable,IComparable, IEquatable, IEqualityComparer { - // still a big piece of *** because how stupid .net structs are. - // .net5 unsafe may remove the need for this union [XmlIgnore] [NonSerialized()] [FieldOffset(0)] public int a; [XmlIgnore] [NonSerialized()] [FieldOffset(4)] public short b; [XmlIgnore] [NonSerialized()] [FieldOffset(6)] public short c; @@ -107,9 +105,135 @@ public unsafe UUID(string val) public unsafe UUID(string sval) { this = new UUID(); - if (sval == null) + if (sval is null) throw new FormatException("Invalid UUID"); + int len = sval.Length; + if (len < 32) + throw new FormatException("Invalid UUID"); + + try + { + fixed (char* bval = sval) + { + char* val = bval; + while (*val == ' ') + { + ++val; + --len; + if (len < 32) + throw new Exception(); + } + + if (val[8] == '-') + { + if (len < 36) + throw new Exception(); + + while (--len > 35) + { + if (val[len] != ' ') + throw new Exception(); + } + + if (val[13] != '-' || val[18] != '-' || val[23] != '-') + throw new Exception(); + + if (BitConverter.IsLittleEndian) + { + bytea3 = Utils.HexToByte(val, 0); + bytea2 = Utils.HexToByte(val, 2); + bytea1 = Utils.HexToByte(val, 4); + bytea0 = Utils.HexToByte(val, 6); + + byteb1 = Utils.HexToByte(val, 9); + byteb0 = Utils.HexToByte(val, 11); + + bytec1 = Utils.HexToByte(val, 14); + bytec0 = Utils.HexToByte(val, 16); + } + else + { + bytea0 = Utils.HexToByte(val, 0); + bytea1 = Utils.HexToByte(val, 2); + bytea2 = Utils.HexToByte(val, 4); + bytea3 = Utils.HexToByte(val, 6); + + byteb0 = Utils.HexToByte(val, 9); + byteb1 = Utils.HexToByte(val, 11); + + bytec0 = Utils.HexToByte(val, 14); + bytec1 = Utils.HexToByte(val, 16); + } + + + d = Utils.HexToByte(val, 19); + e = Utils.HexToByte(val, 21); + + + f = Utils.HexToByte(val, 24); + g = Utils.HexToByte(val, 26); + h = Utils.HexToByte(val, 28); + i = Utils.HexToByte(val, 30); + j = Utils.HexToByte(val, 32); + k = Utils.HexToByte(val, 34); + return; + } + else + { + while (--len > 31) + { + if (val[len] != ' ') + throw new Exception(); + } + + if (BitConverter.IsLittleEndian) + { + bytea3 = Utils.HexToByte(val, 0); + bytea2 = Utils.HexToByte(val, 2); + bytea1 = Utils.HexToByte(val, 4); + bytea0 = Utils.HexToByte(val, 6); + + byteb1 = Utils.HexToByte(val, 8); + byteb0 = Utils.HexToByte(val, 10); + + bytec1 = Utils.HexToByte(val, 12); + bytec0 = Utils.HexToByte(val, 14); + } + else + { + bytea0 = Utils.HexToByte(val, 0); + bytea1 = Utils.HexToByte(val, 2); + bytea2 = Utils.HexToByte(val, 4); + bytea3 = Utils.HexToByte(val, 6); + + byteb0 = Utils.HexToByte(val, 8); + byteb1 = Utils.HexToByte(val, 10); + + bytec0 = Utils.HexToByte(val, 12); + bytec1 = Utils.HexToByte(val, 14); + } + + d = Utils.HexToByte(val, 16); + e = Utils.HexToByte(val, 18); + + f = Utils.HexToByte(val, 20); + g = Utils.HexToByte(val, 22); + h = Utils.HexToByte(val, 24); + i = Utils.HexToByte(val, 26); + j = Utils.HexToByte(val, 28); + k = Utils.HexToByte(val, 30); + return; + } + } + } + catch { } + this = new UUID(); + throw new System.FormatException("Invalid UUID"); + } + public unsafe UUID(ReadOnlySpan sval) + { + this = new UUID(); int len = sval.Length; if (len < 32) throw new FormatException("Invalid UUID"); @@ -143,42 +267,42 @@ public unsafe UUID(string sval) if (BitConverter.IsLittleEndian) { - bytea3 = (byte)Utils.HexToByte(val, 0); - bytea2 = (byte)Utils.HexToByte(val, 2); - bytea1 = (byte)Utils.HexToByte(val, 4); - bytea0 = (byte)Utils.HexToByte(val, 6); + bytea3 = Utils.HexToByte(val, 0); + bytea2 = Utils.HexToByte(val, 2); + bytea1 = Utils.HexToByte(val, 4); + bytea0 = Utils.HexToByte(val, 6); - byteb1 = (byte)Utils.HexToByte(val, 9); - byteb0 = (byte)Utils.HexToByte(val, 11); + byteb1 = Utils.HexToByte(val, 9); + byteb0 = Utils.HexToByte(val, 11); - bytec1 = (byte)Utils.HexToByte(val, 14); - bytec0 = (byte)Utils.HexToByte(val, 16); + bytec1 = Utils.HexToByte(val, 14); + bytec0 = Utils.HexToByte(val, 16); } else { - bytea0 = (byte)Utils.HexToByte(val, 0); - bytea1 = (byte)Utils.HexToByte(val, 2); - bytea2 = (byte)Utils.HexToByte(val, 4); - bytea3 = (byte)Utils.HexToByte(val, 6); + bytea0 = Utils.HexToByte(val, 0); + bytea1 = Utils.HexToByte(val, 2); + bytea2 = Utils.HexToByte(val, 4); + bytea3 = Utils.HexToByte(val, 6); - byteb0 = (byte)Utils.HexToByte(val, 9); - byteb1 = (byte)Utils.HexToByte(val, 11); + byteb0 = Utils.HexToByte(val, 9); + byteb1 = Utils.HexToByte(val, 11); - bytec0 = (byte)Utils.HexToByte(val, 14); - bytec1 = (byte)Utils.HexToByte(val, 16); + bytec0 = Utils.HexToByte(val, 14); + bytec1 = Utils.HexToByte(val, 16); } - d = (byte)Utils.HexToByte(val, 19); - e = (byte)Utils.HexToByte(val, 21); + d = Utils.HexToByte(val, 19); + e = Utils.HexToByte(val, 21); - f = (byte)Utils.HexToByte(val, 24); - g = (byte)Utils.HexToByte(val, 26); - h = (byte)Utils.HexToByte(val, 28); - i = (byte)Utils.HexToByte(val, 30); - j = (byte)Utils.HexToByte(val, 32); - k = (byte)Utils.HexToByte(val, 34); + f = Utils.HexToByte(val, 24); + g = Utils.HexToByte(val, 26); + h = Utils.HexToByte(val, 28); + i = Utils.HexToByte(val, 30); + j = Utils.HexToByte(val, 32); + k = Utils.HexToByte(val, 34); return; } else @@ -332,13 +456,12 @@ public UUID(UUID val) /// /// IComparable.CompareTo implementation /// - public int CompareTo(object val) + public readonly int CompareTo(object val) { if (val == null) return 1; UUID id = (UUID)val; - if (id.a != a) return (uint)id.a > (uint)a ? -1 : 1; if (id.b != b) @@ -365,7 +488,7 @@ public int CompareTo(object val) return 0; } - public int CompareTo(UUID id) + public readonly int CompareTo(UUID id) { if (id.a != a) return (uint)id.a > (uint)a ? -1 : 1; @@ -437,7 +560,7 @@ public unsafe void FromBytes(byte[] source, int pos) /// /// A 16 byte array containing this UUID [MethodImpl(MethodImplOptions.AggressiveInlining)] - public unsafe byte[] GetBytes() + public readonly unsafe byte[] GetBytes() { byte[] dest = new byte[16]; fixed (byte* ptr = &dest[0]) @@ -477,7 +600,7 @@ public unsafe byte[] GetBytes() /// Position in the destination array to start /// writing. Must be at least 16 bytes before the end of the array [MethodImpl(MethodImplOptions.AggressiveInlining)] - public unsafe void ToBytes(byte[] dest, int pos) + public readonly unsafe void ToBytes(byte[] dest, int pos) { fixed (byte* ptr = &dest[pos]) { @@ -509,7 +632,7 @@ public unsafe void ToBytes(byte[] dest, int pos) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public unsafe void ToBytes(byte* ptr) + public readonly unsafe void ToBytes(byte* ptr) { if (BitConverter.IsLittleEndian) { @@ -551,7 +674,8 @@ public uint CRC() /// Create a 64-bit integer representation from the second half of this UUID /// /// An integer created from the last eight bytes of this UUID - public ulong GetULong() + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public readonly ulong GetULong() { if (BitConverter.IsLittleEndian) return ulongb; @@ -576,20 +700,17 @@ public ulong GetULong() /// A string representation of a UUID, case /// insensitive and can either be hyphenated or non-hyphenated /// UUID.Parse("11f8aa9c-b071-4242-836b-13b7abe0d489") - /* - public static UUID Parse(string val) - { - Guid gg = Guid.Parse(val); - return new UUID(gg); - } - */ + + [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static UUID Parse(string sval) { - UUID result = new UUID(); - if (sval == null) - throw new FormatException("Invalid UUID"); + return Parse(sval.AsSpan()); + } + public unsafe static UUID Parse(ReadOnlySpan sval) + { + UUID result = new(); int len = sval.Length; if (len < 32) throw new FormatException("Invalid UUID"); @@ -621,41 +742,41 @@ public unsafe static UUID Parse(string sval) if (BitConverter.IsLittleEndian) { - result.bytea3 = (byte)Utils.HexToByte(val, 0); - result.bytea2 = (byte)Utils.HexToByte(val, 2); - result.bytea1 = (byte)Utils.HexToByte(val, 4); - result.bytea0 = (byte)Utils.HexToByte(val, 6); + result.bytea3 = Utils.HexToByte(val, 0); + result.bytea2 = Utils.HexToByte(val, 2); + result.bytea1 = Utils.HexToByte(val, 4); + result.bytea0 = Utils.HexToByte(val, 6); - result.byteb1 = (byte)Utils.HexToByte(val, 9); - result.byteb0 = (byte)Utils.HexToByte(val, 11); + result.byteb1 = Utils.HexToByte(val, 9); + result.byteb0 = Utils.HexToByte(val, 11); - result.bytec1 = (byte)Utils.HexToByte(val, 14); - result.bytec0 = (byte)Utils.HexToByte(val, 16); + result.bytec1 = Utils.HexToByte(val, 14); + result.bytec0 = Utils.HexToByte(val, 16); } else { - result.bytea0 = (byte)Utils.HexToByte(val, 0); - result.bytea1 = (byte)Utils.HexToByte(val, 2); - result.bytea2 = (byte)Utils.HexToByte(val, 4); - result.bytea3 = (byte)Utils.HexToByte(val, 6); + result.bytea0 = Utils.HexToByte(val, 0); + result.bytea1 = Utils.HexToByte(val, 2); + result.bytea2 = Utils.HexToByte(val, 4); + result.bytea3 = Utils.HexToByte(val, 6); - result.byteb0 = (byte)Utils.HexToByte(val, 9); - result.byteb1 = (byte)Utils.HexToByte(val, 11); + result.byteb0 = Utils.HexToByte(val, 9); + result.byteb1 = Utils.HexToByte(val, 11); - result.bytec0 = (byte)Utils.HexToByte(val, 14); - result.bytec1 = (byte)Utils.HexToByte(val, 16); + result.bytec0 = Utils.HexToByte(val, 14); + result.bytec1 = Utils.HexToByte(val, 16); } - result.d = (byte)Utils.HexToByte(val, 19); - result.e = (byte)Utils.HexToByte(val, 21); + result.d = Utils.HexToByte(val, 19); + result.e = Utils.HexToByte(val, 21); - result.f = (byte)Utils.HexToByte(val, 24); - result.g = (byte)Utils.HexToByte(val, 26); - result.h = (byte)Utils.HexToByte(val, 28); - result.i = (byte)Utils.HexToByte(val, 30); - result.j = (byte)Utils.HexToByte(val, 32); - result.k = (byte)Utils.HexToByte(val, 34); + result.f = Utils.HexToByte(val, 24); + result.g = Utils.HexToByte(val, 26); + result.h = Utils.HexToByte(val, 28); + result.i = Utils.HexToByte(val, 30); + result.j = Utils.HexToByte(val, 32); + result.k = Utils.HexToByte(val, 34); return result; } else @@ -721,11 +842,15 @@ public unsafe static UUID Parse(string sval) /// True if the string was successfully parse, otherwise false /// UUID.TryParse("11f8aa9c-b071-4242-836b-13b7abe0d489", result) + [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static bool TryParse(string sval, out UUID result) + { + return TryParse(sval.AsSpan(), out result); + } + + public unsafe static bool TryParse(ReadOnlySpan sval, out UUID result) { result = new UUID(); - if (sval is null) - return false; int len = sval.Length; if (len < 32) @@ -760,41 +885,41 @@ public unsafe static bool TryParse(string sval, out UUID result) if (BitConverter.IsLittleEndian) { - result.bytea3 = (byte)Utils.HexToByte(val, 0); - result.bytea2 = (byte)Utils.HexToByte(val, 2); - result.bytea1 = (byte)Utils.HexToByte(val, 4); - result.bytea0 = (byte)Utils.HexToByte(val, 6); + result.bytea3 = Utils.HexToByte(val, 0); + result.bytea2 = Utils.HexToByte(val, 2); + result.bytea1 = Utils.HexToByte(val, 4); + result.bytea0 = Utils.HexToByte(val, 6); - result.byteb1 = (byte)Utils.HexToByte(val, 9); - result.byteb0 = (byte)Utils.HexToByte(val, 11); + result.byteb1 = Utils.HexToByte(val, 9); + result.byteb0 = Utils.HexToByte(val, 11); - result.bytec1 = (byte)Utils.HexToByte(val, 14); - result.bytec0 = (byte)Utils.HexToByte(val, 16); + result.bytec1 = Utils.HexToByte(val, 14); + result.bytec0 = Utils.HexToByte(val, 16); } else { - result.bytea0 = (byte)Utils.HexToByte(val, 0); - result.bytea1 = (byte)Utils.HexToByte(val, 2); - result.bytea2 = (byte)Utils.HexToByte(val, 4); - result.bytea3 = (byte)Utils.HexToByte(val, 6); + result.bytea0 = Utils.HexToByte(val, 0); + result.bytea1 = Utils.HexToByte(val, 2); + result.bytea2 = Utils.HexToByte(val, 4); + result.bytea3 = Utils.HexToByte(val, 6); - result.byteb0 = (byte)Utils.HexToByte(val, 9); - result.byteb1 = (byte)Utils.HexToByte(val, 11); + result.byteb0 = Utils.HexToByte(val, 9); + result.byteb1 = Utils.HexToByte(val, 11); - result.bytec0 = (byte)Utils.HexToByte(val, 14); - result.bytec1 = (byte)Utils.HexToByte(val, 16); + result.bytec0 = Utils.HexToByte(val, 14); + result.bytec1 = Utils.HexToByte(val, 16); } - result.d = (byte)Utils.HexToByte(val, 19); - result.e = (byte)Utils.HexToByte(val, 21); + result.d = Utils.HexToByte(val, 19); + result.e = Utils.HexToByte(val, 21); - result.f = (byte)Utils.HexToByte(val, 24); - result.g = (byte)Utils.HexToByte(val, 26); - result.h = (byte)Utils.HexToByte(val, 28); - result.i = (byte)Utils.HexToByte(val, 30); - result.j = (byte)Utils.HexToByte(val, 32); - result.k = (byte)Utils.HexToByte(val, 34); + result.f = Utils.HexToByte(val, 24); + result.g = Utils.HexToByte(val, 26); + result.h = Utils.HexToByte(val, 28); + result.i = Utils.HexToByte(val, 30); + result.j = Utils.HexToByte(val, 32); + result.k = Utils.HexToByte(val, 34); return true; } else @@ -886,7 +1011,7 @@ public unsafe static UUID Random() ///
/// An integer composed of all the UUID bytes XORed together [MethodImpl(MethodImplOptions.AggressiveInlining)] - public override int GetHashCode() + public readonly override int GetHashCode() { int h = Utils.CombineHash(intd, intc); h = Utils.CombineHash(h, intb); @@ -894,9 +1019,11 @@ public override int GetHashCode() } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public int GetHashCode(UUID u) + public readonly int GetHashCode(UUID u) { - return u.a ^ u.intb ^ u.intc ^ u.intd; + int h = Utils.CombineHash(u.intd, u.intc); + h = Utils.CombineHash(h, u.intb); + return Utils.CombineHash(h, u.a); } /// @@ -905,12 +1032,11 @@ public int GetHashCode(UUID u) /// An object to compare to this UUID /// True if the object is a UUID and both UUIDs are equal [MethodImpl(MethodImplOptions.AggressiveInlining)] - public override bool Equals(object o) + public readonly override bool Equals(object o) { - if (!(o is UUID)) + if (o is not UUID uuid) return false; - UUID uuid = (UUID)o; if (ulonga != uuid.ulonga) return false; if (ulongb != uuid.ulongb) @@ -924,7 +1050,7 @@ public override bool Equals(object o) /// UUID to compare to /// True if the UUIDs are equal, otherwise false [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool Equals(UUID uuid) + public readonly bool Equals(UUID uuid) { if (ulonga != uuid.ulonga) return false; @@ -934,7 +1060,7 @@ public bool Equals(UUID uuid) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool Equals(UUID a, UUID b) + public readonly bool Equals(UUID a, UUID b) { if (a.ulonga != b.ulonga) return false; @@ -944,7 +1070,7 @@ public bool Equals(UUID a, UUID b) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool IsZero() + public readonly bool IsZero() { if (ulonga != 0) return false; @@ -954,7 +1080,7 @@ public bool IsZero() } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool NotEqual(UUID uuid) + public readonly bool NotEqual(in UUID uuid) { if (ulonga != uuid.ulonga) return true; @@ -964,7 +1090,7 @@ public bool NotEqual(UUID uuid) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool IsNotZero() + public readonly bool IsNotZero() { if (ulonga != 0) return true; @@ -981,9 +1107,9 @@ public bool IsNotZero() /// 11f8aa9c-b071-4242-836b-13b7abe0d489 [MethodImpl(MethodImplOptions.AggressiveInlining)] - public override string ToString() + public readonly override string ToString() { - return Utils.UUIDToDashString(ref this); + return Utils.UUIDToDashString(this); } #endregion Overrides @@ -997,7 +1123,7 @@ public override string ToString() /// Second UUID for comparison /// True if the UUIDs are byte for byte equal, otherwise false [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator ==(UUID lhs, UUID rhs) + public static bool operator ==(in UUID lhs, in UUID rhs) { if (lhs.ulonga != rhs.ulonga) return false; @@ -1013,7 +1139,7 @@ public override string ToString() /// Second UUID for comparison /// True if the UUIDs are not equal, otherwise true [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator !=(UUID lhs, UUID rhs) + public static bool operator !=(in UUID lhs, in UUID rhs) { if (lhs.ulonga != rhs.ulonga) return true; @@ -1030,10 +1156,11 @@ public override string ToString() /// A UUID that is a XOR combination of the two input UUIDs public static UUID operator ^(UUID lhs, UUID rhs) { - UUID ret = new UUID(); - ret.ulonga = lhs.ulonga ^ rhs.ulonga; - ret.ulongb = lhs.ulongb ^ rhs.ulongb; - return ret; + return new() + { + ulonga = lhs.ulonga ^ rhs.ulonga, + ulongb = lhs.ulongb ^ rhs.ulongb + }; } /// @@ -1050,7 +1177,7 @@ public static explicit operator UUID(string val) #endregion Operators /// An UUID with a value of all zeroes - public static readonly UUID Zero = new UUID(); + public static readonly UUID Zero = new(); /// A cache of UUID.Zero as a string to optimize a common path public static readonly string ZeroString = "00000000-0000-0000-0000-000000000000"; diff --git a/OpenMetaverseTypes/Utils.cs b/OpenMetaverseTypes/Utils.cs index d1bff1a9..465db3ca 100644 --- a/OpenMetaverseTypes/Utils.cs +++ b/OpenMetaverseTypes/Utils.cs @@ -34,45 +34,17 @@ namespace OpenMetaverse { public static partial class Utils { - /// - /// Operating system - /// - public enum Platform - { - /// Unknown - Unknown, - /// Microsoft Windows - Windows, - /// Microsoft Windows CE - WindowsCE, - /// Linux - Linux, - /// Apple OSX - OSX - } - - /// - /// Runtime platform - /// - public enum Runtime - { - /// .NET runtime - Windows, - /// Mono runtime: http://www.mono-project.com/ - Mono - } - - public const float E = (float)Math.E; + public const float E = MathF.E; public const float LOG10E = 0.4342945f; public const float LOG2E = 1.442695f; - public const float PI = (float)Math.PI; - public const float TWO_PI = (float)(Math.PI * 2.0d); - public const float PI_OVER_TWO = (float)(Math.PI / 2.0d); - public const float PI_OVER_FOUR = (float)(Math.PI / 4.0d); + public const float PI = MathF.PI; + public const float TWO_PI = MathF.PI * 2.0f; + public const float PI_OVER_TWO = MathF.PI / 2.0f; + public const float PI_OVER_FOUR = MathF.PI / 4.0f; /// Used for converting degrees to radians - public const float DEG_TO_RAD = (float)(Math.PI / 180.0d); + public const float DEG_TO_RAD = MathF.PI / 180.0f; /// Used for converting radians to degrees - public const float RAD_TO_DEG = (float)(180.0d / Math.PI); + public const float RAD_TO_DEG = 180.0f / MathF.PI; /// Provide a single instance of the CultureInfo class to /// help parsing in situations where the grid assumes an en-us @@ -377,42 +349,5 @@ public static double RandomDouble() } #endregion Math - - #region Platform - - /// - /// Get the current running platform - /// - /// Enumeration of the current platform we are running on - public static Platform GetRunningPlatform() - { - const string OSX_CHECK_FILE = "/Library/Extensions.kextcache"; - switch(Environment.OSVersion.Platform) - { - case PlatformID.WinCE: - return Platform.WindowsCE; - case PlatformID.Unix: - case PlatformID.MacOSX: - { - if (System.IO.File.Exists(OSX_CHECK_FILE)) - return Platform.OSX; - else - return Platform.Linux; - } - default: - return Platform.Windows; - } - } - - /// - /// Get the current running runtime - /// - /// Enumeration of the current runtime we are running on - public static Runtime GetRunningRuntime() - { - return (Type.GetType("Mono.Runtime") == null) ? Runtime.Windows : Runtime.Mono; - } - - #endregion Platform } } diff --git a/OpenMetaverseTypes/UtilsConversions.cs b/OpenMetaverseTypes/UtilsConversions.cs index f7012f6f..5b51b212 100644 --- a/OpenMetaverseTypes/UtilsConversions.cs +++ b/OpenMetaverseTypes/UtilsConversions.cs @@ -32,6 +32,9 @@ using System.Reflection; using System.IO; using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics.X86; +using System.Runtime.Intrinsics; namespace OpenMetaverse { @@ -39,7 +42,19 @@ public static partial class Utils { // public static readonly bool NoAlignment = CheckNeedAlignment(); public static readonly bool CanDirectCopyLE = CheckNeedAlignment(); -// public static readonly bool CanDirectCopyBE = CheckDirectCopyBE(); + //public static readonly bool CanDirectCopyBE = CheckDirectCopyBE(); + + [StructLayout(LayoutKind.Sequential, Size = 16, Pack = 1)] + public struct Bytes16 { } + + [StructLayout(LayoutKind.Sequential, Size = 12, Pack = 1)] + public struct Bytes12 { } + + [StructLayout(LayoutKind.Sequential, Size = 8, Pack = 1)] + public struct Bytes8 { } + + [StructLayout(LayoutKind.Sequential, Size = 6, Pack = 1)] + public struct Bytes6 { } public unsafe static bool CheckNeedAlignment() { @@ -322,17 +337,16 @@ static bool CheckDirectCopyBE() #endregion String Arrays - #region BytesTo [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool ApproxEqual(float a, float b, float tolerance, float reltolerance = float.Epsilon) { - float dif = Math.Abs(a - b); + float dif = MathF.Abs(a - b); if (dif <= tolerance) return true; - a = Math.Abs(a); - b = Math.Abs(b); + a = MathF.Abs(a); + b = MathF.Abs(b); if (b > a) a = b; return dif <= a * reltolerance; @@ -341,24 +355,24 @@ public static bool ApproxEqual(float a, float b, float tolerance, float reltoler [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool ApproxZero(float a, float tolerance) { - return Math.Abs(a) <= tolerance; + return MathF.Abs(a) <= tolerance; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool ApproxZero(float a) { - return Math.Abs(a) <= 1e-6; + return MathF.Abs(a) <= 1e-6; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool ApproxEqual(float a, float b) { - float dif = Math.Abs(a - b); + float dif = MathF.Abs(a - b); if (dif <= 1e-6f) return true; - a = Math.Abs(a); - b = Math.Abs(b); + a = MathF.Abs(a); + b = MathF.Abs(b); if (b > a) a = b; return dif <= a * float.Epsilon; @@ -384,13 +398,14 @@ public static unsafe short BytesToInt16(byte[] bytes) //if (bytes.Length < 2 ) return 0; if (CanDirectCopyLE) { - fixed (byte* p = bytes) - return *(short*)p; + return Unsafe.As(ref MemoryMarshal.GetArrayDataReference(bytes)); } else return (short)(bytes[0] | (bytes[1] << 8)); } + #region BytesTo + /// /// Convert the first two bytes starting at the given position in /// little endian ordering to a signed short integer @@ -405,8 +420,7 @@ public static unsafe short BytesToInt16(byte[] bytes, int pos) //if (bytes.Length < pos + 2) return 0; if (CanDirectCopyLE) { - fixed (byte* p = &bytes[pos]) - return *(short*)p; + return Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(bytes), pos)); } else return (short)(bytes[pos] | (bytes[pos + 1] << 8)); @@ -437,9 +451,8 @@ public unsafe static int BytesToInt(byte[] bytes, int pos) { if (CanDirectCopyLE) { - if (bytes.Length < pos + 4) return 0; - fixed (byte* p = &bytes[pos]) - return *(int*)p; + //if (bytes.Length < pos + 4) return 0; + return Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(bytes), pos)); } return bytes[pos] | @@ -467,8 +480,7 @@ public unsafe static int BytesToIntSafepos(byte[] bytes, int pos) { if (CanDirectCopyLE) { - fixed (byte* p = &bytes[pos]) - return *(int*)p; + return Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(bytes), pos)); } return bytes[pos] | @@ -489,8 +501,7 @@ public unsafe static int BytesToInt(byte[] bytes) { if (CanDirectCopyLE) { - fixed (byte* p = bytes) - return *(int*)p; + return Unsafe.As(ref MemoryMarshal.GetArrayDataReference(bytes)); } else return bytes[0] | @@ -529,8 +540,7 @@ public unsafe static long BytesToInt64(byte[] bytes) { if (CanDirectCopyLE) { - fixed (byte* p = bytes) - return *(long*)p; + return Unsafe.As(ref MemoryMarshal.GetArrayDataReference(bytes)); } else return @@ -591,8 +601,7 @@ public unsafe static long BytesToInt64(byte[] bytes, int pos) if (CanDirectCopyLE) { if (bytes.Length < pos + 8) return 0; - fixed (byte* p = &bytes[pos]) - return *(long*)p; + return Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(bytes), pos)); } else return @@ -611,8 +620,7 @@ public unsafe static long BytesToInt64Safepos(byte[] bytes, int pos) { if (CanDirectCopyLE) { - fixed (byte* p = &bytes[pos]) - return *(long*)p; + return Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(bytes), pos)); } else return @@ -640,8 +648,7 @@ public static unsafe ushort BytesToUInt16(byte[] bytes, int pos) //if (bytes.Length < pos + 2) return 0; if (CanDirectCopyLE) { - fixed (byte* p = &bytes[pos]) - return *(ushort*)p; + return Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(bytes), pos)); } else return (ushort)(bytes[pos] + (bytes[pos + 1] << 8)); @@ -669,8 +676,7 @@ public static unsafe ushort BytesToUInt16(byte[] bytes) //if (bytes.Length < 2) return 0; if (CanDirectCopyLE) { - fixed (byte* p = bytes) - return *(ushort*)p; + return Unsafe.As(ref MemoryMarshal.GetArrayDataReference(bytes)); } else return (ushort)(bytes[0] + (bytes[1] << 8)); @@ -690,8 +696,7 @@ public unsafe static uint BytesToUInt(byte[] bytes, int pos) if (CanDirectCopyLE) { if (bytes.Length < pos + 4) return 0; - fixed (byte* p = &bytes[pos]) - return *(uint*)p; + return Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(bytes), pos)); } else return (uint)( @@ -706,8 +711,7 @@ public unsafe static uint BytesToUIntSafepos(byte[] bytes, int pos) { if (CanDirectCopyLE) { - fixed (byte* p = &bytes[pos]) - return *(uint*)p; + return Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(bytes), pos)); } else return (uint)( @@ -729,8 +733,7 @@ public unsafe static uint BytesToUInt(byte[] bytes) { if (CanDirectCopyLE) { - fixed (byte* p = bytes) - return *(uint*)p; + return Unsafe.As(ref MemoryMarshal.GetArrayDataReference(bytes)); } else return (uint)( @@ -768,9 +771,7 @@ public unsafe static ulong BytesToUInt64(byte[] bytes, int pos) if (bytes.Length < pos + 8) return 0; if (CanDirectCopyLE) { - //return Unsafe.As(ref bytes[pos]); - fixed (byte* p = &bytes[pos]) - return *(ulong*)p; + return Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(bytes), pos)); } else return (ulong)( @@ -789,8 +790,7 @@ public unsafe static ulong BytesToUInt64Safepos(byte[] bytes, int pos) { if (CanDirectCopyLE) { - fixed (byte* p = &bytes[pos]) - return *(ulong*)p; + return Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(bytes), pos)); } else return (ulong)( @@ -816,8 +816,7 @@ public unsafe static ulong BytesToUInt64(byte[] bytes) { if (CanDirectCopyLE) { - fixed (byte* p = bytes) - return *(ulong*)p; + return Unsafe.As(ref MemoryMarshal.GetArrayDataReference(bytes)); } else return (ulong)( @@ -862,9 +861,7 @@ public unsafe static ulong BytesToUInt64(byte* bytes) [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static float BytesToFloat(byte[] bytes) { - int tmp = BytesToInt(bytes); - return *(float*)&tmp; - //return Unsafe.As(ref bytes[0]); + return Unsafe.As(ref MemoryMarshal.GetArrayDataReference(bytes)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -877,22 +874,19 @@ public unsafe static float BytesToFloat(byte* bytes) [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static float BytesToFloat(byte[] bytes, int pos) { - int tmp = BytesToInt(bytes, pos); - return *(float*)&tmp; + return Unsafe.As(ref bytes[pos]); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static float BytesToFloatSafepos(byte[] bytes, int pos) { - int tmp = BytesToIntSafepos(bytes, pos); - return *(float*)&tmp; + return Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(bytes), pos)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static double BytesToDouble(byte[] bytes) { - long tmp = BytesToInt64(bytes); - return *(double*)&tmp; + return Unsafe.As(ref MemoryMarshal.GetArrayDataReference(bytes)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -912,20 +906,18 @@ public unsafe static double BytesToDouble(byte* bytes) [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static double BytesToDouble(byte[] bytes, int pos) { - long tmp = BytesToInt64(bytes, pos); - return *(double*)&tmp; + return Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(bytes), pos)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static double BytesToDoubleSafepos(byte[] bytes, int pos) { - long tmp = BytesToInt64Safepos(bytes, pos); - return *(double*)&tmp; + return Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(bytes), pos)); } #endregion BytesTo - #region ToBytes + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static byte[] Int16ToBytes(short value) { @@ -945,24 +937,20 @@ public static void Int16ToBytes(Stream ms, short value) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Int16ToBytes(short value, byte[] dest, int pos) { - dest[pos] = (byte)value; - dest[pos + 1] = (byte)(value >> 8); + Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(dest), pos)) = value; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static unsafe void Int16ToBytes(short value, byte* dest) { *(short*)dest = value; - //*dest = (byte)value; - //dest[1] = (byte)(value >> 8); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static unsafe void Int16ToBytes(short value, byte* dest, int pos) { + *(short*)dest[pos] = value; - //*dest = (byte)value; - //dest[1] = (byte)(value >> 8); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -977,9 +965,8 @@ public static byte[] UInt16ToBytes(ushort value) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void UInt16ToBytes(ushort value, byte[] dest, int pos) { - //Unsafe.As(ref dest[pos]) = value; - dest[pos] = (byte)value; - dest[pos + 1] = (byte)(value >> 8); + Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(dest), pos)) = value; + } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -1035,6 +1022,7 @@ public unsafe static byte[] IntToBytes(int value) byte[] bytes = new byte[4]; if (CanDirectCopyLE) { + //Unsafe.As(ref bytes[0]) = value; fixed (byte* p = bytes) *(int*)p = value; } @@ -1054,9 +1042,7 @@ public unsafe static void IntToBytes(int value, byte[] dest, int pos) if (dest.Length < pos + 4) return; if (CanDirectCopyLE) { - //Unsafe.As(ref dest[pos]) = value; - fixed (byte* p = &dest[pos]) - *(int*)p = value; + Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(dest), pos)) = value; } else { @@ -1103,8 +1089,7 @@ public unsafe static void IntToBytesSafepos(int value, byte[] dest, int pos) { if (CanDirectCopyLE) { - fixed (byte* p = &dest[pos]) - *(int*)p = value; + Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(dest), pos)) = value; } else { @@ -1208,8 +1193,7 @@ public unsafe static byte[] Int64ToBytes(long value) byte[] bytes = new byte[8]; if (CanDirectCopyLE) { - fixed (byte* p = bytes) - *(long*)p = value; + Unsafe.As(ref MemoryMarshal.GetArrayDataReference(bytes)) = value; } else { @@ -1230,9 +1214,9 @@ public unsafe static void Int64ToBytes(long value, byte[] dest, int pos) { if (CanDirectCopyLE) { + //Unsafe.As(ref dest[pos]) = value; if (dest.Length < pos + 8) return; - fixed (byte* p = &dest[pos]) - *(long*)p = value; + Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(dest), pos)) = value; } else { @@ -1252,7 +1236,6 @@ public unsafe static void Int64ToBytes(long value, byte* dest, int pos) { if (CanDirectCopyLE) { - //Unsafe.As(ref dest[pos]) = value; *(long*)dest[pos] = value; } else @@ -1293,8 +1276,7 @@ public unsafe static void Int64ToBytesSafepos(long value, byte[] dest, int pos) { if (CanDirectCopyLE) { - fixed (byte* p = &dest[pos]) - *(long*)p = value; + Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(dest), pos)) = value; } else { @@ -1446,8 +1428,7 @@ public unsafe static void FloatToBytes(Stream ms, float value) [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void FloatToBytes(float value, byte[] dest, int pos) { - //Unsafe.As(ref dest[pos]) = value; - IntToBytes(*(int*)&value, dest, pos); + Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(dest), pos)) = value; } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -1466,7 +1447,7 @@ public unsafe static void FloatToBytes(float value, byte* dest) [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void FloatToBytesSafepos(float value, byte[] dest, int pos) { - IntToBytesSafepos(*(int*)&value, dest, pos); + Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(dest), pos)) = value; } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -1490,7 +1471,7 @@ public unsafe static byte[] DoubleToBytesBig(double value) [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void DoubleToBytes(double value, byte[] dest, int pos) { - Int64ToBytes(*(long*)&value, dest, pos); + Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(dest), pos)) = value; } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -1508,7 +1489,7 @@ public unsafe static void DoubleToBytes(double value, byte* dest) [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void DoubleToBytesSafepos(double value, byte[] dest, int pos) { - Int64ToBytesSafepos(*(long*)&value, dest, pos); + Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(dest), pos)) = value; } #endregion ToBytes @@ -1835,14 +1816,15 @@ public static unsafe bool osUTF8TryGetbytes(string srcstr, ref int srcstart, byt return ret; } - public static int osUTF8GetBytesCount(string str, out int maxsource) + public static int osUTF8GetBytesCount(string sstr, out int maxsource) { maxsource = 0; char c; char lastc = (char)0; int nbytes = 0; int i = 0; - while(i < str.Length) + var str = sstr.AsSpan(); + while (i < str.Length) { c = str[i++]; @@ -1886,16 +1868,17 @@ public static int osUTF8GetBytesCount(string str, out int maxsource) return nbytes; } - public static int osUTF8GetBytesCount(string str, int maxnbytes, out int maxsourcelen) + public static int osUTF8GetBytesCount(string sstr, int maxnbytes, out int maxsourcelen) { maxsourcelen = 0; int max2 = maxnbytes - 2; int max3 = maxnbytes - 3; int max4 = maxnbytes - 4; - char c = ' '; + char c; int nbytes = 0; int i = 0; + var str = sstr.AsSpan(); while(i < str.Length && nbytes < maxnbytes) { c = str[i++]; @@ -2108,7 +2091,7 @@ public unsafe static byte HexToByte(byte* data, int pos) return (byte)(HexNibble(data[pos]) << 4 | HexNibble(data[pos + 1])); } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static byte HexToByte(char* hex, int pos) { return (byte)(HexNibble(hex[pos]) << 4 | HexNibble(hex[pos + 1])); @@ -2524,7 +2507,7 @@ public static byte[] CopyBytes(byte[] bytes) return null; byte[] newBytes = new byte[bytes.Length]; - Buffer.BlockCopy(bytes, 0, newBytes, 0, bytes.Length); + Array.Copy(bytes, newBytes, bytes.Length); return newBytes; } @@ -2623,9 +2606,7 @@ public static uint DateTimeToUnixTime(DateTime time) /// Second value public static void Swap(ref T lhs, ref T rhs) { - T temp = lhs; - lhs = rhs; - rhs = temp; + (rhs, lhs) = (lhs, rhs); } /// diff --git a/OpenMetaverseTypes/Vector2.cs b/OpenMetaverseTypes/Vector2.cs index 201bc0a6..b9d11f01 100644 --- a/OpenMetaverseTypes/Vector2.cs +++ b/OpenMetaverseTypes/Vector2.cs @@ -28,6 +28,7 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Globalization; +using System.Text; namespace OpenMetaverse { @@ -156,6 +157,16 @@ public bool IsZero() return true; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool IsNotZero() + { + if (X != 0) + return true; + if (Y != 0) + return true; + return false; + } + /// /// Test if this vector is composed of all finite numbers /// @@ -239,7 +250,7 @@ public unsafe void ToBytes(byte* dest) [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public float Length() { - return (float)Math.Sqrt(X * X + Y * Y); + return MathF.Sqrt(X * X + Y * Y); } [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] @@ -254,7 +265,7 @@ public void Normalize() float factor = LengthSquared(); if (factor > 1e-6) { - factor = 1f / (float)Math.Sqrt(factor); + factor = 1f / MathF.Sqrt(factor); X *= factor; Y *= factor; } @@ -294,7 +305,7 @@ public static Vector2 Clamp(Vector2 value1, Vector2 min, Vector2 max) [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public static float Distance(Vector2 value1, Vector2 value2) { - return (float)Math.Sqrt(DistanceSquared(value1, value2)); + return MathF.Sqrt(DistanceSquared(value1, value2)); } [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] @@ -335,16 +346,16 @@ public static Vector2 Lerp(Vector2 value1, Vector2 value2, float amount) public static Vector2 Max(Vector2 value1, Vector2 value2) { return new Vector2( - Math.Max(value1.X, value2.X), - Math.Max(value1.Y, value2.Y)); + MathF.Max(value1.X, value2.X), + MathF.Max(value1.Y, value2.Y)); } [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public static Vector2 Min(Vector2 value1, Vector2 value2) { return new Vector2( - Math.Min(value1.X, value2.X), - Math.Min(value1.Y, value2.Y)); + MathF.Min(value1.X, value2.X), + MathF.Min(value1.Y, value2.Y)); } [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] @@ -365,13 +376,13 @@ public static Vector2 Negate(Vector2 value) return new Vector2(-value.X, -value.Y); } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 Normalize(Vector2 value) { float factor = value.LengthSquared(); if (factor > 1e-6) { - factor = 1f / (float)Math.Sqrt(factor); + factor = 1f / MathF.Sqrt(factor); return new Vector2(value.X * factor, value.Y * factor); } return new Vector2(); @@ -382,29 +393,129 @@ public static Vector2 Normalize(Vector2 value) /// /// A string representation of a 2D vector, enclosed /// in arrow brackets and separated by commas - public static Vector2 Parse(string val) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static unsafe Vector2 Parse(string val) { - char[] splitChar = { ',' }; - string[] split = val.Replace("<", String.Empty).Replace(">", String.Empty).Split(splitChar); - return new Vector2( - float.Parse(split[0].Trim(), Utils.EnUsCulture), - float.Parse(split[1].Trim(), Utils.EnUsCulture)); + return Parse(val.AsSpan()); } - public static bool TryParse(string val, out Vector2 result) + public static unsafe Vector2 Parse(ReadOnlySpan sp) { - try + if (sp.Length < 5) + throw new FormatException("Invalid Vector2"); + + int start = 0; + fixed (char* p = sp) { - result = Parse(val); - return true; + while (start < sp.Length) + { + if (p[start++] == '<') + break; + } + if (start > sp.Length - 4) + throw new FormatException("Invalid Vector2"); + + int comma1 = start + 1; + while (comma1 < sp.Length) + { + if (p[comma1] == ',') + break; + comma1++; + } + if (comma1 > sp.Length - 3) + throw new FormatException("Invalid Vector2"); + + if (!float.TryParse(sp[start..comma1], NumberStyles.Float, Utils.EnUsCulture, out float x)) + throw new FormatException("Invalid Vector2"); + + comma1++; + start = comma1; + comma1++; + while (comma1 < sp.Length) + { + if (p[comma1] == '>') + break; + comma1++; + } + if (comma1 > sp.Length) + throw new FormatException("Invalid Vector2"); + if (!float.TryParse(sp[start..comma1], NumberStyles.Float, Utils.EnUsCulture, out float y)) + throw new FormatException("Invalid Vector2"); + + return new Vector2(x, y); } - catch (Exception) + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static bool TryParse(string val, out Vector2 result) + { + return TryParse(val.AsSpan(), out result); + } + public unsafe static bool TryParse(ReadOnlySpan sp, out Vector2 result) + { + if (sp.Length < 5) { - result = new Vector2(); + result = Zero; return false; } - } + int start = 0; + fixed (char* p = sp) + { + while (start < sp.Length) + { + if (p[start++] == '<') + break; + } + if (start > sp.Length - 4) + { + result = Zero; + return false; + } + + int comma1 = start + 1; + while (comma1 < sp.Length) + { + if (p[comma1] == ',') + break; + comma1++; + } + if (comma1 > sp.Length - 3) + { + result = Zero; + return false; + } + + if (!float.TryParse(sp[start..comma1], NumberStyles.Float, Utils.EnUsCulture, out float x)) + { + result = Zero; + return false; + } + + comma1++; + start = comma1; + comma1++; + while (comma1 < sp.Length) + { + if (p[comma1] == '>') + break; + comma1++; + } + if (comma1 > sp.Length) + { + result = Zero; + return false; + } + if (!float.TryParse(sp[start..comma1], NumberStyles.Float, Utils.EnUsCulture, out float y)) + { + result = Zero; + return false; + } + + result = new Vector2(x, y); + return true; + } + } /// /// Interpolates between two vectors using a cubic equation /// @@ -486,7 +597,13 @@ public override int GetHashCode() /// A string representation of the vector public override string ToString() { - return String.Format(Utils.EnUsCulture, "<{0}, {1}>", X, Y); + StringBuilder sb = new(); + sb.Append('<'); + sb.Append(X.ToString(Utils.EnUsCulture)); + sb.Append(", "); + sb.Append(Y.ToString(Utils.EnUsCulture)); + sb.Append('>'); + return sb.ToString(); } /// @@ -499,7 +616,12 @@ public string ToRawString() CultureInfo enUs = new CultureInfo("en-us"); enUs.NumberFormat.NumberDecimalDigits = 3; - return String.Format(enUs, "{0} {1}", X, Y); + StringBuilder sb = new(); + sb.Append(X.ToString(enUs)); + sb.Append(' '); + sb.Append(Y.ToString(enUs)); + sb.Append(' '); + return sb.ToString(); } #endregion Overrides diff --git a/OpenMetaverseTypes/Vector3.cs b/OpenMetaverseTypes/Vector3.cs index 9d14dbbc..cdd7b7eb 100644 --- a/OpenMetaverseTypes/Vector3.cs +++ b/OpenMetaverseTypes/Vector3.cs @@ -28,6 +28,10 @@ using System.Globalization; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; +using System.Runtime.Intrinsics.X86; +using System.Runtime.Intrinsics; +using System.Text; +using System.Collections; namespace OpenMetaverse { @@ -38,13 +42,13 @@ namespace OpenMetaverse [StructLayout(LayoutKind.Sequential)] public struct Vector3 : IComparable, IEquatable { - /// X value + /// x value public float X; /// Y value public float Y; /// Z value public float Z; - + #region Constructors [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -166,13 +170,13 @@ public void Clamp(float min, float max) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public float Length() + public readonly float Length() { - return (float)Math.Sqrt(X * X + Y * Y + Z * Z); + return MathF.Sqrt(X * X + Y * Y + Z * Z); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public float LengthSquared() + public readonly float LengthSquared() { return (X * X + Y * Y + Z * Z); } @@ -183,7 +187,7 @@ public void Normalize() float factor = X * X + Y * Y + Z * Z; if (factor > 1e-6f) { - factor = 1f / (float)Math.Sqrt(factor); + factor = 1f / MathF.Sqrt(factor); X *= factor; Y *= factor; Z *= factor; @@ -197,7 +201,7 @@ public void Normalize() } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool ApproxEquals(Vector3 vec) + public readonly bool ApproxEquals(Vector3 vec) { return Utils.ApproxEqual(X, vec.X) && Utils.ApproxEqual(Y, vec.Y) && @@ -214,7 +218,7 @@ public bool ApproxEquals(Vector3 vec) /// True if the magnitude of difference between the two vectors /// is less than the given tolerance, otherwise false [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool ApproxEquals(Vector3 vec, float tolerance) + public readonly bool ApproxEquals(Vector3 vec, float tolerance) { return Utils.ApproxEqual(X, vec.X, tolerance) && Utils.ApproxEqual(Y, vec.Y, tolerance) && @@ -223,7 +227,7 @@ public bool ApproxEquals(Vector3 vec, float tolerance) [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool ApproxZero() + public readonly bool ApproxZero() { if (!Utils.ApproxZero(X)) return false; @@ -235,7 +239,7 @@ public bool ApproxZero() } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool ApproxZero(float tolerance) + public readonly bool ApproxZero(float tolerance) { if (!Utils.ApproxZero(X, tolerance)) return false; @@ -247,7 +251,7 @@ public bool ApproxZero(float tolerance) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool IsZero() + public readonly bool IsZero() { if (X != 0) return false; @@ -258,26 +262,41 @@ public bool IsZero() return true; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public readonly bool IsNotZero() + { + if (X != 0) + return true; + if (Y != 0) + return true; + if (Z != 0) + return true; + return false; + } + /// /// IComparable.CompareTo implementation /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public int CompareTo(Vector3 vector) + public readonly int CompareTo(Vector3 vector) { return LengthSquared().CompareTo(vector.LengthSquared()); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public float Dot(Vector3 value2) + public readonly float Dot(Vector3 value2) { return (X * value2.X) + (Y * value2.Y) + (Z * value2.Z); } - + public readonly float AbsDot(Vector3 value2) + { + return MathF.Abs(X * value2.X) + MathF.Abs(Y * value2.Y) + MathF.Abs(Z * value2.Z); + } /// /// Test if this vector is composed of all finite numbers /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool IsFinite() + public readonly bool IsFinite() { return (Utils.IsFinite(X) && Utils.IsFinite(Y) && Utils.IsFinite(Z)); } @@ -287,12 +306,16 @@ public bool IsFinite() /// /// Byte array containing a 12 byte vector /// Beginning position in the byte array + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void FromBytes(byte[] byteArray) + { + this = Unsafe.ReadUnaligned(ref MemoryMarshal.GetArrayDataReference(byteArray)); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void FromBytes(byte[] byteArray, int pos) { - X = Utils.BytesToFloatSafepos(byteArray, pos); - Y = Utils.BytesToFloatSafepos(byteArray, pos + 4); - Z = Utils.BytesToFloatSafepos(byteArray, pos + 8); + this = Unsafe.ReadUnaligned(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(byteArray), pos)); } /// @@ -300,12 +323,10 @@ public void FromBytes(byte[] byteArray, int pos) /// /// A 12 byte array containing X, Y, and Z [MethodImpl(MethodImplOptions.AggressiveInlining)] - public byte[] GetBytes() + public readonly byte[] GetBytes() { byte[] dest = new byte[12]; - Utils.FloatToBytesSafepos(X, dest, 0); - Utils.FloatToBytesSafepos(Y, dest, 4); - Utils.FloatToBytesSafepos(Z, dest, 8); + Unsafe.WriteUnaligned(ref MemoryMarshal.GetArrayDataReference(dest), this); return dest; } @@ -316,7 +337,7 @@ public byte[] GetBytes() /// Position in the destination array to start /// writing. Must be at least 12 bytes before the end of the array [MethodImpl(MethodImplOptions.AggressiveInlining)] - public unsafe void ToBytes(byte[] dest, int pos) + public readonly unsafe void ToBytes(byte[] dest, int pos) { if (Utils.CanDirectCopyLE) { @@ -332,7 +353,7 @@ public unsafe void ToBytes(byte[] dest, int pos) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public unsafe void ToBytes(byte* dest) + public readonly unsafe void ToBytes(byte* dest) { if (Utils.CanDirectCopyLE) *(Vector3*)dest = this; @@ -345,15 +366,15 @@ public unsafe void ToBytes(byte* dest) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public unsafe void ClampedToShortsBytes(float range, byte[] dest, int pos) + public readonly unsafe void ClampedToShortsBytes(float range, byte[] dest, int pos) { float a, b; - a = Math.Abs(X); - b = Math.Abs(Y); + a = MathF.Abs(X); + b = MathF.Abs(Y); if (b > a) a = b; - b = Math.Abs(Z); + b = MathF.Abs(Z); if (b > a) a = b; @@ -390,15 +411,15 @@ public unsafe void ClampedToShortsBytes(float range, byte[] dest, int pos) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public unsafe void ClampedToShortsBytes(float range, byte* dest, int pos) + public readonly unsafe void ClampedToShortsBytes(float range, byte* dest, int pos) { float a, b; - a = Math.Abs(X); - b = Math.Abs(Y); + a = MathF.Abs(X); + b = MathF.Abs(Y); if (b > a) a = b; - b = Math.Abs(Z); + b = MathF.Abs(Z); if (b > a) a = b; @@ -432,15 +453,15 @@ public unsafe void ClampedToShortsBytes(float range, byte* dest, int pos) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public unsafe void ClampedToShortsBytes(float range, byte* dest) + public readonly unsafe void ClampedToShortsBytes(float range, byte* dest) { float a, b; - a = Math.Abs(X); - b = Math.Abs(Y); + a = MathF.Abs(X); + b = MathF.Abs(Y); if (b > a) a = b; - b = Math.Abs(Z); + b = MathF.Abs(Z); if (b > a) a = b; @@ -473,6 +494,117 @@ public unsafe void ClampedToShortsBytes(float range, byte* dest) } } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Rotate(Quaternion rot) + { + float x2 = rot.X + rot.X; + float y2 = rot.Y + rot.Y; + float z2 = rot.Z + rot.Z; + + float wx2 = rot.W * x2; + float wy2 = rot.W * y2; + float wz2 = rot.W * z2; + float xx2 = rot.X * x2; + float xy2 = rot.X * y2; + float xz2 = rot.X * z2; + float yy2 = rot.Y * y2; + float yz2 = rot.Y * z2; + float zz2 = rot.Z * z2; + + x2 = X; + y2 = Y; + z2 = Z; + + X = x2 * (1.0f - yy2 - zz2) + y2 * (xy2 - wz2) + z2 * (xz2 + wy2); + Y = x2 * (xy2 + wz2) + y2 * (1.0f - xx2 - zz2) + z2 * (yz2 - wx2); + Z = x2 * (xz2 - wy2) + y2 * (yz2 + wx2) + z2 * (1.0f - xx2 - yy2); + } + + public void InverseRotate(Quaternion rot) + { + float x2 = rot.X + rot.X; + float y2 = rot.Y + rot.Y; + float z2 = rot.Z + rot.Z; + + float wx2 = rot.W * x2; + float wy2 = rot.W * y2; + float wz2 = rot.W * z2; + + float xx2 = rot.X * x2; + float xy2 = rot.X * y2; + float xz2 = rot.X * z2; + float yy2 = rot.Y * y2; + float yz2 = rot.Y * z2; + float zz2 = rot.Z * z2; + + x2 = X; + y2 = Y; + z2 = Z; + + X = x2 * (1.0f - yy2 - zz2) + y2 * (xy2 + wz2) + z2 * (xz2 - wy2); + Y = x2 * (xy2 - wz2) + y2 * (1.0f - xx2 - zz2) + z2 * (yz2 + wx2); + Z = x2 * (xz2 + wy2) + y2 * (yz2 - wx2) + z2 * (1.0f - xx2 - yy2); + } + + //quaternion must be normalized <0,0,z,w> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void RotateByQZ(Quaternion rot) + { + float z2 = rot.Z + rot.Z; + float zz2 = 1.0f - rot.Z * z2; + float wz2 = rot.W * z2; + + float ox = X; + float oy = Y; + + X = ox * zz2 - oy * wz2; + Y = ox * wz2 + oy * zz2; + } + + //quaternion must be normalized <0,0,z,w> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void InverseRotateByQZ(Quaternion rot) + { + float z2 = rot.Z + rot.Z; + float zz2 = 1.0f - rot.Z * z2; + float wz2 = rot.W * z2; + + float ox = X; + float oy = Y; + + X = ox * zz2 + oy * wz2; + Y = oy * zz2 - ox * wz2; + } + + //shortQuaternion must be normalized + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void RotateByShortQZ(Vector2 shortQuaternion) + { + float z2 = shortQuaternion.X + shortQuaternion.X; + float zz2 = 1.0f - shortQuaternion.X * z2; + float wz2 = shortQuaternion.Y * z2; + + float ox = X; + float oy = Y; + + X = ox * zz2 - oy * wz2; + Y = ox * wz2 + oy * zz2; + } + + //quaternion must be normalized <0,0,z,w> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void InverseRotateByShortQZ(Vector2 shortQuaternion) + { + float z2 = shortQuaternion.X + shortQuaternion.X; + float zz2 = 1.0f - shortQuaternion.X * z2; + float wz2 = shortQuaternion.Y * z2; + + float ox = X; + float oy = Y; + + X = ox * zz2 + oy * wz2; + Y = oy * zz2 - ox * wz2; + } #endregion Public Methods #region Static Methods @@ -482,6 +614,12 @@ public static Vector3 Add(Vector3 value1, Vector3 value2) return new Vector3(value1.X + value2.X, value1.Y + value2.Y, value1.Z + value2.Z); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector3 Abs(Vector3 value1) + { + return new Vector3(MathF.Abs(value1.X), MathF.Abs(value1.Y), MathF.Abs(value1.Z)); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 Clamp(Vector3 value1, float min, float max) { @@ -509,6 +647,7 @@ public static Vector3 Cross(Vector3 value1, Vector3 value2) value1.X * value2.Y - value2.X * value1.Y); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static float Distance(Vector3 value1, Vector3 value2) { return (float)Math.Sqrt(DistanceSquared(value1, value2)); @@ -543,6 +682,12 @@ public static float Dot(Vector3 value1, Vector3 value2) return (value1.X * value2.X) + (value1.Y * value2.Y) + (value1.Z * value2.Z); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float AbsDot(Vector3 value1, Vector3 value2) + { + return MathF.Abs(value1.X * value2.X) + MathF.Abs(value1.Y * value2.Y) + MathF.Abs(value1.Z * value2.Z); + } + public static Vector3 Lerp(Vector3 value1, Vector3 value2, float amount) { return new Vector3( @@ -599,7 +744,7 @@ public static Vector3 Normalize(Vector3 value) float factor = value.LengthSquared(); if (factor > 1e-6f) { - factor = 1f / (float)Math.Sqrt(factor); + factor = 1f / MathF.Sqrt(factor); return value * factor; } return new Vector3(); @@ -610,28 +755,163 @@ public static Vector3 Normalize(Vector3 value) /// /// A string representation of a 3D vector, enclosed /// in arrow brackets and separated by commas - public static Vector3 Parse(string val) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static unsafe Vector3 Parse(string val) { - char[] splitChar = { ',' }; - string[] split = val.Replace("<", String.Empty).Replace(">", String.Empty).Split(splitChar); - return new Vector3( - Single.Parse(split[0].Trim(), Utils.EnUsCulture), - Single.Parse(split[1].Trim(), Utils.EnUsCulture), - Single.Parse(split[2].Trim(), Utils.EnUsCulture)); + return Parse(val.AsSpan()); } - public static bool TryParse(string val, out Vector3 result) + public static unsafe Vector3 Parse(ReadOnlySpan sp) { - try + if (sp.Length < 7) + throw new FormatException("Invalid Vector3"); + + int start = 0; + fixed (char* p = sp) { - result = Parse(val); - return true; + while (start < sp.Length) + { + if (p[start++] == '<') + break; + } + if (start > sp.Length - 6) + throw new FormatException("Invalid Vector3"); + + int comma1 = start + 1; + while (comma1 < sp.Length) + { + if (p[comma1] == ',') + break; + comma1++; + } + if (comma1 > sp.Length - 5) + throw new FormatException("Invalid Vector3"); + + if (!float.TryParse(sp[start..comma1], NumberStyles.Float, Utils.EnUsCulture, out float x)) + throw new FormatException("Invalid Vector3"); + + comma1++; + start = comma1; + comma1++; + while (comma1 < sp.Length) + { + if (p[comma1] == ',') + break; + comma1++; + } + if (comma1 > sp.Length - 3) + throw new FormatException("Invalid Vector3"); + if (!float.TryParse(sp[start..comma1], NumberStyles.Float, Utils.EnUsCulture, out float y)) + throw new FormatException("Invalid Vector3"); + + comma1++; + start = comma1; + comma1++; + while (comma1 < sp.Length) + { + if (p[comma1] == '>') + break; + comma1++; + } + if (comma1 >= sp.Length) + throw new FormatException("Invalid Vector3"); + + if (!float.TryParse(sp[start..comma1], NumberStyles.Float, Utils.EnUsCulture, out float z)) + throw new FormatException("Invalid Vector3"); + return new Vector3(x, y, z); } - catch (Exception) + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static bool TryParse(string val, out Vector3 result) + { + return TryParse(val.AsSpan(), out result); + } + + public unsafe static bool TryParse(ReadOnlySpan sp, out Vector3 result) + { + if (sp.Length < 7) { - result = Vector3.Zero; + result = Zero; return false; } + + int start = 0; + fixed (char* p = sp) + { + while (start < sp.Length) + { + if (p[start++] == '<') + break; + } + if (start > sp.Length - 6) + { + result = Zero; + return false; + } + + int comma1 = start + 1; + while (comma1 < sp.Length) + { + if (p[comma1] == ',') + break; + comma1++; + } + if (comma1 > sp.Length - 5) + { + result = Zero; + return false; + } + + if (!float.TryParse(sp[start..comma1], NumberStyles.Float, Utils.EnUsCulture, out float x)) + { + result = Zero; + return false; + } + + comma1++; + start = comma1; + comma1++; + while (comma1 < sp.Length) + { + if (p[comma1] == ',') + break; + comma1++; + } + if (comma1 > sp.Length - 3) + { + result = Zero; + return false; + } + if (!float.TryParse(sp[start..comma1], NumberStyles.Float, Utils.EnUsCulture, out float y)) + { + result = Zero; + return false; + } + + comma1++; + start = comma1; + comma1++; + while (comma1 < sp.Length) + { + if (p[comma1] == '>') + break; + comma1++; + } + if (comma1 >= sp.Length) + { + result = Zero; + return false; + } + + if (!float.TryParse(sp[start..comma1], NumberStyles.Float, Utils.EnUsCulture, out float z)) + { + result = Zero; + return false; + } + result = new Vector3(x, y, z); + return true; + } } /// @@ -641,16 +921,16 @@ public static bool TryParse(string val, out Vector3 result) /// Normalized target vector public static Quaternion RotationBetween(Vector3 a, Vector3 b) { - const double piOverfour = 0.25 * Math.PI; - double magProduct = Math.Sqrt(a.LengthSquared() * b.LengthSquared()); - double angle; + const float piOverfour = 0.25f * MathF.PI; + float magProduct = MathF.Sqrt(a.LengthSquared() * b.LengthSquared()); + float angle; if(magProduct > 1e-6) { float dotProduct = Dot(a, b); - if(dotProduct < 1e-6) + if(dotProduct < 1e-6f) angle = piOverfour; else - angle = 0.5 * Math.Acos(dotProduct / magProduct); + angle = 0.5f * MathF.Acos(dotProduct / magProduct); } else angle = piOverfour; @@ -658,7 +938,7 @@ public static Quaternion RotationBetween(Vector3 a, Vector3 b) Vector3 axis = Cross(a, b); axis.Normalize(); - float s = (float)Math.Sin(angle); + float s = MathF.Sin(angle); return new Quaternion( axis.X * s, axis.Y * s, @@ -683,7 +963,52 @@ public static Vector3 Subtract(Vector3 value1, Vector3 value2) { return new Vector3(value1.X - value2.X, value1.Y - value2.Y, value1.Z - value2.Z); } + /* + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static Vector3 SubtractS(Vector3 value1, Vector3 value2) + { + if (Sse2.IsSupported) + { + Vector128 ma = Sse2.LoadScalarVector128((double*)&value1.X).AsSingle(); + ma = Sse2.Shuffle(ma, Sse2.LoadScalarVector128((float*)&value1.Z), 0x44); + + Vector128 mb = Sse2.LoadScalarVector128((double*)&value2.X).AsSingle(); + mb = Sse2.Shuffle(mb, Sse2.LoadScalarVector128((float*)&value2.Z), 0x44); + + ma = Sse.Subtract(ma, mb); + Vector3 ret = new(); + Sse2.StoreScalar((double*)&ret.X, ma.AsDouble()); + Sse2.StoreScalar(&ret.Z, Sse2.Shuffle(ma.AsInt32(), 0x02).AsSingle()); + return ret; + } + else + return Subtract(value1, value2); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector3 AddS(Vector3 value1, Vector3 value2) + { + if (Sse2.IsSupported) + { + unsafe + { + Vector128 ma = Sse2.LoadScalarVector128((double*)&value1.X).AsSingle(); + ma = Sse2.Shuffle(ma, Sse2.LoadScalarVector128(&value1.Z), 0x44); + Vector128 mb = Sse2.LoadScalarVector128((double*)&value2.X).AsSingle(); + mb = Sse2.Shuffle(mb, Sse2.LoadScalarVector128(&value2.Z), 0x44); + + ma = Sse.Add(ma, mb); + Vector3 ret = new(); + Sse2.StoreScalar((double*)&ret.X, ma.AsDouble()); + Sse2.StoreScalar(&ret.Z, Sse2.Shuffle(ma.AsInt32(), 0x02).AsSingle()); + return ret; + } + } + else + return Subtract(value1, value2); + } + */ public static Vector3 Transform(Vector3 position, Matrix4 matrix) { return new Vector3( @@ -702,6 +1027,12 @@ public static Vector3 TransformNormal(Vector3 position, Matrix4 matrix) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 Transform(Vector3 vec, Quaternion rot) + { + return Rotate(vec, rot); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector3 Rotate(Vector3 vec, Quaternion rot) { float x2 = rot.X + rot.X; float y2 = rot.Y + rot.Y; @@ -727,13 +1058,96 @@ public static Vector3 Transform(Vector3 vec, Quaternion rot) x2 * (xz2 - wy2) + y2 * (yz2 + wx2) + z2 * (1.0f - xx2 - yy2)); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector3 InverseRotate(Vector3 vec, Quaternion rot) + { + float x2 = rot.X + rot.X; + float y2 = rot.Y + rot.Y; + float z2 = rot.Z + rot.Z; + + float wx2 = rot.W * x2; + float wy2 = rot.W * y2; + float wz2 = rot.W * z2; + float xx2 = rot.X * x2; + float xy2 = rot.X * y2; + float xz2 = rot.X * z2; + float yy2 = rot.Y * y2; + float yz2 = rot.Y * z2; + float zz2 = rot.Z * z2; + + x2 = vec.X; + y2 = vec.Y; + z2 = vec.Z; + + return new Vector3( + x2 * (1.0f - yy2 - zz2) + y2 * (xy2 + wz2) + z2 * (xz2 - wy2), + x2 * (xy2 - wz2) + y2 * (1.0f - xx2 - zz2) + z2 * (yz2 + wx2), + x2 * (xz2 + wy2) + y2 * (yz2 - wx2) + z2 * (1.0f - xx2 - yy2)); + } + + + //quaternion must be normalized <0,0,z,w> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector3 RotateByQZ(Vector3 vec, Quaternion rot) + { + float z2 = rot.Z + rot.Z; + float wz2 = rot.W * z2; + float zz2 = 1.0f - rot.Z * z2; + + return new Vector3( + vec.X * zz2 - vec.Y * wz2, + vec.X * wz2 + vec.Y * zz2, + vec.Z);; + } + + //quaternion must be normalized <0,0,z,w> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector3 InverseRotateByQZ(Vector3 vec, Quaternion rot) + { + float z2 = rot.Z + rot.Z; + float wz2 = rot.W * z2; + float zz2 = 1.0f - rot.Z * z2; + + return new Vector3( + vec.X * zz2 + vec.Y * wz2, + vec.Y * zz2 - vec.X * wz2, + vec.Z); + } + + //shortQuaternion must be normalized + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector3 RotateByShortQZ(Vector3 vec, Vector2 shortQuaternion) + { + float z2 = shortQuaternion.X + shortQuaternion.X; + float zz2 = 1.0f - shortQuaternion.X * z2; + float wz2 = shortQuaternion.Y * z2; + + return new Vector3( + vec.X * zz2 - vec.Y * wz2, + vec.X * wz2 + vec.Y * zz2, + vec.Z); ; + } + + //shortQuaternion must be normalized + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector3 InverseRotateByShortQZ(Vector3 vec, Vector2 shortQuaternion) + { + float z2 = shortQuaternion.X + shortQuaternion.X; + float zz2 = 1.0f - shortQuaternion.X * z2; + float wz2 = shortQuaternion.Y * z2; + + return new Vector3( + vec.X * zz2 + vec.Y * wz2, + vec.Y * zz2 - vec.X * wz2, + vec.Z); + } #endregion Static Methods #region Overrides - public override bool Equals(object obj) + public readonly override bool Equals(object obj) { - if (!(obj is Vector3)) + if (obj is not Vector3) return false; Vector3 other = (Vector3)obj; @@ -747,7 +1161,7 @@ public override bool Equals(object obj) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool Equals(Vector3 other) + public readonly bool Equals(Vector3 other) { if (X != other.X) return false; @@ -759,7 +1173,7 @@ public bool Equals(Vector3 other) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool NotEqual(Vector3 other) + public readonly bool NotEqual(Vector3 other) { if (X != other.X) return true; @@ -771,7 +1185,7 @@ public bool NotEqual(Vector3 other) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public override int GetHashCode() + public readonly override int GetHashCode() { int hash = X.GetHashCode(); hash = Utils.CombineHash(hash, Y.GetHashCode()); @@ -783,9 +1197,17 @@ public override int GetHashCode() /// Get a formatted string representation of the vector /// /// A string representation of the vector - public override string ToString() + public readonly override string ToString() { - return String.Format(Utils.EnUsCulture, "<{0}, {1}, {2}>", X, Y, Z); + StringBuilder sb = new(); + sb.Append('<'); + sb.Append(X.ToString(Utils.EnUsCulture)); + sb.Append(", "); + sb.Append(Y.ToString(Utils.EnUsCulture)); + sb.Append(", "); + sb.Append(Z.ToString(Utils.EnUsCulture)); + sb.Append('>'); + return sb.ToString(); } /// @@ -793,12 +1215,18 @@ public override string ToString() /// decimal digits and separated by spaces only /// /// Raw string representation of the vector - public string ToRawString() + public readonly string ToRawString() { CultureInfo enUs = new CultureInfo("en-us"); enUs.NumberFormat.NumberDecimalDigits = 3; - return String.Format(enUs, "{0} {1} {2}", X, Y, Z); + StringBuilder sb = new(); + sb.Append(X.ToString(enUs)); + sb.Append(' '); + sb.Append(Y.ToString(enUs)); + sb.Append(' '); + sb.Append(Z.ToString(enUs)); + return sb.ToString(); } #endregion Overrides @@ -929,16 +1357,16 @@ public static explicit operator Vector3(Vector3d value) #endregion Operators /// A vector with a value of 0,0,0 - public readonly static Vector3 Zero = new Vector3(); + public readonly static Vector3 Zero = new(); /// A vector with a value of 1,1,1 - public readonly static Vector3 One = new Vector3(1f); + public readonly static Vector3 One = new(1f); /// A unit vector facing forward (X axis), value 1,0,0 - public readonly static Vector3 UnitX = new Vector3(1f, 0f, 0f); + public readonly static Vector3 UnitX = new(1f, 0f, 0f); /// A unit vector facing left (Y axis), value 0,1,0 - public readonly static Vector3 UnitY = new Vector3(0f, 1f, 0f); + public readonly static Vector3 UnitY = new(0f, 1f, 0f); /// A unit vector facing up (Z axis), value 0,0,1 - public readonly static Vector3 UnitZ = new Vector3(0f, 0f, 1f); - public readonly static Vector3 MinValue = new Vector3(float.MinValue, float.MinValue, float.MinValue); - public readonly static Vector3 MaxValue = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue); + public readonly static Vector3 UnitZ = new(0f, 0f, 1f); + public readonly static Vector3 MinValue = new(float.MinValue, float.MinValue, float.MinValue); + public readonly static Vector3 MaxValue = new(float.MaxValue, float.MaxValue, float.MaxValue); } } diff --git a/OpenMetaverseTypes/Vector3d.cs b/OpenMetaverseTypes/Vector3d.cs index cd238957..2ff19ffc 100644 --- a/OpenMetaverseTypes/Vector3d.cs +++ b/OpenMetaverseTypes/Vector3d.cs @@ -27,6 +27,8 @@ using System; using System.Runtime.InteropServices; using System.Globalization; +using System.Text; +using System.Runtime.CompilerServices; namespace OpenMetaverse { @@ -308,28 +310,163 @@ public static Vector3d Normalize(Vector3d value) /// /// A string representation of a 3D vector, enclosed /// in arrow brackets and separated by commas - public static Vector3d Parse(string val) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static unsafe Vector3d Parse(string val) { - char[] splitChar = { ',' }; - string[] split = val.Replace("<", String.Empty).Replace(">", String.Empty).Split(splitChar); - return new Vector3d( - Double.Parse(split[0].Trim(), Utils.EnUsCulture), - Double.Parse(split[1].Trim(), Utils.EnUsCulture), - Double.Parse(split[2].Trim(), Utils.EnUsCulture)); + return Parse(val.AsSpan()); } - public static bool TryParse(string val, out Vector3d result) + public static unsafe Vector3d Parse(ReadOnlySpan sp) { - try + if (sp.Length < 7) + throw new FormatException("Invalid Vector3"); + + int start = 0; + fixed (char* p = sp) { - result = Parse(val); - return true; + while (start < sp.Length) + { + if (p[start++] == '<') + break; + } + if (start > sp.Length - 6) + throw new FormatException("Invalid Vector3"); + + int comma1 = start + 1; + while (comma1 < sp.Length) + { + if (p[comma1] == ',') + break; + comma1++; + } + if (comma1 > sp.Length - 5) + throw new FormatException("Invalid Vector3"); + + if (!double.TryParse(sp[start..comma1], NumberStyles.Float, Utils.EnUsCulture, out double x)) + throw new FormatException("Invalid Vector3"); + + comma1++; + start = comma1; + comma1++; + while (comma1 < sp.Length) + { + if (p[comma1] == ',') + break; + comma1++; + } + if (comma1 > sp.Length - 3) + throw new FormatException("Invalid Vector3"); + if (!double.TryParse(sp[start..comma1], NumberStyles.Float, Utils.EnUsCulture, out double y)) + throw new FormatException("Invalid Vector3"); + + comma1++; + start = comma1; + comma1++; + while (comma1 < sp.Length) + { + if (p[comma1] == '>') + break; + comma1++; + } + if (comma1 >= sp.Length) + throw new FormatException("Invalid Vector3"); + + if (!double.TryParse(sp[start..comma1], NumberStyles.Float, Utils.EnUsCulture, out double z)) + throw new FormatException("Invalid Vector3"); + return new Vector3d(x, y, z); } - catch (Exception) + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static bool TryParse(string val, out Vector3d result) + { + return TryParse(val.AsSpan(), out result); + } + + public unsafe static bool TryParse(ReadOnlySpan sp, out Vector3d result) + { + if (sp.Length < 7) { - result = Vector3d.Zero; + result = Zero; return false; } + + int start = 0; + fixed (char* p = sp) + { + while (start < sp.Length) + { + if (p[start++] == '<') + break; + } + if (start > sp.Length - 6) + { + result = Zero; + return false; + } + + int comma1 = start + 1; + while (comma1 < sp.Length) + { + if (p[comma1] == ',') + break; + comma1++; + } + if (comma1 > sp.Length - 5) + { + result = Zero; + return false; + } + + if (!double.TryParse(sp[start..comma1], NumberStyles.Float, Utils.EnUsCulture, out double x)) + { + result = Zero; + return false; + } + + comma1++; + start = comma1; + comma1++; + while (comma1 < sp.Length) + { + if (p[comma1] == ',') + break; + comma1++; + } + if (comma1 > sp.Length - 3) + { + result = Zero; + return false; + } + if (!double.TryParse(sp[start..comma1], NumberStyles.Float, Utils.EnUsCulture, out double y)) + { + result = Zero; + return false; + } + + comma1++; + start = comma1; + comma1++; + while (comma1 < sp.Length) + { + if (p[comma1] == '>') + break; + comma1++; + } + if (comma1 >= sp.Length) + { + result = Zero; + return false; + } + + if (!double.TryParse(sp[start..comma1], NumberStyles.Float, Utils.EnUsCulture, out double z)) + { + result = Zero; + return false; + } + result = new Vector3d(x, y, z); + return true; + } } /// @@ -376,7 +513,15 @@ public override int GetHashCode() /// A string representation of the vector public override string ToString() { - return String.Format(Utils.EnUsCulture, "<{0}, {1}, {2}>", X, Y, Z); + StringBuilder sb = new(); + sb.Append('<'); + sb.Append(X.ToString(Utils.EnUsCulture)); + sb.Append(", "); + sb.Append(Y.ToString(Utils.EnUsCulture)); + sb.Append(", "); + sb.Append(Z.ToString(Utils.EnUsCulture)); + sb.Append('>'); + return sb.ToString(); } /// @@ -386,10 +531,16 @@ public override string ToString() /// Raw string representation of the vector public string ToRawString() { - CultureInfo enUs = new CultureInfo("en-us"); + CultureInfo enUs = new("en-us"); enUs.NumberFormat.NumberDecimalDigits = 3; - return String.Format(enUs, "{0} {1} {2}", X, Y, Z); + StringBuilder sb = new(); + sb.Append(X.ToString(enUs)); + sb.Append(' '); + sb.Append(Y.ToString(enUs)); + sb.Append(' '); + sb.Append(Z.ToString(enUs)); + return sb.ToString(); } #endregion Overrides diff --git a/OpenMetaverseTypes/Vector4.cs b/OpenMetaverseTypes/Vector4.cs index 6131040d..27bbadfb 100644 --- a/OpenMetaverseTypes/Vector4.cs +++ b/OpenMetaverseTypes/Vector4.cs @@ -28,6 +28,7 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Globalization; +using System.Text; namespace OpenMetaverse { @@ -230,6 +231,20 @@ public bool IsZero() return false; return true; } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool IsNotZero() + { + if (X != 0) + return true; + if (Y != 0) + return true; + if (Z != 0) + return true; + if (W != 0) + return true; + return false; + } /// /// IComparable.CompareTo implementation /// @@ -501,29 +516,196 @@ public static Vector4 Transform(Vector4 vector, Matrix4 matrix) (vector.X * matrix.M14) + (vector.Y * matrix.M24) + (vector.Z * matrix.M34) + (vector.W * matrix.M44)); } - public static Vector4 Parse(string val) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static Vector4 Parse(string val) { - char[] splitChar = { ',' }; - string[] split = val.Replace("<", String.Empty).Replace(">", String.Empty).Split(splitChar); - return new Vector4( - float.Parse(split[0].Trim(), Utils.EnUsCulture), - float.Parse(split[1].Trim(), Utils.EnUsCulture), - float.Parse(split[2].Trim(), Utils.EnUsCulture), - float.Parse(split[3].Trim(), Utils.EnUsCulture)); + return Parse(val.AsSpan()); } - public static bool TryParse(string val, out Vector4 result) + public static unsafe Vector4 Parse(ReadOnlySpan sp) { - try + if (sp.Length < 9) + throw new FormatException("Invalid Vector4"); + + int start = 0; + fixed (char* p = sp) { - result = Parse(val); - return true; + while (start < sp.Length) + { + if (p[start++] == '<') + break; + } + if (start > sp.Length - 8) + throw new FormatException("Invalid Vector4"); + + int comma1 = start + 1; + while (comma1 < sp.Length) + { + if (p[comma1] == ',') + break; + comma1++; + } + if (comma1 > sp.Length - 7) + throw new FormatException("Invalid Vector4"); + + if (!float.TryParse(sp[start..comma1], NumberStyles.Float, Utils.EnUsCulture, out float x)) + throw new FormatException("Invalid Vector4"); + + comma1++; + start = comma1; + comma1++; + while (comma1 < sp.Length) + { + if (p[comma1] == ',') + break; + comma1++; + } + if (comma1 > sp.Length - 5) + throw new FormatException("Invalid Vector4"); + if (!float.TryParse(sp[start..comma1], NumberStyles.Float, Utils.EnUsCulture, out float y)) + throw new FormatException("Invalid Vector4"); + + comma1++; + start = comma1; + comma1++; + while (comma1 < sp.Length) + { + if (p[comma1] == ',') + break; + comma1++; + } + if (comma1 > sp.Length - 3) + throw new FormatException("Invalid Vector4"); + if (!float.TryParse(sp[start..comma1], NumberStyles.Float, Utils.EnUsCulture, out float z)) + throw new FormatException("Invalid Vector4"); + + comma1++; + start = comma1; + comma1++; + while (comma1 < sp.Length) + { + if (p[comma1] == '>') + break; + comma1++; + } + if (comma1 >= sp.Length) + throw new FormatException("Invalid Vector4"); + + if (!float.TryParse(sp[start..comma1], NumberStyles.Float, Utils.EnUsCulture, out float w)) + throw new FormatException("Invalid Vector4"); + return new Vector4(x, y, z, w); } - catch (Exception) + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static bool TryParse(string val, out Vector4 result) + { + return TryParse(val.AsSpan(), out result); + } + + public unsafe static bool TryParse(ReadOnlySpan sp, out Vector4 result) + { + if (sp.Length < 9) { - result = new Vector4(); + result = Zero; return false; } + int start = 0; + fixed (char* p = sp) + { + while (start < sp.Length) + { + if (p[start++] == '<') + break; + } + if (start > sp.Length - 8) + { + result = Zero; + return false; + } + + int comma1 = start + 1; + while (comma1 < sp.Length) + { + if (p[comma1] == ',') + break; + comma1++; + } + if (comma1 > sp.Length - 7) + { + result = Zero; + return false; + } + + if (!float.TryParse(sp[start..comma1], NumberStyles.Float, Utils.EnUsCulture, out float x)) + { + result = Zero; + return false; + } + + comma1++; + start = comma1; + comma1++; + while (comma1 < sp.Length) + { + if (p[comma1] == ',') + break; + comma1++; + } + if (comma1 > sp.Length - 5) + { + result = Zero; + return false; + } + if (!float.TryParse(sp[start..comma1], NumberStyles.Float, Utils.EnUsCulture, out float y)) + { + result = Zero; + return false; + } + + comma1++; + start = comma1; + comma1++; + while (comma1 < sp.Length) + { + if (p[comma1] == ',') + break; + comma1++; + } + if (comma1 > sp.Length - 3) + { + result = Zero; + return false; + } + if (!float.TryParse(sp[start..comma1], NumberStyles.Float, Utils.EnUsCulture, out float z)) + { + result = Zero; + return false; + } + + comma1++; + start = comma1; + comma1++; + while (comma1 < sp.Length) + { + if (p[comma1] == '>') + break; + comma1++; + } + if (comma1 >= sp.Length) + { + result = Zero; + return false; + } + + if (!float.TryParse(sp[start..comma1], NumberStyles.Float, Utils.EnUsCulture, out float w)) + { + result = Zero; + return false; + } + result = new Vector4(x, y, z, w); + return true; + } } #endregion Static Methods @@ -580,7 +762,17 @@ public override int GetHashCode() public override string ToString() { - return String.Format(Utils.EnUsCulture, "<{0}, {1}, {2}, {3}>", X, Y, Z, W); + StringBuilder sb = new(); + sb.Append('<'); + sb.Append(X.ToString(Utils.EnUsCulture)); + sb.Append(", "); + sb.Append(Y.ToString(Utils.EnUsCulture)); + sb.Append(", "); + sb.Append(Z.ToString(Utils.EnUsCulture)); + sb.Append(", "); + sb.Append(W.ToString(Utils.EnUsCulture)); + sb.Append('>'); + return sb.ToString(); } /// @@ -593,7 +785,15 @@ public string ToRawString() CultureInfo enUs = new CultureInfo("en-us"); enUs.NumberFormat.NumberDecimalDigits = 3; - return String.Format(enUs, "{0} {1} {2} {3}", X, Y, Z, W); + StringBuilder sb = new(); + sb.Append(X.ToString(enUs)); + sb.Append(' '); + sb.Append(Y.ToString(enUs)); + sb.Append(' '); + sb.Append(Z.ToString(enUs)); + sb.Append(' '); + sb.Append(W.ToString(enUs)); + return sb.ToString(); } #endregion Overrides @@ -689,18 +889,18 @@ public string ToRawString() #endregion Operators /// A vector with a value of 0,0,0,0 - public readonly static Vector4 Zero = new Vector4(); + public readonly static Vector4 Zero = new(); /// A vector with a value of 1,1,1,1 - public readonly static Vector4 One = new Vector4(1f, 1f, 1f, 1f); + public readonly static Vector4 One = new(1f, 1f, 1f, 1f); /// A vector with a value of 1,0,0,0 - public readonly static Vector4 UnitX = new Vector4(1f, 0f, 0f, 0f); + public readonly static Vector4 UnitX = new(1f, 0f, 0f, 0f); /// A vector with a value of 0,1,0,0 - public readonly static Vector4 UnitY = new Vector4(0f, 1f, 0f, 0f); + public readonly static Vector4 UnitY = new(0f, 1f, 0f, 0f); /// A vector with a value of 0,0,1,0 - public readonly static Vector4 UnitZ = new Vector4(0f, 0f, 1f, 0f); + public readonly static Vector4 UnitZ = new(0f, 0f, 1f, 0f); /// A vector with a value of 0,0,0,1 - public readonly static Vector4 UnitW = new Vector4(0f, 0f, 0f, 1f); - public readonly static Vector4 MinValue = new Vector4(float.MinValue, float.MinValue, float.MinValue, float.MinValue); - public readonly static Vector4 MaxValue = new Vector4(float.MaxValue, float.MaxValue, float.MaxValue, float.MaxValue); + public readonly static Vector4 UnitW = new(0f, 0f, 0f, 1f); + public readonly static Vector4 MinValue = new(float.MinValue, float.MinValue, float.MinValue, float.MinValue); + public readonly static Vector4 MaxValue = new(float.MaxValue, float.MaxValue, float.MaxValue, float.MaxValue); } } diff --git a/Programs/GridImageUpload/Properties/Resources.Designer.cs b/Programs/GridImageUpload/Properties/Resources.Designer.cs index 13781231..890a2aa5 100644 --- a/Programs/GridImageUpload/Properties/Resources.Designer.cs +++ b/Programs/GridImageUpload/Properties/Resources.Designer.cs @@ -1,17 +1,17 @@ //------------------------------------------------------------------------------ // // This code was generated by a tool. -// Runtime Version:2.0.50727.42 +// Runtime Version:4.0.30319.42000 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // //------------------------------------------------------------------------------ -namespace GridImageUpload.Properties -{ - - +namespace GridImageUpload.Properties { + using System; + + /// /// A strongly-typed resource class, for looking up localized strings, etc. /// @@ -19,51 +19,43 @@ namespace GridImageUpload.Properties // class via a tool like ResGen or Visual Studio. // To add or remove a member, edit your .ResX file then rerun ResGen // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "2.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - internal class Resources - { - + internal class Resources { + private static global::System.Resources.ResourceManager resourceMan; - + private static global::System.Globalization.CultureInfo resourceCulture; - + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - internal Resources() - { + internal Resources() { } - + /// /// Returns the cached ResourceManager instance used by this class. /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Resources.ResourceManager ResourceManager - { - get - { - if ((resourceMan == null)) - { + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("GridImageUpload.Properties.Resources", typeof(Resources).Assembly); resourceMan = temp; } return resourceMan; } } - + /// /// Overrides the current thread's CurrentUICulture property for all /// resource lookups using this strongly typed resource class. /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Globalization.CultureInfo Culture - { - get - { + internal static global::System.Globalization.CultureInfo Culture { + get { return resourceCulture; } - set - { + set { resourceCulture = value; } } diff --git a/Programs/GridImageUpload/Properties/Settings.Designer.cs b/Programs/GridImageUpload/Properties/Settings.Designer.cs index c2a71e12..495ea1ae 100644 --- a/Programs/GridImageUpload/Properties/Settings.Designer.cs +++ b/Programs/GridImageUpload/Properties/Settings.Designer.cs @@ -1,28 +1,24 @@ //------------------------------------------------------------------------------ // // This code was generated by a tool. -// Runtime Version:2.0.50727.42 +// Runtime Version:4.0.30319.42000 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // //------------------------------------------------------------------------------ -namespace SLImageUpload.Properties -{ - - +namespace GridImageUpload.Properties { + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "8.0.0.0")] - internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase - { - + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.5.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); - - public static Settings Default - { - get - { + + public static Settings Default { + get { return defaultInstance; } } diff --git a/Programs/GridProxy/GridProxy.cs b/Programs/GridProxy/GridProxy.cs index 735408bd..9448a540 100644 --- a/Programs/GridProxy/GridProxy.cs +++ b/Programs/GridProxy/GridProxy.cs @@ -47,6 +47,8 @@ using log4net; using Nwc.XmlRpc; using Logger = Nwc.XmlRpc.Logger; +using System.Net.Security; +using System.Security.Cryptography.X509Certificates; namespace GridProxy { @@ -199,17 +201,32 @@ public class Proxy /* * Proxy Management */ + public static bool ValidateServerCertificate( + object sender, + X509Certificate certificate, + X509Chain chain, + SslPolicyErrors sslPolicyErrors) + { + //if (m_NoVerifyCertChain) + sslPolicyErrors &= ~SslPolicyErrors.RemoteCertificateChainErrors; + + //if (m_NoVerifyCertHostname) + sslPolicyErrors &= ~SslPolicyErrors.RemoteCertificateNameMismatch; + + if (sslPolicyErrors == SslPolicyErrors.None) + return true; + + return false; + } // Proxy: construct a proxy server with the given configuration public Proxy(ProxyConfig proxyConfig) { this.proxyConfig = proxyConfig; - ServicePointManager.CertificatePolicy = new TrustAllCertificatePolicy(); ServicePointManager.Expect100Continue = false; ServicePointManager.DefaultConnectionLimit = 128; - // Even though this will compile on Mono 2.4, it throws a runtime exception - //ServicePointManager.ServerCertificateValidationCallback = TrustAllCertificatePolicy.TrustAllCertificateHandler; + ServicePointManager.ServerCertificateValidationCallback = ValidateServerCertificate; InitializeLoginProxy(); InitializeSimProxy(); @@ -587,7 +604,7 @@ private void ProxyHTTP(Socket client) headers["method"] = meth; if (contentType == "application/llsd+xml" || contentType == "application/xml+llsd" || contentType == "application/xml") { - ProxyLoginSD(netStream, content); + ProxyLoginSD(netStream, content, headers); } else { @@ -645,15 +662,6 @@ private void ProxyCaps(NetworkStream netStream, string meth, string uri, Diction int indx = capuri.IndexOf("/item/"); if (indx < 0) indx = capuri.IndexOf("/category/"); - - if (indx < 0) - { - indx = capuri.IndexOf("/cap/"); - if(indx > 0 && indx + 45 < capuri.Length) - indx += 41; - else - indx = -1; - } if(indx > 0) capuri = capuri.Substring(0,indx); @@ -1247,12 +1255,13 @@ private void ProxyLogin(NetworkStream netStream, byte[] content, Dictionary headers) { lock (this) { AutoResetEvent remoteComplete = new AutoResetEvent(false); CapsClient loginRequest = new CapsClient(proxyConfig.remoteLoginUri); + OSD response = null; loginRequest.OnComplete += new CapsClient.CompleteCallback( delegate(CapsClient client, OSD result, Exception error) @@ -1267,6 +1276,7 @@ private void ProxyLoginSD(NetworkStream netStream, byte[] content) remoteComplete.Set(); } ); + loginRequest.BeginGetResponse(content, "application/llsd+xml", 1000 * 100); remoteComplete.WaitOne(1000 * 100, false); diff --git a/Programs/PrimWorkshop/Properties/Resources.Designer.cs b/Programs/PrimWorkshop/Properties/Resources.Designer.cs index e1a6b5c3..cb5c05e7 100644 --- a/Programs/PrimWorkshop/Properties/Resources.Designer.cs +++ b/Programs/PrimWorkshop/Properties/Resources.Designer.cs @@ -1,17 +1,17 @@ //------------------------------------------------------------------------------ // // This code was generated by a tool. -// Runtime Version:2.0.50727.42 +// Runtime Version:4.0.30319.42000 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // //------------------------------------------------------------------------------ -namespace PrimWorkshop.Properties -{ - - +namespace PrimWorkshop.Properties { + using System; + + /// /// A strongly-typed resource class, for looking up localized strings, etc. /// @@ -19,51 +19,43 @@ namespace PrimWorkshop.Properties // class via a tool like ResGen or Visual Studio. // To add or remove a member, edit your .ResX file then rerun ResGen // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "2.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - internal class Resources - { - + internal class Resources { + private static global::System.Resources.ResourceManager resourceMan; - + private static global::System.Globalization.CultureInfo resourceCulture; - + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - internal Resources() - { + internal Resources() { } - + /// /// Returns the cached ResourceManager instance used by this class. /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Resources.ResourceManager ResourceManager - { - get - { - if ((resourceMan == null)) - { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("primpreview.Properties.Resources", typeof(Resources).Assembly); + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("PrimWorkshop.Properties.Resources", typeof(Resources).Assembly); resourceMan = temp; } return resourceMan; } } - + /// /// Overrides the current thread's CurrentUICulture property for all /// resource lookups using this strongly typed resource class. /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Globalization.CultureInfo Culture - { - get - { + internal static global::System.Globalization.CultureInfo Culture { + get { return resourceCulture; } - set - { + set { resourceCulture = value; } } diff --git a/Programs/PrimWorkshop/Properties/Settings.Designer.cs b/Programs/PrimWorkshop/Properties/Settings.Designer.cs index 531461cb..3e49e161 100644 --- a/Programs/PrimWorkshop/Properties/Settings.Designer.cs +++ b/Programs/PrimWorkshop/Properties/Settings.Designer.cs @@ -1,28 +1,24 @@ //------------------------------------------------------------------------------ // // This code was generated by a tool. -// Runtime Version:2.0.50727.42 +// Runtime Version:4.0.30319.42000 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // //------------------------------------------------------------------------------ -namespace PrimWorkshop.Properties -{ - - +namespace PrimWorkshop.Properties { + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "8.0.0.0")] - internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase - { - + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.5.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); - - public static Settings Default - { - get - { + + public static Settings Default { + get { return defaultInstance; } } diff --git a/Programs/PrimWorkshop/frmBrowser.cs b/Programs/PrimWorkshop/frmBrowser.cs index 12fc4ac7..943e0f19 100644 --- a/Programs/PrimWorkshop/frmBrowser.cs +++ b/Programs/PrimWorkshop/frmBrowser.cs @@ -22,8 +22,8 @@ public partial class frmBrowser : Form const float DEG_TO_RAD = 0.0174532925f; const uint TERRAIN_START = (uint)Int32.MaxValue + 1; - ContextMenu ExportPrimMenu; - ContextMenu ExportTerrainMenu; + ContextMenuStrip ExportPrimMenu; + ContextMenuStrip ExportTerrainMenu; GridClient Client; Camera Camera; @@ -84,14 +84,14 @@ public frmBrowser() cboServer.SelectedIndex = 0; // Context menus - ExportPrimMenu = new ContextMenu(); - ExportPrimMenu.MenuItems.Add("Download", new EventHandler(DownloadMenu_Clicked)); - ExportPrimMenu.MenuItems.Add("Download All Objects", new EventHandler(DownloadAllMenu_Clicked)); - ExportTerrainMenu = new ContextMenu(); - ExportTerrainMenu.MenuItems.Add("Teleport", new EventHandler(TeleportMenu_Clicked)); - ExportTerrainMenu.MenuItems.Add("Export Terrain", new EventHandler(ExportTerrainMenu_Clicked)); - ExportTerrainMenu.MenuItems.Add("Import Object", new EventHandler(ImportObjectMenu_Clicked)); - ExportTerrainMenu.MenuItems.Add("Import Sim", new EventHandler(ImportSimMenu_Clicked)); + ExportPrimMenu = new ContextMenuStrip(); + ExportPrimMenu.Items.Add("Download", null,new EventHandler(DownloadMenu_Clicked) ); + ExportPrimMenu.Items.Add("Download All Objects",null, new EventHandler(DownloadAllMenu_Clicked)); + ExportTerrainMenu = new ContextMenuStrip(); + ExportTerrainMenu.Items.Add("Teleport", null, new EventHandler(TeleportMenu_Clicked)); + ExportTerrainMenu.Items.Add("Export Terrain",null, new EventHandler(ExportTerrainMenu_Clicked)); + ExportTerrainMenu.Items.Add("Import Object",null, new EventHandler(ImportObjectMenu_Clicked)); + ExportTerrainMenu.Items.Add("Import Sim",null, new EventHandler(ImportSimMenu_Clicked)); // Setup a timer for updating the progress bar ProgressTimer = new System.Timers.Timer(250); @@ -558,14 +558,14 @@ private void DownloadMenu_Clicked(object sender, EventArgs e) { // This should have already been fixed in the picking processing code Console.WriteLine("Download menu clicked when a child prim is selected!"); - glControl.ContextMenu = null; + glControl.ContextMenuStrip = null; LastHit = 0; } } else { Console.WriteLine("Download menu clicked when there is no selected prim!"); - glControl.ContextMenu = null; + glControl.ContextMenuStrip = null; LastHit = 0; } } @@ -698,7 +698,7 @@ private void TeleportMenu_Clicked(object sender, EventArgs e) else { // This shouldn't have happened... - glControl.ContextMenu = null; + glControl.ContextMenuStrip = null; } } } @@ -869,7 +869,7 @@ private void StopPicking() else { LastHit = 0; - glControl.ContextMenu = null; + glControl.ContextMenuStrip = null; } } @@ -905,7 +905,7 @@ private void ProcessHits(int hits, uint[] selectBuffer) if (LastHit >= TERRAIN_START) { // Terrain was clicked on, turn off the context menu - glControl.ContextMenu = ExportTerrainMenu; + glControl.ContextMenuStrip = ExportTerrainMenu; } else { @@ -924,7 +924,7 @@ private void ProcessHits(int hits, uint[] selectBuffer) if (RenderPrimList.TryGetValue(render.Prim.ParentID, out renderParent)) { // Turn on the context menu - glControl.ContextMenu = ExportPrimMenu; + glControl.ContextMenuStrip = ExportPrimMenu; // Change the clicked on prim to the parent. Camera position stays on the // clicked child but the highlighting is applied to all the children diff --git a/Programs/WinGridProxy/Properties/AssemblyInfo.cs b/Programs/WinGridProxy/Properties/AssemblyInfo.cs index 4a200515..757e0663 100644 --- a/Programs/WinGridProxy/Properties/AssemblyInfo.cs +++ b/Programs/WinGridProxy/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("0.9.4.*")] +[assembly: AssemblyVersion("0.9.4.0")] [assembly: AssemblyFileVersion("0.9.4.0")] diff --git a/Programs/examples/GridAccountant/AssemblyInfo.cs b/Programs/examples/GridAccountant/AssemblyInfo.cs index 9f89a328..55d014d4 100644 --- a/Programs/examples/GridAccountant/AssemblyInfo.cs +++ b/Programs/examples/GridAccountant/AssemblyInfo.cs @@ -26,7 +26,7 @@ // You can specify all the values or you can default the Revision and Build Numbers // by using the '*' as shown below: -[assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0")] // // In order to sign your assembly you must specify a key to use. Refer to the diff --git a/bin/openmetaverse_data/avatar_lad.xml b/bin/openmetaverse_data/avatar_lad.xml index 3bd7ba72..0c3fa9d4 100644 --- a/bin/openmetaverse_data/avatar_lad.xml +++ b/bin/openmetaverse_data/avatar_lad.xml @@ -1,12308 +1,17476 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bin/openmetaverse_data/avatar_skeleton.xml b/bin/openmetaverse_data/avatar_skeleton.xml index 6b07bbc1..2241a125 100644 --- a/bin/openmetaverse_data/avatar_skeleton.xml +++ b/bin/openmetaverse_data/avatar_skeleton.xml @@ -1,81 +1,232 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/openjpeg-dotnet/DllOpenJPEG.sln b/openjpeg-dotnet/DllOpenJPEG.sln index 965364de..cf4e1669 100644 --- a/openjpeg-dotnet/DllOpenJPEG.sln +++ b/openjpeg-dotnet/DllOpenJPEG.sln @@ -1,7 +1,9 @@  -Microsoft Visual Studio Solution File, Format Version 10.00 -# Visual Studio 2008 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DllOpenJPEG", "DllOpenJPEG.vcproj", "{89AC992C-5E2C-4E6B-A453-61C1DF446216}" +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.27130.2003 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DllOpenJPEG", "DllOpenJPEG.vcxproj", "{89AC992C-5E2C-4E6B-A453-61C1DF446216}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -23,4 +25,7 @@ Global GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {DCB4E0B5-36BA-489A-BC3E-27426CD34B43} + EndGlobalSection EndGlobal From 79f29fd55176f153c963d8943e054cd564c23578 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Fri, 25 Nov 2022 08:52:24 +0000 Subject: [PATCH 084/149] add some SSE code --- OpenMetaverseTypes/UUID.cs | 36 +++ OpenMetaverseTypes/UtilsConversions.cs | 318 ++++++++++++++++--------- 2 files changed, 238 insertions(+), 116 deletions(-) diff --git a/OpenMetaverseTypes/UUID.cs b/OpenMetaverseTypes/UUID.cs index c4d0f507..26f7af48 100644 --- a/OpenMetaverseTypes/UUID.cs +++ b/OpenMetaverseTypes/UUID.cs @@ -29,6 +29,8 @@ using System.Collections.Generic; using System.Runtime.InteropServices; using System.Xml.Serialization; +using System.Runtime.Intrinsics.X86; +using System.Runtime.Intrinsics; namespace OpenMetaverse { @@ -384,6 +386,15 @@ public unsafe UUID(ulong _la, ulong _lb) : this() [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe UUID(byte[] source, int pos) : this() { + if(Ssse3.IsSupported) + { + Vector128 rawval = Unsafe.As>(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(source), pos)); + if (BitConverter.IsLittleEndian) + rawval = Ssse3.Shuffle(rawval, Vector128.Create((byte)0x03, 0x02, 0x01, 0x00, 0x05, 0x04, 0x07, 0x06, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F)); + Unsafe.As>(ref this) = rawval; + return; + } + fixed (byte* ptr = &source[pos]) { if (BitConverter.IsLittleEndian) @@ -524,6 +535,15 @@ public readonly int CompareTo(UUID id) [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe void FromBytes(byte[] source, int pos) { + if (Ssse3.IsSupported) + { + Vector128 rawval = Unsafe.As>(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(source), pos)); + if (BitConverter.IsLittleEndian) + rawval = Ssse3.Shuffle(rawval, Vector128.Create((byte)0x03, 0x02, 0x01, 0x00, 0x05, 0x04, 0x07, 0x06, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F)); + Unsafe.As>(ref this) = rawval; + return; + } + fixed (byte* ptr = &source[pos]) { if (BitConverter.IsLittleEndian) @@ -563,6 +583,14 @@ public unsafe void FromBytes(byte[] source, int pos) public readonly unsafe byte[] GetBytes() { byte[] dest = new byte[16]; + if (Ssse3.IsSupported) + { + Vector128 rawval = Unsafe.As>(ref Unsafe.AsRef(in this)); + if (BitConverter.IsLittleEndian) + rawval = Ssse3.Shuffle(rawval, Vector128.Create((byte)0x03, 0x02, 0x01, 0x00, 0x05, 0x04, 0x07, 0x06, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F)); + Unsafe.As>(ref MemoryMarshal.GetArrayDataReference(dest)) = rawval; + return dest; + } fixed (byte* ptr = &dest[0]) { if (BitConverter.IsLittleEndian) @@ -602,6 +630,14 @@ public readonly unsafe byte[] GetBytes() [MethodImpl(MethodImplOptions.AggressiveInlining)] public readonly unsafe void ToBytes(byte[] dest, int pos) { + if (Ssse3.IsSupported) + { + Vector128 val = Unsafe.As>(ref Unsafe.AsRef(in this)); + if (BitConverter.IsLittleEndian) + val = Ssse3.Shuffle(val, Vector128.Create((byte)0x03, 0x02, 0x01, 0x00, 0x05, 0x04, 0x07, 0x06, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F)); + Unsafe.As>(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(dest), pos)) = val; + return; + } fixed (byte* ptr = &dest[pos]) { if (BitConverter.IsLittleEndian) diff --git a/OpenMetaverseTypes/UtilsConversions.cs b/OpenMetaverseTypes/UtilsConversions.cs index 5b51b212..6fd71530 100644 --- a/OpenMetaverseTypes/UtilsConversions.cs +++ b/OpenMetaverseTypes/UtilsConversions.cs @@ -2996,6 +2996,49 @@ public static byte HighNibbleToHexByteChar(byte b) public static unsafe void UUIDToByteDashString(ref UUID u, byte* dst) { + if (Sse41.IsSupported) + { + Vector128 lower = Unsafe.As>(ref Unsafe.AsRef(in u)); + if (BitConverter.IsLittleEndian) + lower = Ssse3.Shuffle(lower, Vector128.Create((byte)0x03, 0x02, 0x01, 0x00, 0x05, 0x04, 0x07, 0x06, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F)); + Vector128 upper = (Sse2.ShiftRightLogical(lower.AsInt32(), 4)).AsByte(); + + Vector128 mask0f = Vector128.Create((byte)0x0f); + lower = Sse2.And(mask0f, lower); + upper = Sse2.And(mask0f, upper); + + Vector128 pastNine = Vector128.Create((sbyte)10); + Vector128 lowerMask = Sse2.CompareLessThan(lower.AsSByte(), pastNine).AsByte(); + Vector128 upperMask = Sse2.CompareLessThan(upper.AsSByte(), pastNine).AsByte(); + + Vector128 first = Vector128.Create((byte)'0'); + Vector128 second = Vector128.Create((byte)('a' - 10)); + Vector128 addlower = Sse41.BlendVariable(second, first, lowerMask); + Vector128 addupper = Sse41.BlendVariable(second, first, upperMask); + + lower = Sse2.Add(lower, addlower); + upper = Sse2.Add(upper, addupper); + + Vector128 mask1 = Ssse3.Shuffle(lower, Vector128.Create(0xff, 0, 0xff, 1, 0xff, 2, 0xff, 3, 0xff, 0xff, 4, 0xff, 5, 0xff, 0xff, 6)); + Vector128 mask2 = Ssse3.Shuffle(upper, Vector128.Create(0, 0xff, 1, 0xff, 2, 0xff, 3, 0xff, 0xff, 4, 0xff, 5, 0xff, 0xff, 6, 0xff)); + Vector128 mask3 = Ssse3.Shuffle(lower, Vector128.Create(0xff, 7, 0xff, 0xff, 8, 0xff, 9, 0xff, 0xff, 10, 0xff, 11, 0xff, 12, 0xff, 13)); + Vector128 mask4 = Ssse3.Shuffle(upper, Vector128.Create(7, 0xff, 0xff, 8, 0xff, 9, 0xff, 0xff, 10, 0xff, 11, 0xff, 12, 0xff, 13, 0xff)); + Vector128 hypens = Vector128.Create(0, 0, (byte)'-', 0, 0, 0, 0, (byte)'-', 0, 0, 0, 0, 0, 0, 0, 0); + Vector128 hypens2 = Vector128.Create(0, 0, 0, 0, 0, 0, 0, 0, (byte)'-', 0, 0, 0, 0, (byte)'-', 0, 0); + Vector128 upperSorted = Sse2.Or(Sse2.Or(mask1, mask2), hypens2); + Vector128 lowerSorted = Sse2.Or(Sse2.Or(mask3, mask4), hypens); + + Unsafe.As>(ref Unsafe.AsRef(dst)) = upperSorted; + Unsafe.As>(ref Unsafe.AddByteOffset(ref Unsafe.AsRef(dst), 16)) = lowerSorted; + + int v1 = Sse2.Extract(upper.AsUInt16(), 7); + int v2 = Sse2.Extract(lower.AsUInt16(), 7); + Unsafe.As(ref Unsafe.AddByteOffset(ref Unsafe.AsRef(dst), 32)) = (byte)(v1 & 0xff); + Unsafe.As(ref Unsafe.AddByteOffset(ref Unsafe.AsRef(dst), 33)) = (byte)(v2 & 0xff); + Unsafe.As(ref Unsafe.AddByteOffset(ref Unsafe.AsRef(dst), 34)) = (byte)((v1 >> 8) & 0xff); + Unsafe.As(ref Unsafe.AddByteOffset(ref Unsafe.AsRef(dst), 35)) = (byte)((v2 >> 8) & 0xff); + return; + } byte b; if (BitConverter.IsLittleEndian) { @@ -3109,16 +3152,6 @@ public static unsafe osUTF8 UUIDToosUTF8(UUID v) return ret; } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static unsafe osUTF8 UUIDToosUTF8(ref UUID v) - { - osUTF8 ret = new osUTF8(36); - fixed (byte* d = ret.m_data) - UUIDToByteDashString(ref v, d); - ret.m_len = 36; - return ret; - } - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static char charNibbleToHexUpper(byte b) { @@ -3140,116 +3173,169 @@ public static char charHighNibbleToHexChar(byte b) return (char)(b > 9 ? b + 0x57 : b + ASCIIzero); } - public static string UUIDToDashString(ref UUID u) + public static string UUIDToDashString(UUID u) { - char[] dst = new char[36]; - byte b; - if (BitConverter.IsLittleEndian) + return string.Create(36, u, (dst, u) => { - //a - b = u.bytea3; - dst[0] = charHighNibbleToHexChar(b); - dst[1] = charLowNibbleToHexChar(b); - b = u.bytea2; - dst[2] = charHighNibbleToHexChar(b); - dst[3] = charLowNibbleToHexChar(b); - b = u.bytea1; - dst[4] = charHighNibbleToHexChar(b); - dst[5] = charLowNibbleToHexChar(b); - b = u.bytea0; - dst[6] = charHighNibbleToHexChar(b); - dst[7] = charLowNibbleToHexChar(b); - - dst[8] = '-'; - - //b - b = u.byteb1; - dst[9] = charHighNibbleToHexChar(b); - dst[10] = charLowNibbleToHexChar(b); - b = u.byteb0; - dst[11] = charHighNibbleToHexChar(b); - dst[12] = charLowNibbleToHexChar(b); - - dst[13] = '-'; - - //c - b = u.bytec1; - dst[14] = charHighNibbleToHexChar(b); - dst[15] = charLowNibbleToHexChar(b); - b = u.bytec0; - dst[16] = charHighNibbleToHexChar(b); - dst[17] = charLowNibbleToHexChar(b); - } - else - { - //a - b = u.bytea0; - dst[0] = charHighNibbleToHexChar(b); - dst[1] = charLowNibbleToHexChar(b); - b = u.bytea1; - dst[2] = charHighNibbleToHexChar(b); - dst[3] = charLowNibbleToHexChar(b); - b = u.bytea2; - dst[4] = charHighNibbleToHexChar(b); - dst[5] = charLowNibbleToHexChar(b); - b = u.bytea3; - dst[6] = charHighNibbleToHexChar(b); - dst[7] = charLowNibbleToHexChar(b); - - dst[8] = '-'; - - //b - b = u.byteb0; - dst[9] = charHighNibbleToHexChar(b); - dst[10] = charLowNibbleToHexChar(b); - b = u.byteb1; - dst[11] = charHighNibbleToHexChar(b); - dst[12] = charLowNibbleToHexChar(b); - - dst[13] = '-'; - - //c - b = u.bytec0; - dst[14] = charHighNibbleToHexChar(b); - dst[15] = charLowNibbleToHexChar(b); - b = u.bytec1; - dst[16] = charHighNibbleToHexChar(b); - dst[17] = charLowNibbleToHexChar(b); - } - - - dst[18] = '-'; - - b = u.d; //d - dst[19] = charHighNibbleToHexChar(b); - dst[20] = charLowNibbleToHexChar(b); - b = u.e; //e - dst[21] = charHighNibbleToHexChar(b); - dst[22] = charLowNibbleToHexChar(b); - - dst[23] = '-'; + if (Sse41.IsSupported) + { + Vector128 lower = Unsafe.As>(ref Unsafe.AsRef(in u)); + if (BitConverter.IsLittleEndian) + lower = Ssse3.Shuffle(lower, Vector128.Create((byte)0x03, 0x02, 0x01, 0x00, 0x05, 0x04, 0x07, 0x06, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F)); + Vector128 upper = (Sse2.ShiftRightLogical(lower.AsInt32(), 4)).AsByte(); + + Vector128 mask0f = Vector128.Create((byte)0x0f); + lower = Sse2.And(mask0f, lower); + upper = Sse2.And(mask0f, upper); + + Vector128 pastNine = Vector128.Create((sbyte)10); + Vector128 lowerMask = Sse2.CompareLessThan(lower.AsSByte(), pastNine).AsByte(); + Vector128 upperMask = Sse2.CompareLessThan(upper.AsSByte(), pastNine).AsByte(); + + Vector128 first = Vector128.Create((byte)'0'); + Vector128 second = Vector128.Create((byte)('a' - 10)); + Vector128 addlower = Sse41.BlendVariable(second, first, lowerMask); + Vector128 addupper = Sse41.BlendVariable(second, first, upperMask); + + lower = Sse2.Add(lower, addlower); + upper = Sse2.Add(upper, addupper); + + Vector128 mask1 = Ssse3.Shuffle(lower, Vector128.Create(0xff, 0, 0xff, 1, 0xff, 2, 0xff, 3, 0xff, 0xff, 4, 0xff, 5, 0xff, 0xff, 6)); + Vector128 mask2 = Ssse3.Shuffle(upper, Vector128.Create(0, 0xff, 1, 0xff, 2, 0xff, 3, 0xff, 0xff, 4, 0xff, 5, 0xff, 0xff, 6, 0xff)); + Vector128 mask3 = Ssse3.Shuffle(lower, Vector128.Create(0xff, 7, 0xff, 0xff, 8, 0xff, 9, 0xff, 0xff, 10, 0xff, 11, 0xff, 12, 0xff, 13)); + Vector128 mask4 = Ssse3.Shuffle(upper, Vector128.Create(7, 0xff, 0xff, 8, 0xff, 9, 0xff, 0xff, 10, 0xff, 11, 0xff, 12, 0xff, 13, 0xff)); + Vector128 hypens = Vector128.Create(0, 0, (byte)'-', 0, 0, 0, 0, (byte)'-', 0, 0, 0, 0, 0, 0, 0, 0); + Vector128 hypens2 = Vector128.Create(0, 0, 0, 0, 0, 0, 0, 0, (byte)'-', 0, 0, 0, 0, (byte)'-', 0, 0); + Vector128 upperSorted = Sse2.Or(Sse2.Or(mask1, mask2), hypens2); + Vector128 lowerSorted = Sse2.Or(Sse2.Or(mask3, mask4), hypens); + + Vector128 charsMask0 = Vector128.Create(0, 0xff, 1, 0xff, 2, 0xff, 3, 0xff, 4, 0xff, 5, 0xff, 6, 0xff, 7, 0xff); + Vector128 chars0 = Ssse3.Shuffle(upperSorted, charsMask0); + Unsafe.As>(ref MemoryMarshal.GetReference(dst)) = chars0; + + Vector128 charsMask1 = Vector128.Create(8, 0xff, 9, 0xff, 10, 0xff, 11, 0xff, 12, 0xff, 13, 0xff, 14, 0xff, 15, 0xff); + Vector128 chars1 = Ssse3.Shuffle(upperSorted, charsMask1); + Unsafe.As>(ref Unsafe.AddByteOffset(ref MemoryMarshal.GetReference(dst), 16)) = chars1; + + chars0 = Ssse3.Shuffle(lowerSorted, charsMask0); + Unsafe.As>(ref Unsafe.AddByteOffset(ref MemoryMarshal.GetReference(dst), 32)) = chars0; + + chars1 = Ssse3.Shuffle(lowerSorted, charsMask1); + Unsafe.As>(ref Unsafe.AddByteOffset(ref MemoryMarshal.GetReference(dst), 48)) = chars1; + + int v1 = Sse2.Extract(upper.AsUInt16(), 7); + int v2 = Sse2.Extract(lower.AsUInt16(), 7); + Unsafe.As(ref Unsafe.AddByteOffset(ref MemoryMarshal.GetReference(dst), 64)) = (byte)(v1 & 0xff); + Unsafe.As(ref Unsafe.AddByteOffset(ref MemoryMarshal.GetReference(dst), 66)) = (byte)(v2 & 0xff); + Unsafe.As(ref Unsafe.AddByteOffset(ref MemoryMarshal.GetReference(dst), 68)) = (byte)((v1 >> 8) & 0xff); + Unsafe.As(ref Unsafe.AddByteOffset(ref MemoryMarshal.GetReference(dst), 70)) = (byte)((v2 >> 8) & 0xff); + return; + } + byte b; + if (BitConverter.IsLittleEndian) + { + //a + b = u.bytea3; + dst[0] = charHighNibbleToHexChar(b); + dst[1] = charLowNibbleToHexChar(b); + b = u.bytea2; + dst[2] = charHighNibbleToHexChar(b); + dst[3] = charLowNibbleToHexChar(b); + b = u.bytea1; + dst[4] = charHighNibbleToHexChar(b); + dst[5] = charLowNibbleToHexChar(b); + b = u.bytea0; + dst[6] = charHighNibbleToHexChar(b); + dst[7] = charLowNibbleToHexChar(b); + + dst[8] = '-'; + + //b + b = u.byteb1; + dst[9] = charHighNibbleToHexChar(b); + dst[10] = charLowNibbleToHexChar(b); + b = u.byteb0; + dst[11] = charHighNibbleToHexChar(b); + dst[12] = charLowNibbleToHexChar(b); + + dst[13] = '-'; + + //c + b = u.bytec1; + dst[14] = charHighNibbleToHexChar(b); + dst[15] = charLowNibbleToHexChar(b); + b = u.bytec0; + dst[16] = charHighNibbleToHexChar(b); + dst[17] = charLowNibbleToHexChar(b); + } + else + { + //a + b = u.bytea0; + dst[0] = charHighNibbleToHexChar(b); + dst[1] = charLowNibbleToHexChar(b); + b = u.bytea1; + dst[2] = charHighNibbleToHexChar(b); + dst[3] = charLowNibbleToHexChar(b); + b = u.bytea2; + dst[4] = charHighNibbleToHexChar(b); + dst[5] = charLowNibbleToHexChar(b); + b = u.bytea3; + dst[6] = charHighNibbleToHexChar(b); + dst[7] = charLowNibbleToHexChar(b); + + dst[8] = '-'; + + //b + b = u.byteb0; + dst[9] = charHighNibbleToHexChar(b); + dst[10] = charLowNibbleToHexChar(b); + b = u.byteb1; + dst[11] = charHighNibbleToHexChar(b); + dst[12] = charLowNibbleToHexChar(b); + + dst[13] = '-'; + + //c + b = u.bytec0; + dst[14] = charHighNibbleToHexChar(b); + dst[15] = charLowNibbleToHexChar(b); + b = u.bytec1; + dst[16] = charHighNibbleToHexChar(b); + dst[17] = charLowNibbleToHexChar(b); + } - b = u.f; //f - dst[24] = charHighNibbleToHexChar(b); - dst[25] = charLowNibbleToHexChar(b); - b = u.g; //g - dst[26] = charHighNibbleToHexChar(b); - dst[27] = charLowNibbleToHexChar(b); - b = u.h; //h - dst[28] = charHighNibbleToHexChar(b); - dst[29] = charLowNibbleToHexChar(b); - b = u.i; //i - dst[30] = charHighNibbleToHexChar(b); - dst[31] = charLowNibbleToHexChar(b); - b = u.j; //j - dst[32] = charHighNibbleToHexChar(b); - dst[33] = charLowNibbleToHexChar(b); - b = u.k; //k - dst[34] = charHighNibbleToHexChar(b); - dst[35] = charLowNibbleToHexChar(b); - return new string(dst); + dst[18] = '-'; + + b = u.d; //d + dst[19] = charHighNibbleToHexChar(b); + dst[20] = charLowNibbleToHexChar(b); + b = u.e; //e + dst[21] = charHighNibbleToHexChar(b); + dst[22] = charLowNibbleToHexChar(b); + + dst[23] = '-'; + + b = u.f; //f + dst[24] = charHighNibbleToHexChar(b); + dst[25] = charLowNibbleToHexChar(b); + b = u.g; //g + dst[26] = charHighNibbleToHexChar(b); + dst[27] = charLowNibbleToHexChar(b); + b = u.h; //h + dst[28] = charHighNibbleToHexChar(b); + dst[29] = charLowNibbleToHexChar(b); + b = u.i; //i + dst[30] = charHighNibbleToHexChar(b); + dst[31] = charLowNibbleToHexChar(b); + b = u.j; //j + dst[32] = charHighNibbleToHexChar(b); + dst[33] = charLowNibbleToHexChar(b); + b = u.k; //k + dst[34] = charHighNibbleToHexChar(b); + dst[35] = charLowNibbleToHexChar(b); + }); } - #endregion Miscellaneous } } From de3c2d543d8fd737c9bb66acc4db266f3bee3e93 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Fri, 25 Nov 2022 15:35:42 +0000 Subject: [PATCH 085/149] use some ugly unsafe.as.... anti bounds check hack --- OpenMetaverseTypes/OSUTF8.cs | 2 +- OpenMetaverseTypes/OSUTF8Slice.cs | 357 ++++++++----------------- OpenMetaverseTypes/UUID.cs | 229 +--------------- OpenMetaverseTypes/UtilsConversions.cs | 4 +- 4 files changed, 130 insertions(+), 462 deletions(-) diff --git a/OpenMetaverseTypes/OSUTF8.cs b/OpenMetaverseTypes/OSUTF8.cs index 95d730de..11a3102a 100644 --- a/OpenMetaverseTypes/OSUTF8.cs +++ b/OpenMetaverseTypes/OSUTF8.cs @@ -559,7 +559,7 @@ public unsafe void AppendUUID(UUID u) { CheckCapacity(36); fixed (byte* d = m_data) - Utils.UUIDToByteDashString(ref u, d + m_len); + Utils.UUIDToByteDashString(u, d + m_len); m_len += 36; } diff --git a/OpenMetaverseTypes/OSUTF8Slice.cs b/OpenMetaverseTypes/OSUTF8Slice.cs index ef472594..664c4278 100644 --- a/OpenMetaverseTypes/OSUTF8Slice.cs +++ b/OpenMetaverseTypes/OSUTF8Slice.cs @@ -38,6 +38,7 @@ Ubit Umarov (Leal Duarte) 2020 using System.Text; using System.Collections.Generic; using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; namespace OpenMetaverse { @@ -132,7 +133,7 @@ public byte this[int i] i = 0; else if (i >= m_data.Length) i = m_data.Length - 1; - return m_data[i]; + return Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(m_data), i)); } set { @@ -140,7 +141,7 @@ public byte this[int i] { i += m_offset; if(i < m_len) - m_data[i] = value; + Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(m_data), i)) = value; } } } @@ -217,7 +218,7 @@ public static unsafe bool IsNullOrWhitespace(osUTF8Slice u) byte[] data = u.m_data; for (int i = u.m_offset; i < u.m_offset + u.m_len; ++i) { - if (data[i] != 0x20) + if (Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(data), i)) != 0x20) return false; } return true; @@ -226,26 +227,11 @@ public static unsafe bool IsNullOrWhitespace(osUTF8Slice u) public unsafe override int GetHashCode() { int hash = m_len; - if (m_len < 8) - { - for (int i = m_offset; i < m_offset + m_len; ++i) - { - hash += m_data[i]; - hash <<= 3; - hash += hash >> 26; - } - } - else + for (int i = m_offset; i < m_offset + m_len; ++i) { - fixed (byte* a = &m_data[m_offset]) - { - for (int i = 0; i < m_len; ++i) - { - hash += a[i]; - hash <<= 5; - hash += hash >> 26; - } - } + hash += Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(m_data), i)); + hash <<= 3; + hash += hash >> 26; } return hash & 0x7fffffff; } @@ -260,103 +246,64 @@ public override string ToString() public override bool Equals(object obj) { - if (obj == null) + if (obj is null) return false; - if (obj is osUTF8) - return Equals((osUTF8)obj); + if (obj is osUTF8 o8) + return Equals(o8); - if (obj is osUTF8Slice) - return Equals((osUTF8Slice)obj); + if (obj is osUTF8Slice o8s) + return Equals(o8s); - if (obj is string) - return Equals((string)obj); + if (obj is string os) + return Equals(os); - if (obj is byte[]) - return Equals((byte[])obj); + if (obj is byte[] oba) + return Equals(oba); return false; } - public unsafe bool Equals(osUTF8Slice o) + public bool Equals(osUTF8Slice o) { if (o is null || m_len != o.m_len) return false; byte[] otherdata = o.m_data; - - if (m_len < 8) + for (int i = m_offset, j = o.m_offset; i < m_offset + m_len; ++i, ++j) { - for (int i = m_offset, j = o.m_offset; i < m_offset + m_len; ++i, ++j) - { - if (m_data[i] != otherdata[j]) - return false; - } - return true; - } - - fixed (byte* a = &m_data[m_offset], b = &otherdata[o.m_offset]) - { - for (int i = 0; i < m_len; ++i) - { - if (a[i] != b[i]) - return false; - } + if (Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(m_data), i)) != + Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(otherdata), j))) + return false; } - return true; } - public unsafe bool Equals(osUTF8 o) + public bool Equals(osUTF8 o) { if (o is null || m_len != o.m_len) return false; byte[] otherdata = o.m_data; - - if (m_len < 8) - { - for (int i = m_offset, j = 0; i < m_offset + m_len; ++i, ++j) - { - if (m_data[i] != otherdata[j]) - return false; - } - return true; - } - - fixed (byte* a = &m_data[m_offset], b = otherdata) + for (int i = m_offset, j = 0; i < m_offset + m_len; ++i, ++j) { - for (int i = 0; i < m_len; ++i) - { - if (a[i] != b[i]) - return false; - } + if (Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(m_data), i)) != + Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(otherdata), j))) + return false; } return true; } - public unsafe bool Equals(byte[] o) + public bool Equals(byte[] o) { if (o == null || m_len != o.Length) return false; - if (m_len < 8) - { - for (int i = m_offset, j = 0; i < m_offset + m_len; ++i, ++j) - { - if (m_data[i] != o[j]) - return false; - } - return true; - } - - fixed (byte* a = &m_data[m_offset], b = o) + for (int i = m_offset, j = 0; i < m_offset + m_len; ++i, ++j) { - for (int i = 0; i < m_len; ++i) - { - if (a[i] != b[i]) - return false; - } + if (Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(m_data), i)) != + Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(o), j))) + return false; } return true; } @@ -365,7 +312,7 @@ public bool Equals(string s) { if(string.IsNullOrEmpty(s)) return m_len == 0; - osUTF8 o = new osUTF8(s); + osUTF8 o = new(s); return Equals(o); } @@ -381,14 +328,15 @@ public bool Equals(string s) public static bool operator !=(osUTF8Slice value1, osUTF8Slice value2) { if (value1 is null) - return !(value2 is null); + return value2 is not null; return !value1.Equals(value2); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool Equals(char c) { - return m_len == 1 && m_data[m_offset] == (byte)c; + return m_len == 1 && + Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(m_data), m_offset)) == (byte)c; } public unsafe bool ACSIILowerEquals(osUTF8 o) @@ -538,7 +486,7 @@ public void AppendASCII(char c) { int indx = m_offset + m_len; CheckCapacity(ref indx, 1); - m_data[indx] = (byte)c; + Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(m_data), indx)) = (byte)c; ++m_len; } @@ -663,22 +611,22 @@ public osUTF8Slice SubUTF8(int start, int len) int last = start + len - 1; // cut at code points; - if (start > 0 && (m_data[start] & 0x80) != 0) + if (start > 0 && (Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(m_data), start)) & 0x80) != 0) { do { --last; } - while (start > 0 && (m_data[start] & 0xc0) != 0xc0); + while (start > 0 && (Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(m_data), start)) & 0xc0) != 0xc0); } - if (last > start && (m_data[last] & 0x80) != 0) + if (last > start && (Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(m_data), last)) & 0x80) != 0) { do { --last; } - while (last > start && (m_data[last] & 0xc0) != 0xc0); + while (last > start && (Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(m_data), last)) & 0xc0) != 0xc0); } return new osUTF8Slice(m_data, start, last - start + 1); @@ -725,22 +673,22 @@ public void SubUTF8Self(int start, int len) int last = start + len - 1; // cut at code points; - if (start > 0 && (m_data[start] & 0x80) != 0) + if (start > 0 && (Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(m_data), start)) & 0x80) != 0) { do { --last; } - while (start > 0 && (m_data[start] & 0xc0) != 0xc0); + while (start > 0 && (Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(m_data), start)) & 0xc0) != 0xc0); } - if (last > start && (m_data[last] & 0x80) != 0) + if (last > start && (Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(m_data), last)) & 0x80) != 0) { do { --last; } - while (last > start && (m_data[last] & 0xc0) != 0xc0); + while (last > start && (Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(m_data), last)) & 0xc0) != 0xc0); } m_offset = start; @@ -786,7 +734,7 @@ private bool checkAny(byte b, char[] chars) // inplace remove white spaces at start public void SelfTrimStart() { - while (m_len > 0 && m_data[m_offset] == 0x20) + while (m_len > 0 && Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(m_data), m_offset)) == 0x20) { ++m_offset; --m_len; @@ -795,7 +743,7 @@ public void SelfTrimStart() public void SelfTrimStart(byte b) { - while (m_len > 0 && m_data[m_offset] == b) + while (m_len > 0 && Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(m_data), m_offset)) == b) { ++m_offset; --m_len; @@ -804,7 +752,7 @@ public void SelfTrimStart(byte b) public void SelfTrimStart(byte[] b) { - while (m_len > 0 && checkAny(m_data[m_offset], b)) + while (m_len > 0 && checkAny(Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(m_data), m_offset)), b)) { ++m_offset; --m_len; @@ -813,7 +761,7 @@ public void SelfTrimStart(byte[] b) public void SelfTrimStart(char[] b) { - while (m_len > 0 && checkAny(m_data[m_offset], b)) + while (m_len > 0 && checkAny(Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(m_data), m_offset)), b)) { ++m_offset; --m_len; @@ -825,7 +773,7 @@ public void SelfTrimEnd() if (m_len == 0) return; int last = m_offset + m_len - 1; - while (m_len > 0 && m_data[last] == 0x20) + while (m_len > 0 && Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(m_data), last)) == 0x20) { --last; --m_len; @@ -837,7 +785,7 @@ public void SelfTrimEnd(byte b) if (m_len == 0) return; int last = m_offset + m_len - 1; - while (m_len > 0 && m_data[last] == b) + while (m_len > 0 && Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(m_data), last)) == b) { --last; --m_len; @@ -849,7 +797,7 @@ public void SelfTrimEnd(byte[] b) if (m_len == 0) return; int last = m_offset + m_len - 1; - while (m_len > 0 && checkAny(m_data[last], b)) + while (m_len > 0 && checkAny(Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(m_data), last)), b)) { --last; --m_len; @@ -861,7 +809,7 @@ public void SelfTrimEnd(char[] b) if (m_len == 0) return; int last = m_offset + m_len - 1; - while (m_len > 0 && checkAny(m_data[last], b)) + while (m_len > 0 && checkAny(Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(m_data), last)), b)) { --last; --m_len; @@ -1039,22 +987,22 @@ public bool StartsWith(string s) public bool StartsWith(byte b) { - return m_data[m_offset] == b; + return Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(m_data), m_offset)) == b; } public bool StartsWith(char b) { - return m_data[m_offset] == (byte)b; + return Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(m_data), m_offset)) == (byte)b; } public bool EndsWith(byte b) { - return m_data[m_offset + m_len - 1] == b; + return Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(m_data), m_offset + m_len - 1)) == b; } public bool EndsWith(char b) { - return m_data[m_offset + m_len - 1] == (byte)b; + return Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(m_data), m_offset + m_len - 1)) == (byte)b; } public unsafe bool EndsWith(osUTF8Slice other) @@ -1116,22 +1064,9 @@ public bool EndsWith(string s) public unsafe int IndexOf(byte b) { - if (m_len > 8) - { - fixed (byte* a = &m_data[m_offset]) - { - for (int i = 0; i < m_len; ++i) - { - if (a[i] == b) - return i; - } - return -1; - } - } - for (int i = m_offset; i < m_offset + m_len; ++i) { - if (m_data[i] == b) + if (Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(m_data), i)) == b) return i - m_offset; } return -1; @@ -1226,48 +1161,24 @@ public int IndexOf(string s) return IndexOf(o); } - public unsafe int IndexOfAny(byte[] b) + public int IndexOfAny(byte[] b) { - if (m_len < 8) - { - for (int i = m_offset; i < m_offset + m_len; ++i) - { - if (checkAny(m_data[i], b)) - return i - m_offset; - } - return -1; - } - fixed (byte* a = &m_data[m_offset]) + for (int i = m_offset; i < m_offset + m_len; ++i) { - for (int i = 0; i < m_len; ++i) - { - if (checkAny(a[i], b)) - return i; - } - return -1; + if (checkAny(Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(m_data), i)), b)) + return i - m_offset; } + return -1; } - public unsafe int IndexOfAny(char[] b) + public int IndexOfAny(char[] b) { - if (m_len < 8) - { - for (int i = m_offset; i < m_offset + m_len; ++i) - { - if (checkAny(m_data[i], b)) - return i - m_offset; - } - return -1; - } - fixed (byte* a = &m_data[m_offset]) + for (int i = m_offset; i < m_offset + m_len; ++i) { - for (int i = 0; i < m_len; ++i) - { - if (checkAny(a[i], b)) - return i; - } - return -1; + if (checkAny(Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(m_data), i)), b)) + return i - m_offset; } + return -1; } public bool Contains(osUTF8Slice other) @@ -1379,35 +1290,15 @@ public unsafe bool ReadLine(out osUTF8Slice line) int lineend = -1; byte b = 0; - if (m_len < 8) - { - for (int i = m_offset; i < m_offset + m_len; ++i) - { - b = m_data[i]; - if (b == (byte)'\r' || b == (byte)'\n') - { - if (i > 0 && m_data[i - 1] == (byte)'\\') - continue; - lineend = i; - break; - } - } - } - else + for (int i = m_offset; i < m_offset + m_len; ++i) { - fixed (byte* a = &m_data[m_offset]) + b = Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(m_data), i)); + if (b == (byte)'\r' || b == (byte)'\n') { - for (int i = 0; i < m_len; ++i) - { - b = a[i]; - if (b == (byte)'\r' || b == (byte)'\n') - { - if (i > 0 && a[i - 1] == (byte)'\\') - continue; - lineend = i + m_offset; - break; - } - } + if (i > 0 && Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(m_data), i - 1)) == (byte)'\\') + continue; + lineend = i; + break; } } @@ -1441,7 +1332,7 @@ public unsafe bool ReadLine(out osUTF8Slice line) if (b == (byte)'\r') { - if (m_data[m_offset] == (byte)'\n') + if (Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(m_data), m_offset)) == (byte)'\n') { ++m_offset; --m_len; @@ -1461,35 +1352,15 @@ public unsafe bool SkipLine() int lineend = -1; byte b = 0; - if (m_len < 8) - { - for (int i = m_offset; i < m_offset + m_len; ++i) - { - b = m_data[i]; - if (b == (byte)'\r' || b == (byte)'\n') - { - if (i > 0 && m_data[i - 1] == (byte)'\\') - continue; - lineend = i; - break; - } - } - } - else + for (int i = m_offset; i < m_offset + m_len; ++i) { - fixed (byte* a = &m_data[m_offset]) + b = Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(m_data), i)); + if (b == (byte)'\r' || b == (byte)'\n') { - for (int i = 0; i < m_len; ++i) - { - b = a[i]; - if (b == (byte)'\r' || b == (byte)'\n') - { - if (i > 0 && a[i - 1] == (byte)'\\') - continue; - lineend = i + m_offset; - break; - } - } + if (i > 0 && Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(m_data), i - 1)) == (byte)'\\') + continue; + lineend = i; + break; } } @@ -1520,7 +1391,7 @@ public unsafe bool SkipLine() if (b == (byte)'\r') { - if (m_data[m_offset] == (byte)'\n') + if (Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(m_data), m_offset)) == (byte)'\n') { ++m_offset; --m_len; @@ -1597,12 +1468,12 @@ public bool TryParseInt(out int res) len += start; bool neg = false; - if (m_data[start] == (byte)'-') + if (Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(m_data), start)) == (byte)'-') { neg = true; ++start; } - else if (m_data[start] == (byte)'+') + else if (Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(m_data), start)) == (byte)'+') ++start; int b; @@ -1610,7 +1481,7 @@ public bool TryParseInt(out int res) { while (start < len) { - b = m_data[start]; + b = Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(m_data), start)); b -= (byte)'0'; if (b < 0 || b > 9) break; @@ -1641,12 +1512,12 @@ public static bool TryParseInt(osUTF8Slice t, out int res) len += start; bool neg = false; - if (data[start] == (byte)'-') + if (Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(data), start)) == (byte)'-') { neg = true; ++start; } - else if (data[start] == (byte)'+') + else if (Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(data), start)) == (byte)'+') ++start; int b; @@ -1654,7 +1525,7 @@ public static bool TryParseInt(osUTF8Slice t, out int res) { while (start < len) { - b = data[start]; + b = Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(data), start)); b -= (byte)'0'; if (b < 0 || b > 9) break; @@ -1702,41 +1573,41 @@ public unsafe static bool TryParseUUID(osUTF8Slice inp, out UUID result) if (BitConverter.IsLittleEndian) { - result.bytea3 = (byte)Utils.HexToByte(val, 0); - result.bytea2 = (byte)Utils.HexToByte(val, 2); - result.bytea1 = (byte)Utils.HexToByte(val, 4); - result.bytea0 = (byte)Utils.HexToByte(val, 6); + result.bytea3 = Utils.HexToByte(val, 0); + result.bytea2 = Utils.HexToByte(val, 2); + result.bytea1 = Utils.HexToByte(val, 4); + result.bytea0 = Utils.HexToByte(val, 6); - result.byteb1 = (byte)Utils.HexToByte(val, 9); - result.byteb0 = (byte)Utils.HexToByte(val, 11); + result.byteb1 = Utils.HexToByte(val, 9); + result.byteb0 = Utils.HexToByte(val, 11); - result.bytec1 = (byte)Utils.HexToByte(val, 14); - result.bytec0 = (byte)Utils.HexToByte(val, 16); + result.bytec1 = Utils.HexToByte(val, 14); + result.bytec0 = Utils.HexToByte(val, 16); } else { - result.bytea0 = (byte)Utils.HexToByte(val, 0); - result.bytea1 = (byte)Utils.HexToByte(val, 2); - result.bytea2 = (byte)Utils.HexToByte(val, 4); - result.bytea3 = (byte)Utils.HexToByte(val, 6); + result.bytea0 = Utils.HexToByte(val, 0); + result.bytea1 = Utils.HexToByte(val, 2); + result.bytea2 = Utils.HexToByte(val, 4); + result.bytea3 = Utils.HexToByte(val, 6); - result.byteb0 = (byte)Utils.HexToByte(val, 9); - result.byteb1 = (byte)Utils.HexToByte(val, 11); + result.byteb0 = Utils.HexToByte(val, 9); + result.byteb1 = Utils.HexToByte(val, 11); - result.bytec0 = (byte)Utils.HexToByte(val, 14); - result.bytec1 = (byte)Utils.HexToByte(val, 16); + result.bytec0 = Utils.HexToByte(val, 14); + result.bytec1 = Utils.HexToByte(val, 16); } - result.d = (byte)Utils.HexToByte(val, 19); - result.e = (byte)Utils.HexToByte(val, 21); + result.d = Utils.HexToByte(val, 19); + result.e = Utils.HexToByte(val, 21); - result.f = (byte)Utils.HexToByte(val, 24); - result.g = (byte)Utils.HexToByte(val, 26); - result.h = (byte)Utils.HexToByte(val, 28); - result.i = (byte)Utils.HexToByte(val, 30); - result.j = (byte)Utils.HexToByte(val, 32); - result.k = (byte)Utils.HexToByte(val, 34); + result.f = Utils.HexToByte(val, 24); + result.g = Utils.HexToByte(val, 26); + result.h = Utils.HexToByte(val, 28); + result.i = Utils.HexToByte(val, 30); + result.j = Utils.HexToByte(val, 32); + result.k = Utils.HexToByte(val, 34); return true; } else diff --git a/OpenMetaverseTypes/UUID.cs b/OpenMetaverseTypes/UUID.cs index 26f7af48..3eb04bbc 100644 --- a/OpenMetaverseTypes/UUID.cs +++ b/OpenMetaverseTypes/UUID.cs @@ -74,163 +74,28 @@ public struct UUID : IComparable,IComparable, IEquatable, IEqualityC [XmlIgnore] [NonSerialized()] [FieldOffset(0)] public ulong ulonga; [XmlIgnore] [NonSerialized()] [FieldOffset(8)] public ulong ulongb; - [FieldOffset(0)] public Guid Guid; - #region Constructors + public Guid Guid + { + get + { + return Unsafe.As(ref this); + } + set + { + Unsafe.As(ref this) = value; + } + } /// /// Constructor that takes a string UUID representation /// /// A string representation of a UUID, case /// insensitive and can either be hyphenated or non-hyphenated /// UUID("11f8aa9c-b071-4242-836b-13b7abe0d489") - /* [MethodImpl(MethodImplOptions.AggressiveInlining)] - public unsafe UUID(string val) + public UUID(string sval) : this(sval.AsSpan()) { - if (!string.IsNullOrEmpty(val)) - { - try - { - if (Guid.TryParse(val, out Guid gg)) - { - this = *(UUID*)≫ - return; - } - } - catch { } - } - this = new UUID(); - } - */ - - public unsafe UUID(string sval) - { - this = new UUID(); - if (sval is null) - throw new FormatException("Invalid UUID"); - int len = sval.Length; - if (len < 32) - throw new FormatException("Invalid UUID"); - - try - { - fixed (char* bval = sval) - { - char* val = bval; - while (*val == ' ') - { - ++val; - --len; - if (len < 32) - throw new Exception(); - } - - if (val[8] == '-') - { - if (len < 36) - throw new Exception(); - - while (--len > 35) - { - if (val[len] != ' ') - throw new Exception(); - } - - if (val[13] != '-' || val[18] != '-' || val[23] != '-') - throw new Exception(); - - if (BitConverter.IsLittleEndian) - { - bytea3 = Utils.HexToByte(val, 0); - bytea2 = Utils.HexToByte(val, 2); - bytea1 = Utils.HexToByte(val, 4); - bytea0 = Utils.HexToByte(val, 6); - - byteb1 = Utils.HexToByte(val, 9); - byteb0 = Utils.HexToByte(val, 11); - - bytec1 = Utils.HexToByte(val, 14); - bytec0 = Utils.HexToByte(val, 16); - } - else - { - bytea0 = Utils.HexToByte(val, 0); - bytea1 = Utils.HexToByte(val, 2); - bytea2 = Utils.HexToByte(val, 4); - bytea3 = Utils.HexToByte(val, 6); - - byteb0 = Utils.HexToByte(val, 9); - byteb1 = Utils.HexToByte(val, 11); - - bytec0 = Utils.HexToByte(val, 14); - bytec1 = Utils.HexToByte(val, 16); - } - - - d = Utils.HexToByte(val, 19); - e = Utils.HexToByte(val, 21); - - - f = Utils.HexToByte(val, 24); - g = Utils.HexToByte(val, 26); - h = Utils.HexToByte(val, 28); - i = Utils.HexToByte(val, 30); - j = Utils.HexToByte(val, 32); - k = Utils.HexToByte(val, 34); - return; - } - else - { - while (--len > 31) - { - if (val[len] != ' ') - throw new Exception(); - } - - if (BitConverter.IsLittleEndian) - { - bytea3 = Utils.HexToByte(val, 0); - bytea2 = Utils.HexToByte(val, 2); - bytea1 = Utils.HexToByte(val, 4); - bytea0 = Utils.HexToByte(val, 6); - - byteb1 = Utils.HexToByte(val, 8); - byteb0 = Utils.HexToByte(val, 10); - - bytec1 = Utils.HexToByte(val, 12); - bytec0 = Utils.HexToByte(val, 14); - } - else - { - bytea0 = Utils.HexToByte(val, 0); - bytea1 = Utils.HexToByte(val, 2); - bytea2 = Utils.HexToByte(val, 4); - bytea3 = Utils.HexToByte(val, 6); - - byteb0 = Utils.HexToByte(val, 8); - byteb1 = Utils.HexToByte(val, 10); - - bytec0 = Utils.HexToByte(val, 12); - bytec1 = Utils.HexToByte(val, 14); - } - - d = Utils.HexToByte(val, 16); - e = Utils.HexToByte(val, 18); - - f = Utils.HexToByte(val, 20); - g = Utils.HexToByte(val, 22); - h = Utils.HexToByte(val, 24); - i = Utils.HexToByte(val, 26); - j = Utils.HexToByte(val, 28); - k = Utils.HexToByte(val, 30); - return; - } - } - } - catch { } - this = new UUID(); - throw new System.FormatException("Invalid UUID"); } public unsafe UUID(ReadOnlySpan sval) @@ -258,12 +123,6 @@ public unsafe UUID(ReadOnlySpan sval) if (len < 36) throw new Exception(); - while (--len > 35) - { - if (val[len] != ' ') - throw new Exception(); - } - if (val[13] != '-' || val[18] != '-' || val[23] != '-') throw new Exception(); @@ -294,7 +153,6 @@ public unsafe UUID(ReadOnlySpan sval) bytec1 = Utils.HexToByte(val, 16); } - d = Utils.HexToByte(val, 19); e = Utils.HexToByte(val, 21); @@ -309,12 +167,6 @@ public unsafe UUID(ReadOnlySpan sval) } else { - while (--len > 31) - { - if (val[len] != ' ') - throw new Exception(); - } - if (BitConverter.IsLittleEndian) { bytea3 = Utils.HexToByte(val, 0); @@ -583,41 +435,7 @@ public unsafe void FromBytes(byte[] source, int pos) public readonly unsafe byte[] GetBytes() { byte[] dest = new byte[16]; - if (Ssse3.IsSupported) - { - Vector128 rawval = Unsafe.As>(ref Unsafe.AsRef(in this)); - if (BitConverter.IsLittleEndian) - rawval = Ssse3.Shuffle(rawval, Vector128.Create((byte)0x03, 0x02, 0x01, 0x00, 0x05, 0x04, 0x07, 0x06, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F)); - Unsafe.As>(ref MemoryMarshal.GetArrayDataReference(dest)) = rawval; - return dest; - } - fixed (byte* ptr = &dest[0]) - { - if (BitConverter.IsLittleEndian) - { - *ptr = bytea3; - *(ptr + 1) = bytea2; - *(ptr + 2) = bytea1; - *(ptr + 3) = bytea0; - *(ptr + 4) = byteb1; - *(ptr + 5) = byteb0; - *(ptr + 6) = bytec1; - *(ptr + 7) = bytec0; - *(ulong*)(ptr + 8) = ulongb; - } - else - { - *(ulong*)(ptr) = ulonga; - *(ptr + 8) = d; - *(ptr + 9) = e; - *(ptr + 10) = f; - *(ptr + 11) = g; - *(ptr + 12) = h; - *(ptr + 13) = i; - *(ptr + 14) = j; - *(ptr + 15) = k; - } - } + ToBytes(dest, 0); return dest; } @@ -767,11 +585,6 @@ public unsafe static UUID Parse(ReadOnlySpan sval) { if (len < 36) throw new Exception(); - while (--len > 35) - { - if (val[len] != ' ') - throw new Exception(); - } if (val[13] != '-' || val[18] != '-' || val[23] != '-') throw new Exception(); @@ -817,12 +630,6 @@ public unsafe static UUID Parse(ReadOnlySpan sval) } else { - while (--len > 31) - { - if (val[len] != ' ') - throw new Exception(); - } - if (BitConverter.IsLittleEndian) { result.bytea3 = Utils.HexToByte(val, 0); @@ -910,11 +717,6 @@ public unsafe static bool TryParse(ReadOnlySpan sval, out UUID result) { if (len < 36) return false; - while (--len > 35) - { - if (val[len] != ' ') - return false; - } if (val[13] != '-' || val[18] != '-' || val[23] != '-') return false; @@ -960,11 +762,6 @@ public unsafe static bool TryParse(ReadOnlySpan sval, out UUID result) } else { - while (--len > 31) - { - if (val[len] != ' ') - return false; - } if (BitConverter.IsLittleEndian) { result.bytea3 = Utils.HexToByte(val, 0); diff --git a/OpenMetaverseTypes/UtilsConversions.cs b/OpenMetaverseTypes/UtilsConversions.cs index 6fd71530..4ffbe4dc 100644 --- a/OpenMetaverseTypes/UtilsConversions.cs +++ b/OpenMetaverseTypes/UtilsConversions.cs @@ -2994,7 +2994,7 @@ public static byte HighNibbleToHexByteChar(byte b) return (byte)(b > 9 ? b + 0x57 : b + ASCIIzero); } - public static unsafe void UUIDToByteDashString(ref UUID u, byte* dst) + public static unsafe void UUIDToByteDashString(UUID u, byte* dst) { if (Sse41.IsSupported) { @@ -3147,7 +3147,7 @@ public static unsafe osUTF8 UUIDToosUTF8(UUID v) { osUTF8 ret = new osUTF8(36); fixed (byte* d = ret.m_data) - UUIDToByteDashString(ref v, d); + UUIDToByteDashString(v, d); ret.m_len = 36; return ret; } From 351da86779f3b334a4fb437f23b6c0679ec99b94 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Sat, 26 Nov 2022 20:14:41 +0000 Subject: [PATCH 086/149] add a bit more simd --- OpenMetaverseTypes/UUID.cs | 240 +++++++++++++++++++++++++ OpenMetaverseTypes/UtilsConversions.cs | 7 +- 2 files changed, 245 insertions(+), 2 deletions(-) diff --git a/OpenMetaverseTypes/UUID.cs b/OpenMetaverseTypes/UUID.cs index 3eb04bbc..16ea1286 100644 --- a/OpenMetaverseTypes/UUID.cs +++ b/OpenMetaverseTypes/UUID.cs @@ -126,6 +126,86 @@ public unsafe UUID(ReadOnlySpan sval) if (val[13] != '-' || val[18] != '-' || val[23] != '-') throw new Exception(); + if (Sse42.IsSupported) + { + Vector128 input = Unsafe.As>(ref Unsafe.AsRef(val)); + Vector128 upper = Ssse3.Shuffle(input, Vector128.Create(0, 4, 8, 12, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff)); + Vector128 lower = Ssse3.Shuffle(input, Vector128.Create(2, 6, 10, 14, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff)); + + input = Unsafe.As>(ref Unsafe.AddByteOffset(ref Unsafe.AsRef(val), 18)); + Vector128 uppertmp = Ssse3.Shuffle(input, Vector128.Create(0xff, 0xff, 0xff, 0xff, 0, 4, 10, 14, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff)); + Vector128 lowerhalf = Ssse3.Shuffle(input, Vector128.Create(0xff, 0xff, 0xff, 0xff, 2, 6, 12, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff)); + upper = Sse2.Or(upper, uppertmp); + lower = Sse2.Or(lower, lowerhalf); + + lower = Sse41.Insert(lower, Unsafe.As(ref Unsafe.AddByteOffset(ref Unsafe.AsRef(val), 34)), 7); + + input = Unsafe.As>(ref Unsafe.AddByteOffset(ref Unsafe.AsRef(val), 38)); + uppertmp = Ssse3.Shuffle(input, Vector128.Create(0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 4, 10, 14, 0xff, 0xff, 0xff, 0xff)); + lowerhalf = Ssse3.Shuffle(input, Vector128.Create(0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 2, 6, 12, 0xff, 0xff, 0xff, 0xff, 0xff)); + upper = Sse2.Or(upper, uppertmp); + lower = Sse2.Or(lower, lowerhalf); + + lower = Sse41.Insert(lower, Unsafe.As(ref Unsafe.AddByteOffset(ref Unsafe.AsRef(val), 54)), 11); + + input = Unsafe.As>(ref Unsafe.AddByteOffset(ref Unsafe.AsRef(val), 56)); + uppertmp = Ssse3.Shuffle(input, Vector128.Create(0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 4, 8, 12)); + lowerhalf = Ssse3.Shuffle(input, Vector128.Create(0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 2, 6, 10, 14)); + + upper = Sse2.Or(upper, uppertmp); + lower = Sse2.Or(lower, lowerhalf); + + Vector128 charTolower = Vector128.Create((byte)0x20); + Vector128 upperLetters = Sse2.Or(upper, charTolower); + Vector128 lowerLetters = Sse2.Or(lower, charTolower); + + Vector128 letterTohex = Vector128.Create((byte)('a' - '0' - 10)); + upperLetters = Sse2.Subtract(upperLetters, letterTohex); + lowerLetters = Sse2.Subtract(lowerLetters, letterTohex); + + Vector128 char9 = Vector128.Create((byte)'9'); + Vector128 above9upper = (Sse2.CompareGreaterThan(upper.AsSByte(), char9.AsSByte())).AsByte(); + Vector128 above9lower = (Sse2.CompareGreaterThan(lower.AsSByte(), char9.AsSByte())).AsByte(); + + Vector128 ten = Vector128.Create((byte)('0' + 10)); + Vector128 tmpcmpA = Sse2.Subtract(upperLetters, ten); + Vector128 tmpcmpB = Sse2.Subtract(lowerLetters, ten); + + Vector128 fifteen = Vector128.Create((byte)('0' + 15)); + Vector128 tmpcmpC = Sse2.Subtract(fifteen, upperLetters); + Vector128 tmpcmpD = Sse2.Subtract(fifteen, lowerLetters); + + tmpcmpA = Sse2.Or(tmpcmpC, tmpcmpA); + tmpcmpB = Sse2.Or(tmpcmpD, tmpcmpB); + + tmpcmpA = Sse2.And(tmpcmpA, above9upper); + tmpcmpB = Sse2.And(tmpcmpB, above9lower); + + tmpcmpA = Sse2.Or(tmpcmpB, tmpcmpA); + int cmp = Sse2.MoveMask(tmpcmpA); + if (cmp != 0) + throw new Exception(); + + upper = Sse41.BlendVariable(upper, upperLetters, above9upper); + lower = Sse41.BlendVariable(lower, lowerLetters, above9lower); + + Vector128 charzero = Vector128.Create((byte)'0'); + upper = Sse2.Subtract(upper, charzero); + lower = Sse2.Subtract(lower, charzero); + + tmpcmpA = Sse2.Or(lower, upper); + cmp = Sse2.MoveMask(tmpcmpA); + if (cmp != 0) + throw new Exception(); + + upper = Sse2.ShiftLeftLogical(upper.AsUInt16(), 4).AsByte(); + lower = Sse2.Or(lower, upper); + if (BitConverter.IsLittleEndian) + lower = Ssse3.Shuffle(lower, Vector128.Create((byte)0x03, 0x02, 0x01, 0x00, 0x05, 0x04, 0x07, 0x06, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F)); + Unsafe.As>(ref Unsafe.AsRef(in this)) = lower; + return; + } + if (BitConverter.IsLittleEndian) { bytea3 = Utils.HexToByte(val, 0); @@ -589,6 +669,86 @@ public unsafe static UUID Parse(ReadOnlySpan sval) if (val[13] != '-' || val[18] != '-' || val[23] != '-') throw new Exception(); + if (Sse42.IsSupported) + { + Vector128 input = Unsafe.As>(ref Unsafe.AsRef(val)); + Vector128 upper = Ssse3.Shuffle(input, Vector128.Create(0, 4, 8, 12, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff)); + Vector128 lower = Ssse3.Shuffle(input, Vector128.Create(2, 6, 10, 14, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff)); + + input = Unsafe.As>(ref Unsafe.AddByteOffset(ref Unsafe.AsRef(val), 18)); + Vector128 uppertmp = Ssse3.Shuffle(input, Vector128.Create(0xff, 0xff, 0xff, 0xff, 0, 4, 10, 14, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff)); + Vector128 lowerhalf = Ssse3.Shuffle(input, Vector128.Create(0xff, 0xff, 0xff, 0xff, 2, 6, 12, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff)); + upper = Sse2.Or(upper, uppertmp); + lower = Sse2.Or(lower, lowerhalf); + + lower = Sse41.Insert(lower, Unsafe.As(ref Unsafe.AddByteOffset(ref Unsafe.AsRef(val), 34)), 7); + + input = Unsafe.As>(ref Unsafe.AddByteOffset(ref Unsafe.AsRef(val), 38)); + uppertmp = Ssse3.Shuffle(input, Vector128.Create(0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 4, 10, 14, 0xff, 0xff, 0xff, 0xff)); + lowerhalf = Ssse3.Shuffle(input, Vector128.Create(0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 2, 6, 12, 0xff, 0xff, 0xff, 0xff, 0xff)); + upper = Sse2.Or(upper, uppertmp); + lower = Sse2.Or(lower, lowerhalf); + + lower = Sse41.Insert(lower, Unsafe.As(ref Unsafe.AddByteOffset(ref Unsafe.AsRef(val), 54)), 11); + + input = Unsafe.As>(ref Unsafe.AddByteOffset(ref Unsafe.AsRef(val), 56)); + uppertmp = Ssse3.Shuffle(input, Vector128.Create(0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 4, 8, 12)); + lowerhalf = Ssse3.Shuffle(input, Vector128.Create(0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 2, 6, 10, 14)); + + upper = Sse2.Or(upper, uppertmp); + lower = Sse2.Or(lower, lowerhalf); + + Vector128 charTolower = Vector128.Create((byte)0x20); + Vector128 upperLetters = Sse2.Or(upper, charTolower); + Vector128 lowerLetters = Sse2.Or(lower, charTolower); + + Vector128 letterTohex = Vector128.Create((byte)('a' - '0' - 10)); + upperLetters = Sse2.Subtract(upperLetters, letterTohex); + lowerLetters = Sse2.Subtract(lowerLetters, letterTohex); + + Vector128 char9 = Vector128.Create((byte)'9'); + Vector128 above9upper = (Sse2.CompareGreaterThan(upper.AsSByte(), char9.AsSByte())).AsByte(); + Vector128 above9lower = (Sse2.CompareGreaterThan(lower.AsSByte(), char9.AsSByte())).AsByte(); + + Vector128 ten = Vector128.Create((byte)('0' + 10)); + Vector128 tmpcmpA = Sse2.Subtract(upperLetters, ten); + Vector128 tmpcmpB = Sse2.Subtract(lowerLetters, ten); + + Vector128 fifteen = Vector128.Create((byte)('0' + 15)); + Vector128 tmpcmpC = Sse2.Subtract(fifteen, upperLetters); + Vector128 tmpcmpD = Sse2.Subtract(fifteen, lowerLetters); + + tmpcmpA = Sse2.Or(tmpcmpC, tmpcmpA); + tmpcmpB = Sse2.Or(tmpcmpD, tmpcmpB); + + tmpcmpA = Sse2.And(tmpcmpA, above9upper); + tmpcmpB = Sse2.And(tmpcmpB, above9lower); + + tmpcmpA = Sse2.Or(tmpcmpB, tmpcmpA); + int cmp = Sse2.MoveMask(tmpcmpA); + if (cmp != 0) + throw new Exception(); + + upper = Sse41.BlendVariable(upper, upperLetters, above9upper); + lower = Sse41.BlendVariable(lower, lowerLetters, above9lower); + + Vector128 charzero = Vector128.Create((byte)'0'); + upper = Sse2.Subtract(upper, charzero); + lower = Sse2.Subtract(lower, charzero); + + tmpcmpA = Sse2.Or(lower, upper); + cmp = Sse2.MoveMask(tmpcmpA); + if (cmp != 0) + throw new Exception(); + + upper = Sse2.ShiftLeftLogical(upper.AsUInt16(), 4).AsByte(); + lower = Sse2.Or(lower, upper); + if (BitConverter.IsLittleEndian) + lower = Ssse3.Shuffle(lower, Vector128.Create((byte)0x03, 0x02, 0x01, 0x00, 0x05, 0x04, 0x07, 0x06, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F)); + Unsafe.As>(ref Unsafe.AsRef(in result)) = lower; + return result; + } + if (BitConverter.IsLittleEndian) { result.bytea3 = Utils.HexToByte(val, 0); @@ -721,6 +881,86 @@ public unsafe static bool TryParse(ReadOnlySpan sval, out UUID result) if (val[13] != '-' || val[18] != '-' || val[23] != '-') return false; + if (Sse42.IsSupported) + { + Vector128 input = Unsafe.As>(ref Unsafe.AsRef(val)); + Vector128 upper = Ssse3.Shuffle(input, Vector128.Create(0, 4, 8, 12, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff)); + Vector128 lower = Ssse3.Shuffle(input, Vector128.Create(2, 6, 10, 14, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff)); + + input = Unsafe.As>(ref Unsafe.AddByteOffset(ref Unsafe.AsRef(val), 18)); + Vector128 uppertmp = Ssse3.Shuffle(input, Vector128.Create(0xff, 0xff, 0xff, 0xff, 0, 4, 10, 14, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff)); + Vector128 lowerhalf = Ssse3.Shuffle(input, Vector128.Create(0xff, 0xff, 0xff, 0xff, 2, 6, 12, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff)); + upper = Sse2.Or(upper, uppertmp); + lower = Sse2.Or(lower, lowerhalf); + + lower = Sse41.Insert(lower, Unsafe.As(ref Unsafe.AddByteOffset(ref Unsafe.AsRef(val), 34)), 7); + + input = Unsafe.As>(ref Unsafe.AddByteOffset(ref Unsafe.AsRef(val), 38)); + uppertmp = Ssse3.Shuffle(input, Vector128.Create(0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 4, 10, 14, 0xff, 0xff, 0xff, 0xff)); + lowerhalf = Ssse3.Shuffle(input, Vector128.Create(0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 2, 6, 12, 0xff, 0xff, 0xff, 0xff, 0xff)); + upper = Sse2.Or(upper, uppertmp); + lower = Sse2.Or(lower, lowerhalf); + + lower = Sse41.Insert(lower, Unsafe.As(ref Unsafe.AddByteOffset(ref Unsafe.AsRef(val), 54)), 11); + + input = Unsafe.As>(ref Unsafe.AddByteOffset(ref Unsafe.AsRef(val), 56)); + uppertmp = Ssse3.Shuffle(input, Vector128.Create(0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 4, 8, 12)); + lowerhalf = Ssse3.Shuffle(input, Vector128.Create(0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 2, 6, 10, 14)); + + upper = Sse2.Or(upper, uppertmp); + lower = Sse2.Or(lower, lowerhalf); + + Vector128 charTolower = Vector128.Create((byte)0x20); + Vector128 upperLetters = Sse2.Or(upper, charTolower); + Vector128 lowerLetters = Sse2.Or(lower, charTolower); + + Vector128 letterTohex = Vector128.Create((byte)('a' - '0' - 10)); + upperLetters = Sse2.Subtract(upperLetters, letterTohex); + lowerLetters = Sse2.Subtract(lowerLetters, letterTohex); + + Vector128 char9 = Vector128.Create((byte)'9'); + Vector128 above9upper = (Sse2.CompareGreaterThan(upper.AsSByte(), char9.AsSByte())).AsByte(); + Vector128 above9lower = (Sse2.CompareGreaterThan(lower.AsSByte(), char9.AsSByte())).AsByte(); + + Vector128 ten = Vector128.Create((byte)('0' + 10)); + Vector128 tmpcmpA = Sse2.Subtract(upperLetters, ten); + Vector128 tmpcmpB = Sse2.Subtract(lowerLetters, ten); + + Vector128 fifteen = Vector128.Create((byte)('0' + 15)); + Vector128 tmpcmpC = Sse2.Subtract(fifteen, upperLetters); + Vector128 tmpcmpD = Sse2.Subtract(fifteen, lowerLetters); + + tmpcmpA = Sse2.Or(tmpcmpC, tmpcmpA); + tmpcmpB = Sse2.Or(tmpcmpD, tmpcmpB); + + tmpcmpA = Sse2.And(tmpcmpA, above9upper); + tmpcmpB = Sse2.And(tmpcmpB, above9lower); + + tmpcmpA = Sse2.Or(tmpcmpB, tmpcmpA); + int cmp = Sse2.MoveMask(tmpcmpA); + if (cmp != 0) + return false; + + upper = Sse41.BlendVariable(upper, upperLetters, above9upper); + lower = Sse41.BlendVariable(lower, lowerLetters, above9lower); + + Vector128 charzero = Vector128.Create((byte)'0'); + upper = Sse2.Subtract(upper, charzero); + lower = Sse2.Subtract(lower, charzero); + + tmpcmpA = Sse2.Or(lower, upper); + cmp = Sse2.MoveMask(tmpcmpA); + if (cmp != 0) + return false; + + upper = Sse2.ShiftLeftLogical(upper.AsUInt16(), 4).AsByte(); + lower = Sse2.Or(lower, upper); + if (BitConverter.IsLittleEndian) + lower = Ssse3.Shuffle(lower, Vector128.Create((byte)0x03, 0x02, 0x01, 0x00, 0x05, 0x04, 0x07, 0x06, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F)); + Unsafe.As>(ref Unsafe.AsRef(in result)) = lower; + return true; + } + if (BitConverter.IsLittleEndian) { result.bytea3 = Utils.HexToByte(val, 0); diff --git a/OpenMetaverseTypes/UtilsConversions.cs b/OpenMetaverseTypes/UtilsConversions.cs index 4ffbe4dc..4a0be06d 100644 --- a/OpenMetaverseTypes/UtilsConversions.cs +++ b/OpenMetaverseTypes/UtilsConversions.cs @@ -1927,6 +1927,7 @@ public static int osUTF8GetBytesCount(string sstr, int maxnbytes, out int maxsou /// /// Character to test /// true if hex digit, false if not + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool IsHexDigit(Char c) { @@ -1949,7 +1950,7 @@ public static bool IsHexDigit(Char c) return false; } - + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int HexNibbleWithChk(Char c) { const int numA = 65; @@ -1971,7 +1972,7 @@ public static int HexNibbleWithChk(Char c) return -1; } - + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int HexNibbleWithChk(byte c) { const int numA = 65; @@ -1994,6 +1995,7 @@ public static int HexNibbleWithChk(byte c) return -1; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int HexNibble(Char c) { @@ -2020,6 +2022,7 @@ public static int HexNibble(Char c) throw new FormatException("invalid hex char"); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int HexNibble(byte c) { const byte numA = (byte)'A'; From 914182980ef2f5a0f0273cc7d9371fc6d14fd6eb Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Tue, 6 Dec 2022 18:23:10 +0000 Subject: [PATCH 087/149] put back Guid field on UUID. This is not nice, but opensim serializeres depend on it --- OpenMetaverseTypes/UUID.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/OpenMetaverseTypes/UUID.cs b/OpenMetaverseTypes/UUID.cs index 16ea1286..32b11d26 100644 --- a/OpenMetaverseTypes/UUID.cs +++ b/OpenMetaverseTypes/UUID.cs @@ -71,11 +71,13 @@ public struct UUID : IComparable,IComparable, IEquatable, IEqualityC [XmlIgnore] [NonSerialized()] [FieldOffset(8)] public int intc; [XmlIgnore] [NonSerialized()] [FieldOffset(12)] public int intd; - [XmlIgnore] [NonSerialized()] [FieldOffset(0)] public ulong ulonga; + [XmlIgnore] [NonSerialized()][FieldOffset(0)] public ulong ulonga; [XmlIgnore] [NonSerialized()] [FieldOffset(8)] public ulong ulongb; - #region Constructors + [FieldOffset(0)] public Guid Guid; + #region Constructors + /* public Guid Guid { get @@ -87,6 +89,7 @@ public Guid Guid Unsafe.As(ref this) = value; } } + */ /// /// Constructor that takes a string UUID representation /// From 4015ac20f73119f4d5c6f57619ba95fce89f17dd Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Tue, 6 Dec 2022 18:26:33 +0000 Subject: [PATCH 088/149] a bit more simd on uuid --- OpenMetaverseTypes/OSUTF8.cs | 118 ++++++++++++++++++++++++------ OpenMetaverseTypes/OSUTF8Slice.cs | 72 ++++++++++++++++++ OpenMetaverseTypes/UUID.cs | 6 +- OpenMetaverseTypes/Vector4.cs | 5 +- 4 files changed, 169 insertions(+), 32 deletions(-) diff --git a/OpenMetaverseTypes/OSUTF8.cs b/OpenMetaverseTypes/OSUTF8.cs index 11a3102a..ece6c10f 100644 --- a/OpenMetaverseTypes/OSUTF8.cs +++ b/OpenMetaverseTypes/OSUTF8.cs @@ -1003,43 +1003,113 @@ public unsafe static bool TryParseUUID(osUTF8 inp, out UUID result) if (val[13] != '-' || val[18] != '-' || val[23] != '-') return false; + if (Sse42.IsSupported) + { + Vector128 input = Unsafe.As>(ref Unsafe.AsRef(val)); + Vector128 upper = Ssse3.Shuffle(input, Vector128.Create(0, 2, 4, 6, 9, 11, 14, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff)); + Vector128 lower = Ssse3.Shuffle(input, Vector128.Create(1, 3, 5, 7, 10, 12, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff)); + input = Unsafe.As>(ref Unsafe.AddByteOffset(ref Unsafe.AsRef(val), 16 + 3)); + Vector128 upperhalf = Ssse3.Shuffle(input, Vector128.Create(0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 2, 5, 7, 9, 11, 13, 15)); + Vector128 lowerhalf = Ssse3.Shuffle(input, Vector128.Create(0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 1, 3, 6, 8, 10, 12, 14, 0xff)); + upper = Sse2.Or(upper, upperhalf); + lower = Sse2.Or(lower, lowerhalf); + + upper = Sse41.Insert(upper, Unsafe.As(ref Unsafe.AddByteOffset(ref Unsafe.AsRef(val), 16)), 7); + lower = Sse41.Insert(lower, Unsafe.As(ref Unsafe.AddByteOffset(ref Unsafe.AsRef(val), 17)), 7); + lower = Sse41.Insert(lower, Unsafe.As(ref Unsafe.AddByteOffset(ref Unsafe.AsRef(val), 35)), 15); + + Vector128 charf = Vector128.Create((byte)'f'); + Vector128 tmpcmp = Sse2.Subtract(charf, lower); + int cmp = Sse2.MoveMask(tmpcmp); + if (cmp != 0) + throw new Exception("bad"); + + tmpcmp = Sse2.Subtract(charf, upper); + cmp = Sse2.MoveMask(tmpcmp); + if (cmp != 0) + throw new Exception("bad"); + + Vector128 charTolower = Vector128.Create((byte)0x20); + Vector128 lowerLetters = Sse2.Or(lower, charTolower); + Vector128 upperLetters = Sse2.Or(upper, charTolower); + + Vector128 letterTohex = Vector128.Create((byte)('a' - '0' - 10)); + lowerLetters = Sse2.Subtract(lowerLetters, letterTohex); + upperLetters = Sse2.Subtract(upperLetters, letterTohex); + + Vector128 char9 = Vector128.Create((byte)'9'); + Vector128 above9lower = (Sse2.CompareGreaterThan(lower.AsSByte(), char9.AsSByte())).AsByte(); + + Vector128 ten = Vector128.Create((byte)('0' + 10)); + tmpcmp = Sse2.Subtract(lowerLetters, ten); + tmpcmp = Sse2.And(tmpcmp, above9lower); + cmp = Sse2.MoveMask(tmpcmp); + if (cmp != 0) + throw new Exception("bad"); + Vector128 above9upper = (Sse2.CompareGreaterThan(upper.AsSByte(), char9.AsSByte())).AsByte(); + + tmpcmp = Sse2.Subtract(upperLetters, ten); + tmpcmp = Sse2.And(tmpcmp, above9upper); + cmp = Sse2.MoveMask(tmpcmp); + if (cmp != 0) + throw new Exception("bad"); + + lower = Sse41.BlendVariable(lower, lowerLetters, above9lower); + upper = Sse41.BlendVariable(upper, upperLetters, above9upper); + Vector128 charzero = Vector128.Create((byte)'0'); + lower = Sse2.Subtract(lower, charzero); + cmp = Sse2.MoveMask(lower); + if (cmp != 0) + throw new Exception("bad"); + upper = Sse2.Subtract(upper, charzero); + cmp = Sse2.MoveMask(upper); + if (cmp != 0) + throw new Exception("bad"); + upper = Sse2.ShiftLeftLogical(upper.AsUInt16(), 4).AsByte(); + lower = Sse2.Or(lower, upper); + if (BitConverter.IsLittleEndian) + lower = Ssse3.Shuffle(lower, Vector128.Create((byte)0x03, 0x02, 0x01, 0x00, 0x05, 0x04, 0x07, 0x06, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F)); + Unsafe.As>(ref Unsafe.AsRef(in result)) = lower; + return true; + } + if (BitConverter.IsLittleEndian) { - result.bytea3 = (byte)Utils.HexToByte(val, 0); - result.bytea2 = (byte)Utils.HexToByte(val, 2); - result.bytea1 = (byte)Utils.HexToByte(val, 4); - result.bytea0 = (byte)Utils.HexToByte(val, 6); + result.bytea3 = Utils.HexToByte(val, 0); + result.bytea2 = Utils.HexToByte(val, 2); + result.bytea1 = Utils.HexToByte(val, 4); + result.bytea0 = Utils.HexToByte(val, 6); - result.byteb1 = (byte)Utils.HexToByte(val, 9); - result.byteb0 = (byte)Utils.HexToByte(val, 11); + result.byteb1 = Utils.HexToByte(val, 9); + result.byteb0 = Utils.HexToByte(val, 11); - result.bytec1 = (byte)Utils.HexToByte(val, 14); - result.bytec0 = (byte)Utils.HexToByte(val, 16); + result.bytec1 = Utils.HexToByte(val, 14); + result.bytec0 = Utils.HexToByte(val, 16); } else { - result.bytea0 = (byte)Utils.HexToByte(val, 0); - result.bytea1 = (byte)Utils.HexToByte(val, 2); - result.bytea2 = (byte)Utils.HexToByte(val, 4); - result.bytea3 = (byte)Utils.HexToByte(val, 6); + result.bytea0 = Utils.HexToByte(val, 0); + result.bytea1 = Utils.HexToByte(val, 2); + result.bytea2 = Utils.HexToByte(val, 4); + result.bytea3 = Utils.HexToByte(val, 6); - result.byteb0 = (byte)Utils.HexToByte(val, 9); - result.byteb1 = (byte)Utils.HexToByte(val, 11); + result.byteb0 = Utils.HexToByte(val, 9); + result.byteb1 = Utils.HexToByte(val, 11); - result.bytec0 = (byte)Utils.HexToByte(val, 14); - result.bytec1 = (byte)Utils.HexToByte(val, 16); + result.bytec0 = Utils.HexToByte(val, 14); + result.bytec1 = Utils.HexToByte(val, 16); } - result.d = (byte)Utils.HexToByte(val, 19); - result.e = (byte)Utils.HexToByte(val, 21); + result.d = Utils.HexToByte(val, 19); + result.e = Utils.HexToByte(val, 21); - result.f = (byte)Utils.HexToByte(val, 24); - result.g = (byte)Utils.HexToByte(val, 26); - result.h = (byte)Utils.HexToByte(val, 28); - result.i = (byte)Utils.HexToByte(val, 30); - result.j = (byte)Utils.HexToByte(val, 32); - result.k = (byte)Utils.HexToByte(val, 34); + result.f = Utils.HexToByte(val, 24); + result.g = Utils.HexToByte(val, 26); + result.h = Utils.HexToByte(val, 28); + result.i = Utils.HexToByte(val, 30); + result.j = Utils.HexToByte(val, 32); + result.k = Utils.HexToByte(val, 34); return true; } else diff --git a/OpenMetaverseTypes/OSUTF8Slice.cs b/OpenMetaverseTypes/OSUTF8Slice.cs index 664c4278..21c5947d 100644 --- a/OpenMetaverseTypes/OSUTF8Slice.cs +++ b/OpenMetaverseTypes/OSUTF8Slice.cs @@ -39,6 +39,8 @@ Ubit Umarov (Leal Duarte) 2020 using System.Collections.Generic; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; +using System.Runtime.Intrinsics.X86; +using System.Runtime.Intrinsics; namespace OpenMetaverse { @@ -1571,6 +1573,76 @@ public unsafe static bool TryParseUUID(osUTF8Slice inp, out UUID result) if (val[13] != '-' || val[18] != '-' || val[23] != '-') return false; + if (Sse42.IsSupported) + { + Vector128 input = Unsafe.As>(ref Unsafe.AsRef(val)); + Vector128 upper = Ssse3.Shuffle(input, Vector128.Create(0, 2, 4, 6, 9, 11, 14, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff)); + Vector128 lower = Ssse3.Shuffle(input, Vector128.Create(1, 3, 5, 7, 10, 12, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff)); + input = Unsafe.As>(ref Unsafe.AddByteOffset(ref Unsafe.AsRef(val), 16 + 3)); + Vector128 upperhalf = Ssse3.Shuffle(input, Vector128.Create(0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 2, 5, 7, 9, 11, 13, 15)); + Vector128 lowerhalf = Ssse3.Shuffle(input, Vector128.Create(0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 1, 3, 6, 8, 10, 12, 14, 0xff)); + upper = Sse2.Or(upper, upperhalf); + lower = Sse2.Or(lower, lowerhalf); + + upper = Sse41.Insert(upper, Unsafe.As(ref Unsafe.AddByteOffset(ref Unsafe.AsRef(val), 16)), 7); + lower = Sse41.Insert(lower, Unsafe.As(ref Unsafe.AddByteOffset(ref Unsafe.AsRef(val), 17)), 7); + lower = Sse41.Insert(lower, Unsafe.As(ref Unsafe.AddByteOffset(ref Unsafe.AsRef(val), 35)), 15); + + Vector128 charf = Vector128.Create((byte)'f'); + Vector128 tmpcmp = Sse2.Subtract(charf, lower); + int cmp = Sse2.MoveMask(tmpcmp); + if (cmp != 0) + throw new Exception("bad"); + + tmpcmp = Sse2.Subtract(charf, upper); + cmp = Sse2.MoveMask(tmpcmp); + if (cmp != 0) + throw new Exception("bad"); + + Vector128 charTolower = Vector128.Create((byte)0x20); + Vector128 lowerLetters = Sse2.Or(lower, charTolower); + Vector128 upperLetters = Sse2.Or(upper, charTolower); + + Vector128 letterTohex = Vector128.Create((byte)('a' - '0' - 10)); + lowerLetters = Sse2.Subtract(lowerLetters, letterTohex); + upperLetters = Sse2.Subtract(upperLetters, letterTohex); + + Vector128 char9 = Vector128.Create((byte)'9'); + Vector128 above9lower = (Sse2.CompareGreaterThan(lower.AsSByte(), char9.AsSByte())).AsByte(); + + Vector128 ten = Vector128.Create((byte)('0' + 10)); + tmpcmp = Sse2.Subtract(lowerLetters, ten); + tmpcmp = Sse2.And(tmpcmp, above9lower); + cmp = Sse2.MoveMask(tmpcmp); + if (cmp != 0) + throw new Exception("bad"); + Vector128 above9upper = (Sse2.CompareGreaterThan(upper.AsSByte(), char9.AsSByte())).AsByte(); + + tmpcmp = Sse2.Subtract(upperLetters, ten); + tmpcmp = Sse2.And(tmpcmp, above9upper); + cmp = Sse2.MoveMask(tmpcmp); + if (cmp != 0) + throw new Exception("bad"); + + lower = Sse41.BlendVariable(lower, lowerLetters, above9lower); + upper = Sse41.BlendVariable(upper, upperLetters, above9upper); + Vector128 charzero = Vector128.Create((byte)'0'); + lower = Sse2.Subtract(lower, charzero); + cmp = Sse2.MoveMask(lower); + if (cmp != 0) + throw new Exception("bad"); + upper = Sse2.Subtract(upper, charzero); + cmp = Sse2.MoveMask(upper); + if (cmp != 0) + throw new Exception("bad"); + upper = Sse2.ShiftLeftLogical(upper.AsUInt16(), 4).AsByte(); + lower = Sse2.Or(lower, upper); + if (BitConverter.IsLittleEndian) + lower = Ssse3.Shuffle(lower, Vector128.Create((byte)0x03, 0x02, 0x01, 0x00, 0x05, 0x04, 0x07, 0x06, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F)); + Unsafe.As>(ref Unsafe.AsRef(in result)) = lower; + return true; + } + if (BitConverter.IsLittleEndian) { result.bytea3 = Utils.HexToByte(val, 0); diff --git a/OpenMetaverseTypes/UUID.cs b/OpenMetaverseTypes/UUID.cs index 32b11d26..b08d8c41 100644 --- a/OpenMetaverseTypes/UUID.cs +++ b/OpenMetaverseTypes/UUID.cs @@ -602,7 +602,7 @@ public readonly unsafe void ToBytes(byte* ptr) /// /// The CRC checksum for this UUID [MethodImpl(MethodImplOptions.AggressiveInlining)] - public uint CRC() + public readonly uint CRC() { return (uint)a + (uint)intb + (uint)intc + (uint)intd; } @@ -1097,9 +1097,7 @@ public readonly override int GetHashCode() [MethodImpl(MethodImplOptions.AggressiveInlining)] public readonly int GetHashCode(UUID u) { - int h = Utils.CombineHash(u.intd, u.intc); - h = Utils.CombineHash(h, u.intb); - return Utils.CombineHash(h, u.a); + return u.GetHashCode(); } /// diff --git a/OpenMetaverseTypes/Vector4.cs b/OpenMetaverseTypes/Vector4.cs index 27bbadfb..e40e050b 100644 --- a/OpenMetaverseTypes/Vector4.cs +++ b/OpenMetaverseTypes/Vector4.cs @@ -94,10 +94,7 @@ public Vector4(byte[] byteArray, int pos) public Vector4(Vector4 value) { - X = value.X; - Y = value.Y; - Z = value.Z; - W = value.W; + this = value; } #endregion Constructors From cd1811c2e2779fd61fc9e97377a816618a311f84 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Tue, 6 Dec 2022 18:58:56 +0000 Subject: [PATCH 089/149] a bit more simd on quaternion ( plus some missing changes on prev commit --- OpenMetaverseTypes/Quaternion.cs | 167 ++++++++++++++++++++++++------- 1 file changed, 129 insertions(+), 38 deletions(-) diff --git a/OpenMetaverseTypes/Quaternion.cs b/OpenMetaverseTypes/Quaternion.cs index 7bf9d918..95b1561c 100644 --- a/OpenMetaverseTypes/Quaternion.cs +++ b/OpenMetaverseTypes/Quaternion.cs @@ -29,7 +29,6 @@ using System.Runtime.InteropServices; using System.Globalization; using System.Text; -using System.Reflection.Metadata; using System.Runtime.Intrinsics.X86; using System.Runtime.Intrinsics; @@ -111,10 +110,13 @@ public Quaternion(byte[] byteArray, int pos, bool normalized) [MethodImpl(MethodImplOptions.AggressiveInlining)] public Quaternion(Quaternion q) { - X = q.X; - Y = q.Y; - Z = q.Z; - W = q.W; + this = q; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Quaternion(Vector128 q) : this() + { + Unsafe.As>(ref Unsafe.AsRef(this)) = q; } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -155,30 +157,52 @@ public Quaternion(MainAxis BaseAxis, float angle) [MethodImpl(MethodImplOptions.AggressiveInlining)] public readonly bool ApproxEquals(Quaternion quat) { + // assume normalized + return MathF.Abs(quat.W - W) < 1e-6f && + MathF.Abs(quat.Z - Z) < 1e-6f && + MathF.Abs(quat.X - X) < 1e-6f; + } + /* not faster + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public readonly bool ApproxEquals2(in Quaternion quat) + { + if (Sse.IsSupported) + { + Vector128 tol = Vector128.Create(1e-6f); + + Vector128 a = Unsafe.As>(ref Unsafe.AsRef(this)); + Vector128 c = Sse.CompareEqual(tol, tol); + + Vector128 b = Unsafe.As>(ref Unsafe.AsRef(quat)); + c = Sse2.ShiftRightLogical(c.AsInt32(), 1).AsSingle(); + + a = Sse.Subtract(a, b); + a = Sse.And(a, c); + a = Sse.CompareLessThan(a, tol); + int res = Sse.MoveMask(a); + return res == 0x0f; + } // assume normalized return MathF.Abs(quat.X - X) < 1e-6f && MathF.Abs(quat.Y - Y) < 1e-6f && MathF.Abs(quat.Z - Z) < 1e-6f; } + */ [MethodImpl(MethodImplOptions.AggressiveInlining)] public readonly bool ApproxEquals(Quaternion quat, float tolerance) { // assume normalized - return MathF.Abs(quat.X - X) < tolerance && - MathF.Abs(quat.Y - Y) < tolerance && - MathF.Abs(quat.Z - Z) < tolerance; + return MathF.Abs(quat.W - W) < tolerance && + MathF.Abs(quat.Z - Z) < tolerance && + MathF.Abs(quat.X - X) < tolerance; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public readonly bool IsIdentity() { // assume normalized - if(W > (1.0f - 1e-6f)) - return true; - if (W < -(1.0f - 1e-6f)) - return true; - return false; + return MathF.Abs(W) > (1.0f - 1e-6f); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -195,31 +219,30 @@ public readonly bool IsIdentityOrZero() } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public readonly float Length() - { - return MathF.Sqrt((X * X) + (Y * Y) + (Z * Z) + (W * W)); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public readonly float LengthSquared() + public readonly unsafe float Length() { - return (X * X) + (Y * Y) + (Z * Z) + (W * W); + if (Sse41.IsSupported) + { + Vector128 q = Unsafe.As>(ref Unsafe.AsRef(this)); + q = Sse41.DotProduct(q, q, 0xf1); + return MathF.Sqrt(q.ToScalar()); + } + else + return MathF.Sqrt((X * X) + (Y * Y) + (Z * Z) + (W * W)); } - /* is slower [MethodImpl(MethodImplOptions.AggressiveInlining)] - public unsafe float LengthSquared2() + public readonly unsafe float LengthSquared() { - if (Avx.IsSupported) + if (Sse41.IsSupported) { - Vector128 q = Avx.LoadVector128((float*)Unsafe.AsPointer(ref X)); - q = Avx.DotProduct(q, q, 0xf1); + Vector128 q = Unsafe.As>(ref Unsafe.AsRef(this)); + q = Sse41.DotProduct(q, q, 0xf1); return q.ToScalar(); } else return (X * X) + (Y * Y) + (Z * Z) + (W * W); } - */ /// /// Normalizes the quaternion @@ -227,6 +250,25 @@ public unsafe float LengthSquared2() [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe void Normalize() { + if (Sse41.IsSupported) + { + Vector128 q = Unsafe.As>(ref Unsafe.AsRef(this)); + Vector128 d = Sse41.DotProduct(q, q, 0xff); + float m = d.ToScalar(); + if (m > 1e-6f) + { + d = Sse.Sqrt(d); + q = Sse.Divide(q, d); + //d = Sse.ReciprocalSqrt(d); + //q = Sse.Multiply(q, d); + Unsafe.As>(ref this) = q; + return; + } + q = Vector128.Create(0f, 0f, 0f, 1f); + Unsafe.As>(ref this) = q; + return; + } + float mag = LengthSquared(); if (mag > 1e-6f) { @@ -277,25 +319,52 @@ public void Invert() [MethodImpl(MethodImplOptions.AggressiveInlining)] public readonly float Dot(Quaternion q2) { + if (Sse41.IsSupported) + { + Vector128 q = Unsafe.As>(ref Unsafe.AsRef(this)); + Vector128 d = Unsafe.As>(ref q2); + d = Sse41.DotProduct(q, d, 0xf1); + return d.ToScalar(); + } return (X * q2.X) + (Y * q2.Y) + (Z * q2.Z) + (W * q2.W); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Add(Quaternion quaternion2) { - X += quaternion2.X; - Y += quaternion2.Y; - Z += quaternion2.Z; - W += quaternion2.W; + if (Sse41.IsSupported) + { + Vector128 q = Unsafe.As>(ref Unsafe.AsRef(this)); + Vector128 d = Unsafe.As>(ref quaternion2); + d = Sse.Add(q, d); + Unsafe.As>(ref Unsafe.AsRef(this)) = d; + } + else + { + X += quaternion2.X; + Y += quaternion2.Y; + Z += quaternion2.Z; + W += quaternion2.W; + } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Sub(Quaternion quaternion2) { - X -= quaternion2.X; - Y -= quaternion2.Y; - Z -= quaternion2.Z; - W -= quaternion2.W; + if (Sse41.IsSupported) + { + Vector128 q = Unsafe.As>(ref Unsafe.AsRef(this)); + Vector128 d = Unsafe.As>(ref quaternion2); + d = Sse.Subtract(q, d); + Unsafe.As>(ref Unsafe.AsRef(this)) = d; + } + else + { + X -= quaternion2.X; + Y -= quaternion2.Y; + Z -= quaternion2.Z; + W -= quaternion2.W; + } } /// @@ -601,8 +670,16 @@ public readonly void GetAxisAngle(out Vector3 axis, out float angle) #region Static Methods [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Quaternion Add(Quaternion quaternion1, Quaternion quaternion2) + public static Quaternion Add(in Quaternion quaternion1, in Quaternion quaternion2) { + if (Sse.IsSupported) + { + Vector128 a = Unsafe.As>(ref Unsafe.AsRef(quaternion1)); + Vector128 b = Unsafe.As>(ref Unsafe.AsRef(quaternion2)); + a = Sse.Add(a, b); + return new Quaternion(a); + } + return new Quaternion( quaternion1.X + quaternion2.X, quaternion1.Y + quaternion2.Y, @@ -614,9 +691,16 @@ public static Quaternion Add(Quaternion quaternion1, Quaternion quaternion2) /// Returns the conjugate (spatial inverse) of a quaternion /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Quaternion Conjugate(Quaternion quaternion) + public static Quaternion Conjugate(in Quaternion quaternion) { - return new Quaternion( -quaternion.X, -quaternion.Y, -quaternion.Z, quaternion.W); + if (Sse.IsSupported) + { + Vector128 d = Unsafe.As>(ref Unsafe.AsRef(quaternion)); + Vector128 Mask = Vector128.Create(0x80000000, 0x80000000, 0x80000000, 0).AsSingle(); + d = Sse.Xor(d, Mask); + return new Quaternion(d); + } + return new Quaternion(-quaternion.X, -quaternion.Y, -quaternion.Z, quaternion.W); } /// @@ -821,6 +905,13 @@ public static Quaternion Divide(Quaternion q1, Quaternion q2) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static float Dot(Quaternion q1, Quaternion q2) { + if (Sse41.IsSupported) + { + Vector128 q = Unsafe.As>(ref q1); + Vector128 d = Unsafe.As>(ref q2); + d = Sse41.DotProduct(q, d, 0xf1); + return d.ToScalar(); + } return (q1.X * q2.X) + (q1.Y * q2.Y) + (q1.Z * q2.Z) + (q1.W * q2.W); } From f666664c9b5b4e399f42ed95c43cc5c39bc3aee4 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Wed, 25 Jan 2023 22:05:06 +0000 Subject: [PATCH 090/149] on uuid.tryparse only allow spaces after the uuid. This is currently needed on some opensim uui parsing --- OpenMetaverseTypes/OSUTF8.cs | 3 +++ OpenMetaverseTypes/Quaternion.cs | 8 ++++---- OpenMetaverseTypes/UUID.cs | 11 +++++++++++ 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/OpenMetaverseTypes/OSUTF8.cs b/OpenMetaverseTypes/OSUTF8.cs index ece6c10f..6bffbacc 100644 --- a/OpenMetaverseTypes/OSUTF8.cs +++ b/OpenMetaverseTypes/OSUTF8.cs @@ -38,6 +38,9 @@ Ubit Umarov (Leal Duarte) 2020 using System.Text; using System.Collections.Generic; using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics.X86; +using System.Runtime.Intrinsics; namespace OpenMetaverse { diff --git a/OpenMetaverseTypes/Quaternion.cs b/OpenMetaverseTypes/Quaternion.cs index 95b1561c..09ad80ba 100644 --- a/OpenMetaverseTypes/Quaternion.cs +++ b/OpenMetaverseTypes/Quaternion.cs @@ -330,12 +330,12 @@ public readonly float Dot(Quaternion q2) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Add(Quaternion quaternion2) + public void Add(in Quaternion quaternion2) { if (Sse41.IsSupported) { Vector128 q = Unsafe.As>(ref Unsafe.AsRef(this)); - Vector128 d = Unsafe.As>(ref quaternion2); + Vector128 d = Unsafe.As>(ref Unsafe.AsRef(quaternion2)); d = Sse.Add(q, d); Unsafe.As>(ref Unsafe.AsRef(this)) = d; } @@ -349,12 +349,12 @@ public void Add(Quaternion quaternion2) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Sub(Quaternion quaternion2) + public void Sub(in Quaternion quaternion2) { if (Sse41.IsSupported) { Vector128 q = Unsafe.As>(ref Unsafe.AsRef(this)); - Vector128 d = Unsafe.As>(ref quaternion2); + Vector128 d = Unsafe.As>(ref Unsafe.AsRef(quaternion2)); d = Sse.Subtract(q, d); Unsafe.As>(ref Unsafe.AsRef(this)) = d; } diff --git a/OpenMetaverseTypes/UUID.cs b/OpenMetaverseTypes/UUID.cs index b08d8c41..b75b83a1 100644 --- a/OpenMetaverseTypes/UUID.cs +++ b/OpenMetaverseTypes/UUID.cs @@ -881,6 +881,12 @@ public unsafe static bool TryParse(ReadOnlySpan sval, out UUID result) if (len < 36) return false; + while (--len > 35) + { + if (val[len] != ' ') + return false; + } + if (val[13] != '-' || val[18] != '-' || val[23] != '-') return false; @@ -1005,6 +1011,11 @@ public unsafe static bool TryParse(ReadOnlySpan sval, out UUID result) } else { + while (--len > 31) + { + if (val[len] != ' ') + return false; + } if (BitConverter.IsLittleEndian) { result.bytea3 = Utils.HexToByte(val, 0); From e0fd3e45fad75abdc8739978ea9f79f9e68742c9 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Thu, 26 Jan 2023 18:11:03 +0000 Subject: [PATCH 091/149] add missing file --- OpenMetaverse/DllmapConfigHelper.cs | 387 ++++++++++++++++++++++++++++ 1 file changed, 387 insertions(+) create mode 100644 OpenMetaverse/DllmapConfigHelper.cs diff --git a/OpenMetaverse/DllmapConfigHelper.cs b/OpenMetaverse/DllmapConfigHelper.cs new file mode 100644 index 00000000..6dd01f91 --- /dev/null +++ b/OpenMetaverse/DllmapConfigHelper.cs @@ -0,0 +1,387 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using System.IO; +using System.Reflection; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics.X86; +using System.Xml.Serialization; +using System.Xml; + +namespace OpenMetaverse +{ + public static class DllmapConfigHelper + { + [XmlRoot("dllmap")] + public class dllmap + { + [XmlAttribute("os")] + public string os; + [XmlAttribute("cpu")] + public string cpu; + [XmlAttribute("target")] + public string target; + [XmlAttribute("dll")] + public string dll; + } + + [XmlRoot("configuration")] + public class configuration + { + [XmlElement("dllmap")] + public List maps = new(); + } + + private static readonly Dictionary LoadedLibs = new(); + private static readonly HashSet RegisteredAssemblies = new(); + private static readonly object m_mainlock = new object(); + + public static void RegisterAssembly(Assembly assembly) + { + lock (m_mainlock) + { + if (RegisteredAssemblies.Contains(assembly)) + return; + RegisteredAssemblies.Add(assembly); + } + + string assemblyPath = Path.GetDirectoryName(assembly.Location); + string path = Path.Combine(assemblyPath, + Path.GetFileNameWithoutExtension(assembly.Location) + ".dll.config"); + configuration c = ParseConfig(path); + if (c is null) + return; + + int matchs = ProcessAssemblyConfiguration(c, out List<(string libname, string libpath)> libstoload); + if (matchs == 0) + return; + if (libstoload.Count == 0) + return; + + foreach (var (libname, libpath) in libstoload) + { + path= Path.Combine(assemblyPath, libpath); + if (NativeLibrary.TryLoad(path, out IntPtr ptr)) + LoadedLibs.Add(libname, ptr); + else + LoadedLibs.Add(libname, IntPtr.Zero); + } + NativeLibrary.SetDllImportResolver(assembly, AssemblyDllImport); + } + private static IntPtr AssemblyDllImport(string libraryName, Assembly assembly, DllImportSearchPath? dllImportSearchPath) + { + if (LoadedLibs.TryGetValue(libraryName, out IntPtr ptr)) + return ptr; + return IntPtr.Zero; + } + + public static configuration ParseConfig(string path) + { + if (string.IsNullOrWhiteSpace(path)) + return null; + + configuration c; + try + { + if (!File.Exists(path)) + return null; + using FileStream fs = new(path, FileMode.Open); + using XmlReader reader = XmlReader.Create(fs); + XmlSerializer serializer = new(typeof(configuration)); + c = (configuration)serializer.Deserialize(reader); + } + catch + { + return null; + } + if (c is null || c.maps is null || c.maps.Count == 0) + return null; + return c; + } + + public static int ProcessAssemblyConfiguration(configuration c, out List<(string libname, string libpath)> libsToLoad) + { + libsToLoad = new List<(string libname, string libpath)>(c.maps.Count); + int MatchCount = 0; + HashSet libsdone = new(); + foreach (dllmap m in c.maps) + { + if (string.IsNullOrEmpty(m.target)) + continue; + if (string.IsNullOrEmpty(m.os)) + continue; + if (string.IsNullOrEmpty(m.dll)) + continue; + if (libsdone.Contains(m.dll)) + continue; + + bool match = false; + bool negate = m.os[0] == '!'; + if (negate) + m.os = m.os[1..]; + string[] tos = m.os.Split(','); + foreach (string s in tos) + { + match = OperatingSystem.IsOSPlatform(s); + if (match) + break; + } + if (negate) + match = !match; + if (!match) + continue; + + if (string.IsNullOrEmpty(m.cpu)) + { + libsdone.Add(m.dll); + MatchCount++; + if (!LoadedLibs.ContainsKey(m.dll)) + libsToLoad.Add((m.dll, m.target)); + break; + } + + negate = m.cpu[0] == '!'; + if (negate) + m.cpu = m.cpu[1..]; + m.cpu = m.cpu.ToLower(); + string[] tcpu = m.cpu.Split(','); + match = false; + foreach (string s in tcpu) + { + switch (s) + { + case "x86": + if (RuntimeInformation.ProcessArchitecture == Architecture.X86) + match = true; + break; + case "x86avx": + if (Avx.IsSupported && RuntimeInformation.ProcessArchitecture == Architecture.X86) + match = true; + break; + case "x86-64": + if (RuntimeInformation.ProcessArchitecture == Architecture.X64) + match = true; + break; + case "x86-64avx": + if (Avx.IsSupported && RuntimeInformation.ProcessArchitecture == Architecture.X64) + match = true; + break; + case "arm": + case "aarch32": + if (RuntimeInformation.ProcessArchitecture == Architecture.Arm) + match = true; + break; + case "arm64": + case "armv8": + case "aarch64": + if (RuntimeInformation.ProcessArchitecture == Architecture.Arm64) + match = true; + break; + case "s390": + case "s390x": + if (RuntimeInformation.ProcessArchitecture == Architecture.S390x) + match = true; + break; + } + if (match) + break; + } + if(negate) + match = !match; + + if (match) + { + MatchCount++; + libsdone.Add(m.dll); + if (!LoadedLibs.ContainsKey(m.dll)) + libsToLoad.Add((m.dll, m.target)); + } + } + return MatchCount; + } + + public static void RegisterDll(Assembly assembly, string libname) + { + lock (m_mainlock) + { + if (RegisteredAssemblies.Contains(assembly)) + return; + RegisteredAssemblies.Add(assembly); + } + + if (!LoadedLibs.TryGetValue(libname, out IntPtr ptr)) + { + string assemblyPath = Path.GetDirectoryName(assembly.Location); + string path = Path.Combine(assemblyPath, libname + ".dllconfig"); + configuration c = ParseConfig(path); + if (c is null) + return; + + string libpath = ProcessDllConfiguration(c); + if (string.IsNullOrEmpty(libpath)) + { + LoadedLibs.Add(libname, IntPtr.Zero); + return; + } + + libpath = Path.Combine(assemblyPath, libpath); + if (!NativeLibrary.TryLoad(libpath, out ptr)) + { + LoadedLibs.Add(libname, IntPtr.Zero); + return; + } + + LoadedLibs.Add(libname, ptr); + } + if (ptr != IntPtr.Zero) + NativeLibrary.SetDllImportResolver(assembly, AssemblyDllImport); + } + + public static IntPtr LoadDll(string libname) + { + if (LoadedLibs.TryGetValue(libname, out IntPtr ptr)) + return ptr; + + string execpath = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location); + + string path = Path.Combine(execpath, libname + ".dllconfig"); + configuration c = ParseConfig(path); + if (c is null) + return IntPtr.Zero; + + string libpath = ProcessDllConfiguration(c); + if (string.IsNullOrEmpty(libpath)) + { + LoadedLibs.Add(libname, IntPtr.Zero); + return IntPtr.Zero; + } + + libpath = Path.Combine(execpath, libpath); + if (NativeLibrary.TryLoad(libpath, out ptr)) + { + LoadedLibs.Add(libname, ptr); + return ptr; + } + + LoadedLibs.Add(libname, IntPtr.Zero); + return IntPtr.Zero; + } + + public static string ProcessDllConfiguration(configuration c) + { + string newlibname = null; + foreach (dllmap m in c.maps) + { + if (string.IsNullOrEmpty(m.target)) + continue; + if (string.IsNullOrEmpty(m.os)) + continue; + + bool match = false; + bool negate = m.os[0] == '!'; + if (negate) + m.os = m.os[1..]; + string[] tos = m.os.Split(','); + foreach (string s in tos) + { + match = System.OperatingSystem.IsOSPlatform(s); + if (match) + { + match = !negate; + break; + } + } + if (!match) + continue; + + if (string.IsNullOrEmpty(m.cpu)) + { + newlibname = m.target; + break; + } + + negate = m.cpu[0] == '!'; + if (negate) + m.cpu = m.cpu[1..]; + m.cpu = m.cpu.ToLower(); + string[] tcpu = m.cpu.Split(','); + match = false; + foreach (string s in tcpu) + { + switch (s) + { + case "x86": + if (RuntimeInformation.ProcessArchitecture == Architecture.X86) + match = true; + break; + case "x86avx": + if (Avx.IsSupported && RuntimeInformation.ProcessArchitecture == Architecture.X86) + match = true; + break; + case "x86-64": + if (RuntimeInformation.ProcessArchitecture == Architecture.X64) + match = true; + break; + case "x86-64avx": + if (Avx.IsSupported && RuntimeInformation.ProcessArchitecture == Architecture.X64) + match = true; + break; + case "arm": + case "aarch32": + if (RuntimeInformation.ProcessArchitecture == Architecture.Arm) + match = true; + break; + case "arm64": + case "armv8": + case "aarch64": + if (RuntimeInformation.ProcessArchitecture == Architecture.Arm64) + match = true; + break; + case "s390": + case "s390x": + if (RuntimeInformation.ProcessArchitecture == Architecture.S390x) + match = true; + break; + } + if (match) + { + match = !negate; + break; + } + } + if (match) + { + newlibname = m.target; + break; + } + } + return newlibname; + } + } +} From 18f53dd62e83cb502d8eb2011203ed848cb4b782 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Wed, 15 Feb 2023 16:42:30 +0000 Subject: [PATCH 092/149] add vector3.Unit?Rotated(rot) ?=x,y,x --- OpenMetaverseTypes/Vector3.cs | 49 +++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/OpenMetaverseTypes/Vector3.cs b/OpenMetaverseTypes/Vector3.cs index cdd7b7eb..ae44e279 100644 --- a/OpenMetaverseTypes/Vector3.cs +++ b/OpenMetaverseTypes/Vector3.cs @@ -1085,6 +1085,55 @@ public static Vector3 InverseRotate(Vector3 vec, Quaternion rot) x2 * (xz2 + wy2) + y2 * (yz2 - wx2) + z2 * (1.0f - xx2 - yy2)); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector3 UnitXRotated(Quaternion rot) + { + float y2 = rot.Y + rot.Y; + float z2 = rot.Z + rot.Z; + + float wy2 = rot.W * y2; + float wz2 = rot.W * z2; + float xy2 = rot.X * y2; + float xz2 = rot.X * z2; + float yy2 = rot.Y * y2; + float zz2 = rot.Z * z2; + + return new Vector3(1.0f - yy2 - zz2, xy2 + wz2, xz2 - wy2); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector3 UnitYRotated(Quaternion rot) + { + float x2 = rot.X + rot.X; + float y2 = rot.Y + rot.Y; + float z2 = rot.Z + rot.Z; + + float wx2 = rot.W * x2; + float wz2 = rot.W * z2; + float xx2 = rot.X * x2; + float xy2 = rot.X * y2; + float yz2 = rot.Y * z2; + float zz2 = rot.Z * z2; + + return new Vector3(xy2 - wz2, 1.0f - xx2 - zz2, yz2 + wx2); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector3 UnitZRotated(Quaternion rot) + { + float x2 = rot.X + rot.X; + float y2 = rot.Y + rot.Y; + float z2 = rot.Z + rot.Z; + + float wx2 = rot.W * x2; + float wy2 = rot.W * y2; + float xx2 = rot.X * x2; + float xz2 = rot.X * z2; + float yy2 = rot.Y * y2; + float yz2 = rot.Y * z2; + + return new Vector3(xz2 + wy2, yz2 - wx2, 1.0f - xx2 - yy2); + } //quaternion must be normalized <0,0,z,w> [MethodImpl(MethodImplOptions.AggressiveInlining)] From b3e885d43bf7d125ea86b7a120f2ffa8c78c6ebc Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Mon, 13 Mar 2023 19:41:41 +0000 Subject: [PATCH 093/149] fix a array size check --- OpenMetaverseTypes/UtilsConversions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenMetaverseTypes/UtilsConversions.cs b/OpenMetaverseTypes/UtilsConversions.cs index f7012f6f..a1d1a595 100644 --- a/OpenMetaverseTypes/UtilsConversions.cs +++ b/OpenMetaverseTypes/UtilsConversions.cs @@ -1543,7 +1543,7 @@ public static string BytesToString(byte[] bytes) public static string BytesToString(byte[] bytes, int index, int count) { - if (bytes.Length <= index + count) + if (bytes.Length < index + count) return string.Empty; if (bytes[index + count - 1] == 0x00) return Encoding.UTF8.GetString(bytes, index, count - 1); From fe8fddfcf81bcce1dbad16df6a545a1a85c2e27d Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Mon, 13 Mar 2023 19:51:35 +0000 Subject: [PATCH 094/149] several changes... --- OpenMetaverse/Primitives/Primitive.cs | 104 +++++---- OpenMetaverseTypes/Quaternion.cs | 287 ++++++++++++------------- OpenMetaverseTypes/UtilsConversions.cs | 2 +- OpenMetaverseTypes/Vector2.cs | 117 +++++----- OpenMetaverseTypes/Vector3.cs | 189 ++++++++-------- OpenMetaverseTypes/Vector4.cs | 239 ++++++++++---------- 6 files changed, 447 insertions(+), 491 deletions(-) diff --git a/OpenMetaverse/Primitives/Primitive.cs b/OpenMetaverse/Primitives/Primitive.cs index 10f8cbf1..1ff62c40 100644 --- a/OpenMetaverse/Primitives/Primitive.cs +++ b/OpenMetaverse/Primitives/Primitive.cs @@ -34,11 +34,17 @@ public partial class Primitive : IEquatable { // Used for packing and unpacking parameters protected const float CUT_QUANTA = 0.00002f; + protected const float CUT_QUANTAINV = 1.0f / CUT_QUANTA; protected const float SCALE_QUANTA = 0.01f; + protected const float SCALE_QUANTAINV = 1-0f/ SCALE_QUANTA; protected const float SHEAR_QUANTA = 0.01f; + protected const float SHEAR_QUANTAINV = 1.0f / SHEAR_QUANTA; protected const float TAPER_QUANTA = 0.01f; + protected const float TAPER_QUANTAINV = 1.0f / TAPER_QUANTA; protected const float REV_QUANTA = 0.015f; + protected const float REV_QUANTAINV = 1.0f / REV_QUANTA; protected const float HOLLOW_QUANTA = 0.00002f; + protected const float HOLLOW_QUANTAINV = 1.0f / HOLLOW_QUANTA; #region Subclasses @@ -130,7 +136,7 @@ public Vector2 PathBeginScale { get { - Vector2 begin = new Vector2(1f, 1f); + Vector2 begin = new(1f, 1f); if (PathScaleX > 1f) begin.X = 2f - PathScaleX; if (PathScaleY > 1f) @@ -144,7 +150,7 @@ public Vector2 PathEndScale { get { - Vector2 end = new Vector2(1f, 1f); + Vector2 end = new(1f, 1f); if (PathScaleX < 1f) end.X = PathScaleX; if (PathScaleY < 1f) @@ -268,14 +274,15 @@ public byte[] GetBytes() /// public OSD GetOSD() { - OSDMap map = new OSDMap(); - - map["simulate_lod"] = OSD.FromInteger(Softness); - map["gravity"] = OSD.FromReal(Gravity); - map["air_friction"] = OSD.FromReal(Drag); - map["wind_sensitivity"] = OSD.FromReal(Wind); - map["tension"] = OSD.FromReal(Tension); - map["user_force"] = OSD.FromVector3(Force); + OSDMap map = new() + { + ["simulate_lod"] = OSD.FromInteger(Softness), + ["gravity"] = OSD.FromReal(Gravity), + ["air_friction"] = OSD.FromReal(Drag), + ["wind_sensitivity"] = OSD.FromReal(Wind), + ["tension"] = OSD.FromReal(Tension), + ["user_force"] = OSD.FromVector3(Force) + }; return map; } @@ -383,13 +390,14 @@ public byte[] GetBytes() public OSD GetOSD() { - OSDMap map = new OSDMap(); - - map["color"] = OSD.FromColor4(Color); - map["intensity"] = OSD.FromReal(Intensity); - map["radius"] = OSD.FromReal(Radius); - map["cutoff"] = OSD.FromReal(Cutoff); - map["falloff"] = OSD.FromReal(Falloff); + OSDMap map = new() + { + ["color"] = OSD.FromColor4(Color), + ["intensity"] = OSD.FromReal(Intensity), + ["radius"] = OSD.FromReal(Radius), + ["cutoff"] = OSD.FromReal(Cutoff), + ["falloff"] = OSD.FromReal(Falloff) + }; return map; } @@ -486,10 +494,11 @@ public byte[] GetBytes() public OSD GetOSD() { - OSDMap map = new OSDMap(); - - map["texture"] = OSD.FromUUID(LightTexture); - map["params"] = OSD.FromVector3(Params); + OSDMap map = new() + { + ["texture"] = OSD.FromUUID(LightTexture), + ["params"] = OSD.FromVector3(Params) + }; return map; } @@ -592,10 +601,11 @@ public byte[] GetBytes() public OSD GetOSD() { - OSDMap map = new OSDMap(); - - map["texture"] = OSD.FromUUID(SculptTexture); - map["type"] = OSD.FromInteger(type); + OSDMap map = new() + { + ["texture"] = OSD.FromUUID(SculptTexture), + ["type"] = OSD.FromInteger(type) + }; return map; } @@ -666,11 +676,12 @@ public byte[] GetBytes() public OSD GetOSD() { - OSDMap map = new OSDMap(); - - map["ambiance"] = OSD.FromReal(Ambiance); - map["clip_distance"] = OSD.FromReal(ClipDistance); - map["flags"] = OSD.FromInteger(Flags); + OSDMap map = new() + { + ["ambiance"] = OSD.FromReal(Ambiance), + ["clip_distance"] = OSD.FromReal(ClipDistance), + ["flags"] = OSD.FromInteger(Flags) + }; return map; } @@ -710,13 +721,28 @@ public override string ToString() /// public class RenderMaterials { - public struct RenderMaterialEntry + public struct RenderMaterialEntry : IComparable { public byte te_index; public UUID id; + public int CompareTo(RenderMaterialEntry other) + { + return te_index.CompareTo(other.te_index); + } + } + + public struct RenderMaterialOverrideEntry : IComparable + { + public byte te_index; + public string data; + public int CompareTo(RenderMaterialEntry other) + { + return te_index.CompareTo(other.te_index); + } } public RenderMaterialEntry[] entries = null; + public RenderMaterialOverrideEntry[] overrides = null; /// /// Default constructor @@ -1623,22 +1649,22 @@ public override int GetHashCode() public static ushort PackBeginCut(float beginCut) { - return (ushort)Math.Round(beginCut / CUT_QUANTA); + return (ushort)MathF.Round(beginCut * CUT_QUANTAINV); } public static ushort PackEndCut(float endCut) { - return (ushort)(50000 - (ushort)Math.Round(endCut / CUT_QUANTA)); + return (ushort)(50000 - (ushort)MathF.Round(endCut * CUT_QUANTAINV)); } public static byte PackPathScale(float pathScale) { - return (byte)(200 - (byte)Math.Round(pathScale / SCALE_QUANTA)); + return (byte)(200 - (byte)MathF.Round(pathScale * SCALE_QUANTAINV)); } public static sbyte PackPathShear(float pathShear) { - return (sbyte)Math.Round(pathShear / SHEAR_QUANTA); + return (sbyte)MathF.Round(pathShear * SHEAR_QUANTAINV); } /// @@ -1649,22 +1675,22 @@ public static sbyte PackPathShear(float pathShear) /// Signed eight bit value containing the packed parameter public static sbyte PackPathTwist(float pathTwist) { - return (sbyte)Math.Round(pathTwist / SCALE_QUANTA); + return (sbyte)MathF.Round(pathTwist * SCALE_QUANTAINV); } public static sbyte PackPathTaper(float pathTaper) { - return (sbyte)Math.Round(pathTaper / TAPER_QUANTA); + return (sbyte)MathF.Round(pathTaper * TAPER_QUANTAINV); } public static byte PackPathRevolutions(float pathRevolutions) { - return (byte)Math.Round((pathRevolutions - 1f) / REV_QUANTA); + return (byte)MathF.Round((pathRevolutions - 1f) * REV_QUANTAINV); } public static ushort PackProfileHollow(float profileHollow) { - return (ushort)Math.Round(profileHollow / HOLLOW_QUANTA); + return (ushort)MathF.Round(profileHollow * HOLLOW_QUANTAINV); } #endregion Parameter Packing Methods diff --git a/OpenMetaverseTypes/Quaternion.cs b/OpenMetaverseTypes/Quaternion.cs index 09ad80ba..dd54107f 100644 --- a/OpenMetaverseTypes/Quaternion.cs +++ b/OpenMetaverseTypes/Quaternion.cs @@ -1051,84 +1051,76 @@ public unsafe static Quaternion Parse(string val) return Parse(val.AsSpan()); } - public unsafe static Quaternion Parse(ReadOnlySpan sp) + public static Quaternion Parse(ReadOnlySpan sp) { if (sp.Length < 7) throw new FormatException("Invalid Quaternion"); int start = 0; - fixed (char* p = sp) + int comma = 0; + char c; + do { - while (start < sp.Length) - { - if (p[start++] == '<') - break; - } - if (start > sp.Length - 6) - throw new FormatException("Invalid Quaternion"); + c = Unsafe.Add(ref MemoryMarshal.GetReference(sp), comma); + if (c == ',' || c == '<') + break; + } + while (++comma < sp.Length); - int comma1 = start + 1; - while (comma1 < sp.Length) + if (c == '<') + { + start = ++comma; + while (++comma < sp.Length) { - if (p[comma1] == ',') + if (Unsafe.Add(ref MemoryMarshal.GetReference(sp), comma) == ',') break; - comma1++; } - if (comma1 > sp.Length - 5) - throw new FormatException("Invalid Quaternion"); - - if (!float.TryParse(sp[start..comma1], NumberStyles.Float, Utils.EnUsCulture, out float x)) - throw new FormatException("Invalid Quaternion"); + } + if (comma > sp.Length - 5) + throw new FormatException("Invalid Quaternion"); - comma1++; - start = comma1; - comma1++; - while (comma1 < sp.Length) - { - if (p[comma1] == ',') - break; - comma1++; - } - if (comma1 > sp.Length - 3) - throw new FormatException("Invalid Quaternion"); - if (!float.TryParse(sp[start..comma1], NumberStyles.Float, Utils.EnUsCulture, out float y)) - throw new FormatException("Invalid Quaternion"); - - comma1++; - start = comma1; - comma1++; - while (comma1 < sp.Length) - { - if (p[comma1] == '>' || p[comma1] == ',') - break; - comma1++; - } - if (comma1 >= sp.Length) - throw new FormatException("Invalid Quaternion"); + if (!float.TryParse(sp[start..comma], NumberStyles.Float, Utils.EnUsCulture, out float x)) + throw new FormatException("Invalid Quaternion"); - if (!float.TryParse(sp[start..comma1], NumberStyles.Float, Utils.EnUsCulture, out float z)) - throw new FormatException("Invalid Quaternion"); + start = ++comma; + while (++comma < sp.Length) + { + if (Unsafe.Add(ref MemoryMarshal.GetReference(sp), comma) == ',') + break; + } + if (comma > sp.Length - 3) + throw new FormatException("Invalid Quaternion"); + if (!float.TryParse(sp[start..comma], NumberStyles.Float, Utils.EnUsCulture, out float y)) + throw new FormatException("Invalid Quaternion"); - if (p[comma1] == '>') - return new Quaternion(x, y, z); + start = ++comma; + while (++comma < sp.Length) + { + c = Unsafe.Add(ref MemoryMarshal.GetReference(sp), comma); + if (c == ',' || c == '>') + break; + } + if (comma >= sp.Length) + throw new FormatException("Invalid Quaternion"); - comma1++; - start = comma1; - comma1++; - while (comma1 < sp.Length) - { - if (p[comma1] == '>') - break; - comma1++; - } - if (comma1 >= sp.Length) - throw new FormatException("Invalid Quaternion"); + if (!float.TryParse(sp[start..comma], NumberStyles.Float, Utils.EnUsCulture, out float z)) + throw new FormatException("Invalid Quaternion"); - if (!float.TryParse(sp[start..comma1], NumberStyles.Float, Utils.EnUsCulture, out float w)) - throw new FormatException("Invalid Quaternion"); + if (c == '>') + return new Quaternion(x, y, z); - return new Quaternion(x, y, z, w); + start = ++comma; + while (++comma < sp.Length) + { + c = Unsafe.Add(ref MemoryMarshal.GetReference(sp), comma); + if (c == ' ' || c == '>') + break; } + + if (!float.TryParse(sp[start..comma], NumberStyles.Float, Utils.EnUsCulture, out float w)) + throw new FormatException("Invalid Quaternion"); + + return new Quaternion(x, y, z, w); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -1137,7 +1129,7 @@ public unsafe static bool TryParse(string val, out Quaternion result) return TryParse(val.AsSpan(), out result); } - public unsafe static bool TryParse(ReadOnlySpan sp, out Quaternion result) + public static bool TryParse(ReadOnlySpan sp, out Quaternion result) { if (sp.Length < 7) { @@ -1146,109 +1138,96 @@ public unsafe static bool TryParse(ReadOnlySpan sp, out Quaternion result) } int start = 0; - fixed (char* p = sp) + int comma = 0; + char c; + + do { - while (start < sp.Length) - { - if (p[start++] == '<') - break; - } - if (start > sp.Length - 6) - { - result = Identity; - return false; - } + c = Unsafe.Add(ref MemoryMarshal.GetReference(sp), comma); + if (c == ',' || c == '<') + break; + } + while (++comma < sp.Length); - int comma1 = start + 1; - while (comma1 < sp.Length) + if (c == '<') + { + start = ++comma; + while (++comma < sp.Length) { - if (p[comma1] == ',') + if (Unsafe.Add(ref MemoryMarshal.GetReference(sp), comma) == ',') break; - comma1++; - } - if (comma1 > sp.Length - 5) - { - result = Identity; - return false; - } - - if (!float.TryParse(sp[start..comma1], NumberStyles.Float, Utils.EnUsCulture, out float x)) - { - result = Identity; - return false; } + } + if (comma > sp.Length - 5) + { + result = Identity; + return false; + } - comma1++; - start = comma1; - comma1++; - while (comma1 < sp.Length) - { - if (p[comma1] == ',') - break; - comma1++; - } - if (comma1 > sp.Length - 3) - { - result = Identity; - return false; - } - if (!float.TryParse(sp[start..comma1], NumberStyles.Float, Utils.EnUsCulture, out float y)) - { - result = Identity; - return false; - } + if (!float.TryParse(sp[start..comma], NumberStyles.Float, Utils.EnUsCulture, out float x)) + { + result = Identity; + return false; + } - comma1++; - start = comma1; - comma1++; - while (comma1 < sp.Length) - { - if (p[comma1] == '>' || p[comma1] == ',') - break; - comma1++; - } - if (comma1 >= sp.Length) - { - result = Identity; - return false; - } + start = ++comma; + while (++comma < sp.Length) + { + if (Unsafe.Add(ref MemoryMarshal.GetReference(sp), comma) == ',') + break; + } + if (comma > sp.Length - 3) + { + result = Identity; + return false; + } + if (!float.TryParse(sp[start..comma], NumberStyles.Float, Utils.EnUsCulture, out float y)) + { + result = Identity; + return false; + } - if (!float.TryParse(sp[start..comma1], NumberStyles.Float, Utils.EnUsCulture, out float z)) - { - result = Identity; - return false; - } + start = ++comma; + while (++comma < sp.Length) + { + c= Unsafe.Add(ref MemoryMarshal.GetReference(sp), comma); + if (c == '>' || c == ',') + break; + } + if (comma >= sp.Length) + { + result = Identity; + return false; + } - if (p[comma1] == '>') - { - result = new Quaternion(x, y, z); - return true; - } + if (!float.TryParse(sp[start..comma], NumberStyles.Float, Utils.EnUsCulture, out float z)) + { + result = Identity; + return false; + } - comma1++; - start = comma1; - comma1++; - while (comma1 < sp.Length) - { - if (p[comma1] == '>') - break; - comma1++; - } - if (comma1 >= sp.Length) - { - result = Identity; - return false; - } + if (c == '>') + { + result = new Quaternion(x, y, z); + return true; + } - if (!float.TryParse(sp[start..comma1], NumberStyles.Float, Utils.EnUsCulture, out float w)) - { - result = Identity; - return false; - } + comma++; + start = comma; + while (++comma < sp.Length) + { + if (Unsafe.Add(ref MemoryMarshal.GetReference(sp), comma) == '>') + break; + } - result = new Quaternion(x, y, z, w); - return true; + if (!float.TryParse(sp[start..comma], NumberStyles.Float, Utils.EnUsCulture, out float w)) + { + result = Identity; + return false; } + + result = new Quaternion(x, y, z, w); + return true; } #endregion Static Methods @@ -1257,9 +1236,9 @@ public unsafe static bool TryParse(ReadOnlySpan sp, out Quaternion result) public readonly override bool Equals(object obj) { - if((obj is not Quaternion)) + if(obj is not Quaternion other) return false; - Quaternion other = (Quaternion)obj; + if (X != other.X) return false; if (Y != other.Y) diff --git a/OpenMetaverseTypes/UtilsConversions.cs b/OpenMetaverseTypes/UtilsConversions.cs index 4a0be06d..565ba078 100644 --- a/OpenMetaverseTypes/UtilsConversions.cs +++ b/OpenMetaverseTypes/UtilsConversions.cs @@ -1524,7 +1524,7 @@ public static string BytesToString(byte[] bytes) public static string BytesToString(byte[] bytes, int index, int count) { - if (bytes.Length <= index + count) + if (bytes.Length < index + count) return string.Empty; if (bytes[index + count - 1] == 0x00) return Encoding.UTF8.GetString(bytes, index, count - 1); diff --git a/OpenMetaverseTypes/Vector2.cs b/OpenMetaverseTypes/Vector2.cs index b9d11f01..6a17d4a6 100644 --- a/OpenMetaverseTypes/Vector2.cs +++ b/OpenMetaverseTypes/Vector2.cs @@ -399,59 +399,56 @@ public static unsafe Vector2 Parse(string val) return Parse(val.AsSpan()); } - public static unsafe Vector2 Parse(ReadOnlySpan sp) + public static Vector2 Parse(ReadOnlySpan sp) { - if (sp.Length < 5) + if (sp.Length < 3) throw new FormatException("Invalid Vector2"); int start = 0; - fixed (char* p = sp) + int comma = 0; + char c; + + do { - while (start < sp.Length) - { - if (p[start++] == '<') - break; - } - if (start > sp.Length - 4) - throw new FormatException("Invalid Vector2"); + c = Unsafe.Add(ref MemoryMarshal.GetReference(sp), comma); + if (c == ',' || c == '<') + break; + } + while (++comma < sp.Length); - int comma1 = start + 1; - while (comma1 < sp.Length) + if (c == '<') + { + start = ++comma; + while (++comma < sp.Length) { - if (p[comma1] == ',') + if (Unsafe.Add(ref MemoryMarshal.GetReference(sp), comma) == ',') break; - comma1++; } - if (comma1 > sp.Length - 3) - throw new FormatException("Invalid Vector2"); + } + if (comma > sp.Length - 1) + throw new FormatException("Invalid Vector2"); if (!float.TryParse(sp[start..comma1], NumberStyles.Float, Utils.EnUsCulture, out float x)) throw new FormatException("Invalid Vector2"); - comma1++; - start = comma1; - comma1++; - while (comma1 < sp.Length) - { - if (p[comma1] == '>') - break; - comma1++; - } - if (comma1 > sp.Length) - throw new FormatException("Invalid Vector2"); - if (!float.TryParse(sp[start..comma1], NumberStyles.Float, Utils.EnUsCulture, out float y)) - throw new FormatException("Invalid Vector2"); - - return new Vector2(x, y); + start = ++comma; + while (++comma < sp.Length) + { + if (Unsafe.Add(ref MemoryMarshal.GetReference(sp), comma) == '>') + break; } + if (!float.TryParse(sp[start..comma], NumberStyles.Float, Utils.EnUsCulture, out float y)) + throw new FormatException("Invalid Vector2"); + + return new Vector2(x, y); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public unsafe static bool TryParse(string val, out Vector2 result) + public static bool TryParse(string val, out Vector2 result) { return TryParse(val.AsSpan(), out result); } - public unsafe static bool TryParse(ReadOnlySpan sp, out Vector2 result) + public static bool TryParse(ReadOnlySpan sp, out Vector2 result) { if (sp.Length < 5) { @@ -460,37 +457,36 @@ public unsafe static bool TryParse(ReadOnlySpan sp, out Vector2 result) } int start = 0; - fixed (char* p = sp) + int comma = 0; + char c; + do { - while (start < sp.Length) - { - if (p[start++] == '<') - break; - } - if (start > sp.Length - 4) - { - result = Zero; - return false; - } + c = Unsafe.Add(ref MemoryMarshal.GetReference(sp), comma); + if (c == ',' || c == '<') + break; + } + while (++comma < sp.Length); - int comma1 = start + 1; - while (comma1 < sp.Length) + if (c == '<') + { + start = ++comma; + while (++comma < sp.Length) { - if (p[comma1] == ',') + if (Unsafe.Add(ref MemoryMarshal.GetReference(sp), comma) == ',') break; - comma1++; - } - if (comma1 > sp.Length - 3) - { - result = Zero; - return false; } + } + if (comma > sp.Length - 1) + { + result = Zero; + return false; + } - if (!float.TryParse(sp[start..comma1], NumberStyles.Float, Utils.EnUsCulture, out float x)) - { - result = Zero; - return false; - } + if (!float.TryParse(sp[start..comma], NumberStyles.Float, Utils.EnUsCulture, out float x)) + { + result = Zero; + return false; + } comma1++; start = comma1; @@ -512,9 +508,8 @@ public unsafe static bool TryParse(ReadOnlySpan sp, out Vector2 result) return false; } - result = new Vector2(x, y); - return true; - } + result = new Vector2(x, y); + return true; } /// /// Interpolates between two vectors using a cubic equation diff --git a/OpenMetaverseTypes/Vector3.cs b/OpenMetaverseTypes/Vector3.cs index ae44e279..0970e609 100644 --- a/OpenMetaverseTypes/Vector3.cs +++ b/OpenMetaverseTypes/Vector3.cs @@ -761,74 +761,71 @@ public static unsafe Vector3 Parse(string val) return Parse(val.AsSpan()); } - public static unsafe Vector3 Parse(ReadOnlySpan sp) + public static Vector3 Parse(ReadOnlySpan sp) { - if (sp.Length < 7) + if (sp.Length < 5) throw new FormatException("Invalid Vector3"); int start = 0; - fixed (char* p = sp) + int comma = 0; + char c; + + do { - while (start < sp.Length) - { - if (p[start++] == '<') - break; - } - if (start > sp.Length - 6) - throw new FormatException("Invalid Vector3"); + c = Unsafe.Add(ref MemoryMarshal.GetReference(sp), comma); + if (c == ',' || c == '<') + break; + } + while (++comma < sp.Length); - int comma1 = start + 1; - while (comma1 < sp.Length) + if (c == '<') + { + start = ++comma; + while (++comma < sp.Length) { - if (p[comma1] == ',') + if (Unsafe.Add(ref MemoryMarshal.GetReference(sp), comma) == ',') break; - comma1++; } - if (comma1 > sp.Length - 5) - throw new FormatException("Invalid Vector3"); + } - if (!float.TryParse(sp[start..comma1], NumberStyles.Float, Utils.EnUsCulture, out float x)) - throw new FormatException("Invalid Vector3"); + if (comma > sp.Length - 3) + throw new FormatException("Invalid Vector3"); - comma1++; - start = comma1; - comma1++; - while (comma1 < sp.Length) - { - if (p[comma1] == ',') - break; - comma1++; - } - if (comma1 > sp.Length - 3) - throw new FormatException("Invalid Vector3"); - if (!float.TryParse(sp[start..comma1], NumberStyles.Float, Utils.EnUsCulture, out float y)) - throw new FormatException("Invalid Vector3"); - - comma1++; - start = comma1; - comma1++; - while (comma1 < sp.Length) - { - if (p[comma1] == '>') - break; - comma1++; - } - if (comma1 >= sp.Length) - throw new FormatException("Invalid Vector3"); + if (!float.TryParse(sp[start..comma], NumberStyles.Float, Utils.EnUsCulture, out float x)) + throw new FormatException("Invalid Vector3"); + + start = ++comma; + while (++comma < sp.Length) + { + if (Unsafe.Add(ref MemoryMarshal.GetReference(sp), comma) == ',') + break; + } + if (comma > sp.Length - 1) + throw new FormatException("Invalid Vector3"); + + if (!float.TryParse(sp[start..comma], NumberStyles.Float, Utils.EnUsCulture, out float y)) + throw new FormatException("Invalid Vector3"); - if (!float.TryParse(sp[start..comma1], NumberStyles.Float, Utils.EnUsCulture, out float z)) - throw new FormatException("Invalid Vector3"); - return new Vector3(x, y, z); + start = ++comma; + while (++comma < sp.Length) + { + c = Unsafe.Add(ref MemoryMarshal.GetReference(sp), comma); + if (c == ' ' || c == '>') + break; } + + if (!float.TryParse(sp[start..comma], NumberStyles.Float, Utils.EnUsCulture, out float z)) + throw new FormatException("Invalid Vector3"); + return new Vector3(x, y, z); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public unsafe static bool TryParse(string val, out Vector3 result) + public static bool TryParse(string val, out Vector3 result) { return TryParse(val.AsSpan(), out result); } - public unsafe static bool TryParse(ReadOnlySpan sp, out Vector3 result) + public static bool TryParse(ReadOnlySpan sp, out Vector3 result) { if (sp.Length < 7) { @@ -837,11 +834,22 @@ public unsafe static bool TryParse(ReadOnlySpan sp, out Vector3 result) } int start = 0; - fixed (char* p = sp) + int comma = 0; + char c; + do { - while (start < sp.Length) + c = Unsafe.Add(ref MemoryMarshal.GetReference(sp), comma); + if (c == ',' || c == '<') + break; + } + while (++comma < sp.Length); + + if (c == '<') + { + start = ++comma; + while (++comma < sp.Length) { - if (p[start++] == '<') + if (Unsafe.Add(ref MemoryMarshal.GetReference(sp), comma) == ',') break; } if (start > sp.Length - 6) @@ -850,18 +858,11 @@ public unsafe static bool TryParse(ReadOnlySpan sp, out Vector3 result) return false; } - int comma1 = start + 1; - while (comma1 < sp.Length) - { - if (p[comma1] == ',') - break; - comma1++; - } - if (comma1 > sp.Length - 5) - { - result = Zero; - return false; - } + if (!float.TryParse(sp[start..comma], NumberStyles.Float, Utils.EnUsCulture, out float x)) + { + result = Zero; + return false; + } if (!float.TryParse(sp[start..comma1], NumberStyles.Float, Utils.EnUsCulture, out float x)) { @@ -869,49 +870,28 @@ public unsafe static bool TryParse(ReadOnlySpan sp, out Vector3 result) return false; } - comma1++; - start = comma1; - comma1++; - while (comma1 < sp.Length) - { - if (p[comma1] == ',') - break; - comma1++; - } - if (comma1 > sp.Length - 3) - { - result = Zero; - return false; - } - if (!float.TryParse(sp[start..comma1], NumberStyles.Float, Utils.EnUsCulture, out float y)) - { - result = Zero; - return false; - } + if (!float.TryParse(sp[start..comma], NumberStyles.Float, Utils.EnUsCulture, out float y)) + { + result = Zero; + return false; + } - comma1++; - start = comma1; - comma1++; - while (comma1 < sp.Length) - { - if (p[comma1] == '>') - break; - comma1++; - } - if (comma1 >= sp.Length) - { - result = Zero; - return false; - } + start = ++comma; + while (++comma < sp.Length) + { + c = Unsafe.Add(ref MemoryMarshal.GetReference(sp), comma); + if (c == ' ' || c == '>') + break; + } - if (!float.TryParse(sp[start..comma1], NumberStyles.Float, Utils.EnUsCulture, out float z)) - { - result = Zero; - return false; - } - result = new Vector3(x, y, z); - return true; + if (!float.TryParse(sp[start..comma], NumberStyles.Float, Utils.EnUsCulture, out float z)) + { + result = Zero; + return false; } + + result = new Vector3(x, y, z); + return true; } /// @@ -1196,10 +1176,9 @@ public static Vector3 InverseRotateByShortQZ(Vector3 vec, Vector2 shortQuaternio public readonly override bool Equals(object obj) { - if (obj is not Vector3) + if (obj is not Vector3 other) return false; - Vector3 other = (Vector3)obj; if (X != other.X) return false; if (Y != other.Y) diff --git a/OpenMetaverseTypes/Vector4.cs b/OpenMetaverseTypes/Vector4.cs index e40e050b..8b0ef883 100644 --- a/OpenMetaverseTypes/Vector4.cs +++ b/OpenMetaverseTypes/Vector4.cs @@ -519,126 +519,116 @@ public unsafe static Vector4 Parse(string val) return Parse(val.AsSpan()); } - public static unsafe Vector4 Parse(ReadOnlySpan sp) + public static Vector4 Parse(ReadOnlySpan sp) { - if (sp.Length < 9) + if (sp.Length < 7) throw new FormatException("Invalid Vector4"); int start = 0; - fixed (char* p = sp) + int comma = 0; + char c; + + do { - while (start < sp.Length) - { - if (p[start++] == '<') - break; - } - if (start > sp.Length - 8) - throw new FormatException("Invalid Vector4"); + c = Unsafe.Add(ref MemoryMarshal.GetReference(sp), comma); + if (c == ',' || c == '<') + break; + } + while (++comma < sp.Length); - int comma1 = start + 1; - while (comma1 < sp.Length) + if (c == '<') + { + start = ++comma; + while (++comma < sp.Length) { - if (p[comma1] == ',') + if (Unsafe.Add(ref MemoryMarshal.GetReference(sp), comma) == ',') break; - comma1++; } - if (comma1 > sp.Length - 7) - throw new FormatException("Invalid Vector4"); - - if (!float.TryParse(sp[start..comma1], NumberStyles.Float, Utils.EnUsCulture, out float x)) - throw new FormatException("Invalid Vector4"); + } + if (comma > sp.Length - 5) + throw new FormatException("Invalid Vector4"); - comma1++; - start = comma1; - comma1++; - while (comma1 < sp.Length) - { - if (p[comma1] == ',') - break; - comma1++; - } - if (comma1 > sp.Length - 5) - throw new FormatException("Invalid Vector4"); - if (!float.TryParse(sp[start..comma1], NumberStyles.Float, Utils.EnUsCulture, out float y)) - throw new FormatException("Invalid Vector4"); + if (!float.TryParse(sp[start..comma], NumberStyles.Float, Utils.EnUsCulture, out float x)) + throw new FormatException("Invalid Vector4"); - comma1++; - start = comma1; - comma1++; - while (comma1 < sp.Length) - { - if (p[comma1] == ',') - break; - comma1++; - } - if (comma1 > sp.Length - 3) - throw new FormatException("Invalid Vector4"); - if (!float.TryParse(sp[start..comma1], NumberStyles.Float, Utils.EnUsCulture, out float z)) - throw new FormatException("Invalid Vector4"); + start = ++comma; + while (++comma < sp.Length) + { + if (Unsafe.Add(ref MemoryMarshal.GetReference(sp), comma) == ',') + break; + } + if (comma > sp.Length - 3) + throw new FormatException("Invalid Vector4"); + if (!float.TryParse(sp[start..comma], NumberStyles.Float, Utils.EnUsCulture, out float y)) + throw new FormatException("Invalid Vector4"); - comma1++; - start = comma1; - comma1++; - while (comma1 < sp.Length) - { - if (p[comma1] == '>') - break; - comma1++; - } - if (comma1 >= sp.Length) - throw new FormatException("Invalid Vector4"); + start = ++comma; + while (++comma < sp.Length) + { + if (Unsafe.Add(ref MemoryMarshal.GetReference(sp), comma) == ',') + break; + } + if (comma > sp.Length - 1) + throw new FormatException("Invalid Vector4"); + if (!float.TryParse(sp[start..comma], NumberStyles.Float, Utils.EnUsCulture, out float z)) + throw new FormatException("Invalid Vector4"); - if (!float.TryParse(sp[start..comma1], NumberStyles.Float, Utils.EnUsCulture, out float w)) - throw new FormatException("Invalid Vector4"); - return new Vector4(x, y, z, w); + start = ++comma; + while (++comma < sp.Length) + { + if (Unsafe.Add(ref MemoryMarshal.GetReference(sp), comma) == '>') + break; } + + if (!float.TryParse(sp[start..comma], NumberStyles.Float, Utils.EnUsCulture, out float w)) + throw new FormatException("Invalid Vector4"); + return new Vector4(x, y, z, w); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public unsafe static bool TryParse(string val, out Vector4 result) + public static bool TryParse(string val, out Vector4 result) { return TryParse(val.AsSpan(), out result); } - public unsafe static bool TryParse(ReadOnlySpan sp, out Vector4 result) + public static bool TryParse(ReadOnlySpan sp, out Vector4 result) { - if (sp.Length < 9) + if (sp.Length < 7) { result = Zero; return false; } int start = 0; - fixed (char* p = sp) + int comma = 0; + char c; + do { - while (start < sp.Length) - { - if (p[start++] == '<') - break; - } - if (start > sp.Length - 8) - { - result = Zero; - return false; - } + c = Unsafe.Add(ref MemoryMarshal.GetReference(sp), comma); + if (c == ',' || c == '<') + break; + } + while (++comma < sp.Length); - int comma1 = start + 1; - while (comma1 < sp.Length) + if (c == '<') + { + start = ++comma; + while (++comma < sp.Length) { - if (p[comma1] == ',') + if (Unsafe.Add(ref MemoryMarshal.GetReference(sp), comma) == ',') break; - comma1++; - } - if (comma1 > sp.Length - 7) - { - result = Zero; - return false; } + } + if (comma > sp.Length - 5) + { + result = Zero; + return false; + } - if (!float.TryParse(sp[start..comma1], NumberStyles.Float, Utils.EnUsCulture, out float x)) - { - result = Zero; - return false; - } + if (!float.TryParse(sp[start..comma], NumberStyles.Float, Utils.EnUsCulture, out float x)) + { + result = Zero; + return false; + } comma1++; start = comma1; @@ -660,49 +650,37 @@ public unsafe static bool TryParse(ReadOnlySpan sp, out Vector4 result) return false; } - comma1++; - start = comma1; - comma1++; - while (comma1 < sp.Length) - { - if (p[comma1] == ',') - break; - comma1++; - } - if (comma1 > sp.Length - 3) - { - result = Zero; - return false; - } - if (!float.TryParse(sp[start..comma1], NumberStyles.Float, Utils.EnUsCulture, out float z)) - { - result = Zero; - return false; - } - - comma1++; - start = comma1; - comma1++; - while (comma1 < sp.Length) - { - if (p[comma1] == '>') - break; - comma1++; - } - if (comma1 >= sp.Length) - { - result = Zero; - return false; - } + start = ++comma; + while (++comma < sp.Length) + { + if (Unsafe.Add(ref MemoryMarshal.GetReference(sp), comma) == ',') + break; + } + if (comma > sp.Length - 1) + { + result = Zero; + return false; + } + if (!float.TryParse(sp[start..comma], NumberStyles.Float, Utils.EnUsCulture, out float z)) + { + result = Zero; + return false; + } - if (!float.TryParse(sp[start..comma1], NumberStyles.Float, Utils.EnUsCulture, out float w)) - { - result = Zero; - return false; - } - result = new Vector4(x, y, z, w); - return true; + start = ++comma; + while (++comma < sp.Length) + { + if (Unsafe.Add(ref MemoryMarshal.GetReference(sp), comma) == '>') + break; + } + if (!float.TryParse(sp[start..comma], NumberStyles.Float, Utils.EnUsCulture, out float w)) + { + result = Zero; + return false; } + + result = new Vector4(x, y, z, w); + return true; } #endregion Static Methods @@ -711,10 +689,9 @@ public unsafe static bool TryParse(ReadOnlySpan sp, out Vector4 result) public override bool Equals(object obj) { - if (!(obj is Vector4)) + if (obj is not Vector4 other) return false; - Vector4 other = (Vector4)obj; if (X != other.X) return false; if (Y != other.Y) @@ -779,7 +756,7 @@ public override string ToString() /// Raw string representation of the vector public string ToRawString() { - CultureInfo enUs = new CultureInfo("en-us"); + CultureInfo enUs = new("en-us"); enUs.NumberFormat.NumberDecimalDigits = 3; StringBuilder sb = new(); From 39cd5eea02e579606bb608ca61c8f239577d86ab Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Tue, 14 Mar 2023 11:20:05 +0000 Subject: [PATCH 095/149] fix merge issues --- OpenMetaverseTypes/Quaternion.cs | 5 ++- OpenMetaverseTypes/Vector2.cs | 75 +++++++++++++++----------------- OpenMetaverseTypes/Vector3.cs | 17 +++++--- OpenMetaverseTypes/Vector4.cs | 38 ++++++++-------- 4 files changed, 67 insertions(+), 68 deletions(-) diff --git a/OpenMetaverseTypes/Quaternion.cs b/OpenMetaverseTypes/Quaternion.cs index dd54107f..85817fed 100644 --- a/OpenMetaverseTypes/Quaternion.cs +++ b/OpenMetaverseTypes/Quaternion.cs @@ -1190,7 +1190,7 @@ public static bool TryParse(ReadOnlySpan sp, out Quaternion result) start = ++comma; while (++comma < sp.Length) { - c= Unsafe.Add(ref MemoryMarshal.GetReference(sp), comma); + c = Unsafe.Add(ref MemoryMarshal.GetReference(sp), comma); if (c == '>' || c == ',') break; } @@ -1216,7 +1216,8 @@ public static bool TryParse(ReadOnlySpan sp, out Quaternion result) start = comma; while (++comma < sp.Length) { - if (Unsafe.Add(ref MemoryMarshal.GetReference(sp), comma) == '>') + c = Unsafe.Add(ref MemoryMarshal.GetReference(sp), comma); + if (c == ' ' || c == '>') break; } diff --git a/OpenMetaverseTypes/Vector2.cs b/OpenMetaverseTypes/Vector2.cs index 6a17d4a6..c92f0cdc 100644 --- a/OpenMetaverseTypes/Vector2.cs +++ b/OpenMetaverseTypes/Vector2.cs @@ -194,7 +194,7 @@ public float Dot(Vector3 value2) /// /// Byte array containing two four-byte floats /// Beginning position in the byte array - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void FromBytes(byte[] byteArray, int pos) { X = Utils.BytesToFloatSafepos(byteArray, pos); @@ -205,7 +205,7 @@ public void FromBytes(byte[] byteArray, int pos) /// Returns the raw bytes for this vector /// /// An eight-byte array containing X and Y - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public byte[] GetBytes() { byte[] dest = new byte[8]; @@ -220,7 +220,7 @@ public byte[] GetBytes() /// Destination byte array /// Position in the destination array to start /// writing. Must be at least 8 bytes before the end of the array - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe void ToBytes(byte[] dest, int pos) { if (Utils.CanDirectCopyLE) @@ -247,19 +247,19 @@ public unsafe void ToBytes(byte* dest) } } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public float Length() { return MathF.Sqrt(X * X + Y * Y); } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public float LengthSquared() { return X * X + Y * Y; } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Normalize() { float factor = LengthSquared(); @@ -280,7 +280,7 @@ public void Normalize() #region Static Methods - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 Add(Vector2 value1, Vector2 value2) { return new Vector2(value1.X + value2.X, value1.Y + value2.Y); @@ -294,7 +294,7 @@ public static Vector2 Clamp(Vector3 value1, float min, float max) Utils.Clamp(value1.Y, min, max)); } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 Clamp(Vector2 value1, Vector2 min, Vector2 max) { return new Vector2( @@ -302,13 +302,13 @@ public static Vector2 Clamp(Vector2 value1, Vector2 min, Vector2 max) Utils.Clamp(value1.Y, min.Y, max.Y)); } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static float Distance(Vector2 value1, Vector2 value2) { return MathF.Sqrt(DistanceSquared(value1, value2)); } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static float DistanceSquared(Vector2 value1, Vector2 value2) { return @@ -316,20 +316,20 @@ public static float DistanceSquared(Vector2 value1, Vector2 value2) (value1.Y - value2.Y) * (value1.Y - value2.Y); } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 Divide(Vector2 value1, Vector2 value2) { return new Vector2(value1.X / value2.X, value1.Y / value2.Y); } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 Divide(Vector2 value1, float divider) { float factor = 1 / divider; return new Vector2(value1.X * factor, value1.Y * factor); } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static float Dot(Vector2 value1, Vector2 value2) { return (value1.X * value2.X) + (value1.Y * value2.Y); @@ -342,7 +342,7 @@ public static Vector2 Lerp(Vector2 value1, Vector2 value2, float amount) Utils.Lerp(value1.Y, value2.Y, amount)); } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 Max(Vector2 value1, Vector2 value2) { return new Vector2( @@ -350,7 +350,7 @@ public static Vector2 Max(Vector2 value1, Vector2 value2) MathF.Max(value1.Y, value2.Y)); } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 Min(Vector2 value1, Vector2 value2) { return new Vector2( @@ -358,19 +358,19 @@ public static Vector2 Min(Vector2 value1, Vector2 value2) MathF.Min(value1.Y, value2.Y)); } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 Multiply(Vector2 value1, Vector2 value2) { return new Vector2(value1.X * value2.X, value1.Y * value2.Y); } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 Multiply(Vector2 value1, float scaleFactor) { return new Vector2(value1.X * scaleFactor, value1.Y * scaleFactor); } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 Negate(Vector2 value) { return new Vector2(-value.X, -value.Y); @@ -428,8 +428,8 @@ public static Vector2 Parse(ReadOnlySpan sp) if (comma > sp.Length - 1) throw new FormatException("Invalid Vector2"); - if (!float.TryParse(sp[start..comma1], NumberStyles.Float, Utils.EnUsCulture, out float x)) - throw new FormatException("Invalid Vector2"); + if (!float.TryParse(sp[start..comma], NumberStyles.Float, Utils.EnUsCulture, out float x)) + throw new FormatException("Invalid Vector2"); start = ++comma; while (++comma < sp.Length) @@ -450,7 +450,7 @@ public static bool TryParse(string val, out Vector2 result) } public static bool TryParse(ReadOnlySpan sp, out Vector2 result) { - if (sp.Length < 5) + if (sp.Length < 3) { result = Zero; return false; @@ -488,25 +488,18 @@ public static bool TryParse(ReadOnlySpan sp, out Vector2 result) return false; } - comma1++; - start = comma1; - comma1++; - while (comma1 < sp.Length) - { - if (p[comma1] == '>') - break; - comma1++; - } - if (comma1 > sp.Length) - { - result = Zero; - return false; - } - if (!float.TryParse(sp[start..comma1], NumberStyles.Float, Utils.EnUsCulture, out float y)) - { - result = Zero; - return false; - } + start = ++comma; + while (++comma < sp.Length) + { + c = Unsafe.Add(ref MemoryMarshal.GetReference(sp), comma); + if (c == ' ' || c == '>') + break; + } + if (!float.TryParse(sp[start..comma], NumberStyles.Float, Utils.EnUsCulture, out float y)) + { + result = Zero; + return false; + } result = new Vector2(x, y); return true; @@ -521,7 +514,7 @@ public static Vector2 SmoothStep(Vector2 value1, Vector2 value2, float amount) Utils.SmoothStep(value1.Y, value2.Y, amount)); } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 Subtract(Vector2 value1, Vector2 value2) { return new Vector2(value1.X - value2.X, value1.Y - value2.Y); diff --git a/OpenMetaverseTypes/Vector3.cs b/OpenMetaverseTypes/Vector3.cs index 0970e609..9a82a151 100644 --- a/OpenMetaverseTypes/Vector3.cs +++ b/OpenMetaverseTypes/Vector3.cs @@ -857,6 +857,7 @@ public static bool TryParse(ReadOnlySpan sp, out Vector3 result) result = Zero; return false; } + } if (!float.TryParse(sp[start..comma], NumberStyles.Float, Utils.EnUsCulture, out float x)) { @@ -864,11 +865,17 @@ public static bool TryParse(ReadOnlySpan sp, out Vector3 result) return false; } - if (!float.TryParse(sp[start..comma1], NumberStyles.Float, Utils.EnUsCulture, out float x)) - { - result = Zero; - return false; - } + start = ++comma; + while (++comma < sp.Length) + { + if (Unsafe.Add(ref MemoryMarshal.GetReference(sp), comma) == ',') + break; + } + if (comma > sp.Length - 3) + { + result = Zero; + return false; + } if (!float.TryParse(sp[start..comma], NumberStyles.Float, Utils.EnUsCulture, out float y)) { diff --git a/OpenMetaverseTypes/Vector4.cs b/OpenMetaverseTypes/Vector4.cs index 8b0ef883..68b415bf 100644 --- a/OpenMetaverseTypes/Vector4.cs +++ b/OpenMetaverseTypes/Vector4.cs @@ -630,25 +630,22 @@ public static bool TryParse(ReadOnlySpan sp, out Vector4 result) return false; } - comma1++; - start = comma1; - comma1++; - while (comma1 < sp.Length) - { - if (p[comma1] == ',') - break; - comma1++; - } - if (comma1 > sp.Length - 5) - { - result = Zero; - return false; - } - if (!float.TryParse(sp[start..comma1], NumberStyles.Float, Utils.EnUsCulture, out float y)) - { - result = Zero; - return false; - } + start = ++comma; + while (++comma < sp.Length) + { + if (Unsafe.Add(ref MemoryMarshal.GetReference(sp), comma) == ',') + break; + } + if (comma > sp.Length - 5) + { + result = Zero; + return false; + } + if (!float.TryParse(sp[start..comma], NumberStyles.Float, Utils.EnUsCulture, out float y)) + { + result = Zero; + return false; + } start = ++comma; while (++comma < sp.Length) @@ -670,7 +667,8 @@ public static bool TryParse(ReadOnlySpan sp, out Vector4 result) start = ++comma; while (++comma < sp.Length) { - if (Unsafe.Add(ref MemoryMarshal.GetReference(sp), comma) == '>') + c = Unsafe.Add(ref MemoryMarshal.GetReference(sp), comma); + if(c == ' ' || c == '>') break; } if (!float.TryParse(sp[start..comma], NumberStyles.Float, Utils.EnUsCulture, out float w)) From 8d58e02e47527080b2334a2cf766c7ac133bb757 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Sun, 18 Jun 2023 00:46:04 +0100 Subject: [PATCH 096/149] some more cosmetic changes on structured data --- .../StructuredData.cs | 353 ++++++++++-------- OpenMetaverse/Primitives/Primitive.cs | 10 +- 2 files changed, 208 insertions(+), 155 deletions(-) diff --git a/OpenMetaverse.StructuredData/StructuredData.cs b/OpenMetaverse.StructuredData/StructuredData.cs index 4c414d00..2e30aafb 100644 --- a/OpenMetaverse.StructuredData/StructuredData.cs +++ b/OpenMetaverse.StructuredData/StructuredData.cs @@ -30,6 +30,7 @@ using System.IO; using System.Reflection; using System.Text; +using System.Runtime.CompilerServices; namespace OpenMetaverse.StructuredData { @@ -102,14 +103,13 @@ public virtual bool AsBoolean() double d = ((OSDReal)this).value; return (!Double.IsNaN(d) && d != 0); case OSDType.String: - string s = ((OSDString)this).value; - if (String.IsNullOrEmpty(s)) - return false; - if (s == "0" || s.ToLower() == "false") + if (string.IsNullOrEmpty(((OSDString)this).value) || + ((OSDString)this).value.Equals("0") || + ((OSDString)this).value.Equals("false", StringComparison.InvariantCultureIgnoreCase)) return false; return true; case OSDType.UUID: - return (((OSDUUID)this).value.IsZero()) ? false : true; + return ((OSDUUID)this).value.IsNotZero(); case OSDType.Map: return ((OSDMap)this).dicvalue.Count > 0; case OSDType.Array: @@ -145,8 +145,7 @@ public virtual int AsInteger() return Int32.MinValue; return (int)Math.Round(v); case OSDType.String: - var s = ((OSDString)this).value.AsSpan(); - if (Double.TryParse(s, out double dbl)) + if (Double.TryParse(((OSDString)this).value.AsSpan(), out double dbl)) return (int)Math.Floor(dbl); else return 0; @@ -196,14 +195,12 @@ public virtual uint AsUInteger() return UInt32.MinValue; return (uint)Math.Round(v); case OSDType.String: - var s = ((OSDString)this).value.AsSpan(); - if (Double.TryParse(s, out double dbl)) + if (Double.TryParse(((OSDString)this).value.AsSpan(), out double dbl)) return (uint)Math.Floor(dbl); else return 0; case OSDType.OSDUTF8: - var us = ((OSDUTF8)this).value.ToString().AsSpan(); - if (Double.TryParse(us, out double udbl)) + if (Double.TryParse(((OSDUTF8)this).value.ToString().AsSpan(), out double udbl)) return (uint)Math.Floor(udbl); else return 0; @@ -247,8 +244,7 @@ public virtual long AsLong() return Int64.MinValue; return (long)Math.Round(v); case OSDType.String: - var s = ((OSDString)this).value.AsSpan(); - if (Double.TryParse(s, out double dbl)) + if (Double.TryParse(((OSDString)this).value, out double dbl)) return (long)Math.Floor(dbl); else return 0; @@ -313,14 +309,12 @@ public virtual ulong AsULong() return UInt64.MinValue; return (ulong)Math.Round(v); case OSDType.String: - var s = ((OSDString)this).value.AsSpan(); - if (Double.TryParse(s, out double dbl)) + if (Double.TryParse(((OSDString)this).value.AsSpan(), out double dbl)) return (ulong)Math.Floor(dbl); else return 0; case OSDType.OSDUTF8: - var us = ((OSDUTF8)this).value.ToString().AsSpan(); - if (Double.TryParse(us, out double udbl)) + if (Double.TryParse(((OSDUTF8)this).value.ToString().AsSpan(), out double udbl)) return (ulong)Math.Floor(udbl); else return 0; @@ -372,14 +366,12 @@ public virtual double AsReal() case OSDType.Real: return ((OSDReal)this).value; case OSDType.String: - var s = ((OSDString)this).value.AsSpan(); - if (Double.TryParse(s, out double dbl)) + if (Double.TryParse(((OSDString)this).value.AsSpan(), out double dbl)) return dbl; else return 0; case OSDType.OSDUTF8: - var us = ((OSDUTF8)this).value.ToString().AsSpan(); - if (Double.TryParse(us, out double udbl)) + if (Double.TryParse(((OSDUTF8)this).value.ToString().AsSpan(), out double udbl)) return udbl; else return 0; @@ -676,35 +668,22 @@ public virtual void Clear() { } public virtual OSD Copy() { - switch (Type) + return Type switch { - case OSDType.Boolean: - return new OSDBoolean(((OSDBoolean)this).value); - case OSDType.Integer: - return new OSDInteger(((OSDInteger)this).value); - case OSDType.Real: - return new OSDReal(((OSDReal)this).value); - case OSDType.String: - return new OSDString(((OSDString)this).value); - case OSDType.OSDUTF8: - return new OSDUTF8(((OSDUTF8)this).value); - case OSDType.UUID: - return new OSDUUID(((OSDUUID)this).value); - case OSDType.Date: - return new OSDDate(((OSDDate)this).value); - case OSDType.URI: - return new OSDUri(((OSDUri)this).value); - case OSDType.Binary: - return new OSDBinary(((OSDBinary)this).value); - case OSDType.Map: - return new OSDMap(((OSDMap)this).dicvalue); - case OSDType.Array: - return new OSDArray(((OSDArray)this).value); - case OSDType.LLSDxml: - return new OSDBoolean(((OSDBoolean)this).value); - default: - return new OSD(); - } + OSDType.Boolean => new OSDBoolean(((OSDBoolean)this).value), + OSDType.Integer => new OSDInteger(((OSDInteger)this).value), + OSDType.Real => new OSDReal(((OSDReal)this).value), + OSDType.String => new OSDString(((OSDString)this).value), + OSDType.OSDUTF8 => new OSDUTF8(((OSDUTF8)this).value), + OSDType.UUID => new OSDUUID(((OSDUUID)this).value), + OSDType.Date => new OSDDate(((OSDDate)this).value), + OSDType.URI => new OSDUri(((OSDUri)this).value), + OSDType.Binary => new OSDBinary(((OSDBinary)this).value), + OSDType.Map => new OSDMap(((OSDMap)this).dicvalue), + OSDType.Array => new OSDArray(((OSDArray)this).value), + OSDType.LLSDxml => new OSDBoolean(((OSDBoolean)this).value), + _ => new OSD(), + }; } public override string ToString() @@ -751,106 +730,109 @@ public override string ToString() return "undef"; } } - + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static OSD FromBoolean(bool value) { return new OSDBoolean(value); } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static OSD FromInteger(int value) { return new OSDInteger(value); } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static OSD FromInteger(uint value) { return new OSDInteger((int)value); } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static OSD FromInteger(short value) { return new OSDInteger((int)value); } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static OSD FromInteger(ushort value) { return new OSDInteger((int)value); } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static OSD FromInteger(sbyte value) { return new OSDInteger((int)value); } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static OSD FromInteger(byte value) { return new OSDInteger((int)value); } - public static OSD FromUInteger(uint value) { return new OSDBinary(value); } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static OSD FromUInteger(uint value) { return new OSDBinary(value); } public static OSD FromLong(long value) { return new OSDBinary(value); } - public static OSD FromULong(ulong value) { return new OSDBinary(value); } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static OSD FromULong(ulong value) { return new OSDBinary(value); } public static OSD FromReal(double value) { return new OSDReal(value); } - public static OSD FromReal(float value) { return new OSDReal((double)value); } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static OSD FromReal(float value) { return new OSDReal((double)value); } public static OSD FromString(string value) { return new OSDString(value); } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static OSD FromUUID(UUID value) { return new OSDUUID(value); } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static OSD FromDate(DateTime value) { return new OSDDate(value); } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static OSD FromUri(Uri value) { return new OSDUri(value); } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static OSD FromBinary(byte[] value) { return new OSDBinary(value); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static OSD FromVector2(Vector2 value) { - OSDArray array = new OSDArray(); - array.Add(OSD.FromReal(value.X)); - array.Add(OSD.FromReal(value.Y)); - return array; + return new OSDArray() { OSD.FromReal(value.X), OSD.FromReal(value.Y) }; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static OSD FromVector3(Vector3 value) { - OSDArray array = new OSDArray(); - array.Add(OSD.FromReal(value.X)); - array.Add(OSD.FromReal(value.Y)); - array.Add(OSD.FromReal(value.Z)); - return array; + return new OSDArray() { OSD.FromReal(value.X), OSD.FromReal(value.Y), OSD.FromReal(value.Z) }; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static OSD FromVector3d(Vector3d value) { - OSDArray array = new OSDArray(); - array.Add(OSD.FromReal(value.X)); - array.Add(OSD.FromReal(value.Y)); - array.Add(OSD.FromReal(value.Z)); - return array; + return new OSDArray() { OSD.FromReal(value.X), OSD.FromReal(value.Y), OSD.FromReal(value.Z) }; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static OSD FromVector4(Vector4 value) { - OSDArray array = new OSDArray(); - array.Add(OSD.FromReal(value.X)); - array.Add(OSD.FromReal(value.Y)); - array.Add(OSD.FromReal(value.Z)); - array.Add(OSD.FromReal(value.W)); - return array; + return new OSDArray() { OSD.FromReal(value.X), OSD.FromReal(value.Y), OSD.FromReal(value.Z), OSD.FromReal(value.W) }; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static OSD FromQuaternion(Quaternion value) { - OSDArray array = new OSDArray(); - array.Add(OSD.FromReal(value.X)); - array.Add(OSD.FromReal(value.Y)); - array.Add(OSD.FromReal(value.Z)); - array.Add(OSD.FromReal(value.W)); - return array; + return new OSDArray() { OSD.FromReal(value.X), OSD.FromReal(value.Y), OSD.FromReal(value.Z), OSD.FromReal(value.W) }; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static OSD FromColor4(Color4 value) { - OSDArray array = new OSDArray(); - array.Add(OSD.FromReal(value.R)); - array.Add(OSD.FromReal(value.G)); - array.Add(OSD.FromReal(value.B)); - array.Add(OSD.FromReal(value.A)); - return array; + return new OSDArray() { OSD.FromReal(value.R), OSD.FromReal(value.G), OSD.FromReal(value.B), OSD.FromReal(value.A) }; } public static OSD FromObject(object value) { if (value == null) { return new OSD(); } - else if (value is bool) { return new OSDBoolean((bool)value); } - else if (value is int) { return new OSDInteger((int)value); } - else if (value is uint) { return new OSDBinary((uint)value); } - else if (value is short) { return new OSDInteger((int)(short)value); } - else if (value is ushort) { return new OSDInteger((int)(ushort)value); } - else if (value is sbyte) { return new OSDInteger((int)(sbyte)value); } - else if (value is byte) { return new OSDInteger((int)(byte)value); } - else if (value is double) { return new OSDReal((double)value); } - else if (value is float) { return new OSDReal((double)(float)value); } - else if (value is string) { return new OSDString((string)value); } - else if (value is UUID) { return new OSDUUID((UUID)value); } - else if (value is DateTime) { return new OSDDate((DateTime)value); } - else if (value is Uri) { return new OSDUri((Uri)value); } - else if (value is byte[]) { return new OSDBinary((byte[])value); } - else if (value is long) { return new OSDBinary((long)value); } - else if (value is ulong) { return new OSDBinary((ulong)value); } - else if (value is Vector2) { return FromVector2((Vector2)value); } - else if (value is Vector3) { return FromVector3((Vector3)value); } - else if (value is Vector3d) { return FromVector3d((Vector3d)value); } - else if (value is Vector4) { return FromVector4((Vector4)value); } - else if (value is Quaternion) { return FromQuaternion((Quaternion)value); } - else if (value is Color4) { return FromColor4((Color4)value); } + else if (value is bool bv) { return new OSDBoolean(bv); } + else if (value is int iv) { return new OSDInteger(iv); } + else if (value is uint uiv) { return new OSDBinary(uiv); } + else if (value is short sv) { return new OSDInteger((int)sv); } + else if (value is ushort usv) { return new OSDInteger((int)usv); } + else if (value is sbyte sbv) { return new OSDInteger((int)sbv); } + else if (value is byte btv) { return new OSDInteger((int)btv); } + else if (value is double dv) { return new OSDReal(dv); } + else if (value is float fv) { return new OSDReal((double)fv); } + else if (value is string stv) { return new OSDString(stv); } + else if (value is UUID uidv) { return new OSDUUID(uidv); } + else if (value is DateTime dtmv) { return new OSDDate(dtmv); } + else if (value is Uri uriv) { return new OSDUri(uriv); } + else if (value is byte[] btav) { return new OSDBinary(btav); } + else if (value is long lv) { return new OSDBinary(lv); } + else if (value is ulong ulv) { return new OSDBinary(ulv); } + else if (value is Vector2 v2v) { return FromVector2(v2v); } + else if (value is Vector3 v3v) { return FromVector3(v3v); } + else if (value is Vector3d v3dv) { return FromVector3d(v3dv); } + else if (value is Vector4 v4v) { return FromVector4(v4v); } + else if (value is Quaternion qv) { return FromQuaternion(qv); } + else if (value is Color4 c4v) { return FromColor4(c4v); } else return new OSD(); } @@ -939,14 +921,14 @@ public static object ToObject(Type type, OSD value) } else if (type == typeof(OSDArray)) { - OSDArray newArray = new OSDArray(); + OSDArray newArray = new(); foreach (OSD o in (OSDArray)value) newArray.Add(o); return newArray; } else if (type == typeof(OSDMap)) { - OSDMap newMap = new OSDMap(); + OSDMap newMap = new(); foreach (KeyValuePair o in (OSDMap)value) newMap.Add(o); return newMap; @@ -959,46 +941,86 @@ public static object ToObject(Type type, OSD value) #region Implicit Conversions + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator OSD(bool value) { return new OSDBoolean(value); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator OSD(int value) { return new OSDInteger(value); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator OSD(uint value) { return new OSDInteger((int)value); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator OSD(short value) { return new OSDInteger((int)value); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator OSD(ushort value) { return new OSDInteger((int)value); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator OSD(sbyte value) { return new OSDInteger((int)value); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator OSD(byte value) { return new OSDInteger((int)value); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator OSD(long value) { return new OSDBinary(value); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator OSD(ulong value) { return new OSDBinary(value); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator OSD(double value) { return new OSDReal(value); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator OSD(float value) { return new OSDReal(value); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator OSD(string value) { return new OSDString(value); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator OSD(UUID value) { return new OSDUUID(value); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator OSD(DateTime value) { return new OSDDate(value); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator OSD(Uri value) { return new OSDUri(value); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator OSD(byte[] value) { return new OSDBinary(value); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator OSD(Vector2 value) { return OSD.FromVector2(value); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator OSD(Vector3 value) { return OSD.FromVector3(value); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator OSD(Vector3d value) { return OSD.FromVector3d(value); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator OSD(Vector4 value) { return OSD.FromVector4(value); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator OSD(Quaternion value) { return OSD.FromQuaternion(value); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator OSD(Color4 value) { return OSD.FromColor4(value); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator bool(OSD value) { return value.AsBoolean(); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator int(OSD value) { return value.AsInteger(); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator uint(OSD value) { return value.AsUInteger(); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator long(OSD value) { return value.AsLong(); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator ulong(OSD value) { return value.AsULong(); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator double(OSD value) { return value.AsReal(); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator float(OSD value) { return (float)value.AsReal(); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator string(OSD value) { return value.AsString(); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator UUID(OSD value) { return value.AsUUID(); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator DateTime(OSD value) { return value.AsDate(); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator Uri(OSD value) { return value.AsUri(); } - public static implicit operator byte[](OSD value) { return value.AsBinary(); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator Vector2(OSD value) { return value.AsVector2(); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static implicit operator byte[](OSD value) { return value.AsBinary(); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator Vector3(OSD value) { return value.AsVector3(); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator Vector3d(OSD value) { return value.AsVector3d(); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator Vector4(OSD value) { return value.AsVector4(); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator Quaternion(OSD value) { return value.AsQuaternion(); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator Color4(OSD value) { return value.AsColor4(); } #endregion Implicit Conversions @@ -1015,7 +1037,7 @@ public static OSDMap SerializeMembers(object obj) Type t = obj.GetType(); FieldInfo[] fields = t.GetFields(); - OSDMap map = new OSDMap(fields.Length); + OSDMap map = new(fields.Length); for (int i = 0; i < fields.Length; i++) { @@ -1050,8 +1072,7 @@ public static void DeserializeMembers(ref object obj, OSDMap serialized) FieldInfo field = fields[i]; if (!Attribute.IsDefined(field, typeof(NonSerializedAttribute))) { - OSD serializedField; - if (serialized.TryGetValue(field.Name, out serializedField)) + if (serialized.TryGetValue(field.Name, out OSD serializedField)) field.SetValue(obj, ToObject(field.FieldType, serializedField)); } } @@ -1071,12 +1092,19 @@ public OSDBoolean(bool value) this.value = value; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public override bool AsBoolean() { return value; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public override int AsInteger() { return value ? 1 : 0; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public override double AsReal() { return value ? 1d : 0d; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public override string AsString() { return value ? "1" : "0"; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public override byte[] AsBinary() { return value ? trueBinary : falseBinary; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public override OSD Copy() { return new OSDBoolean(value); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public override string ToString() { return AsString(); } } @@ -1093,15 +1121,25 @@ public OSDInteger(int value) this.value = value; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public override bool AsBoolean() { return value != 0; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public override int AsInteger() { return value; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public override uint AsUInteger() { return (uint)value; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public override long AsLong() { return value; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public override ulong AsULong() { return (ulong)value; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public override double AsReal() { return (double)value; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public override string AsString() { return value.ToString(); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public override byte[] AsBinary() { return Utils.IntToBytesBig(value); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public override OSD Copy() { return new OSDInteger(value); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public override string ToString() { return AsString(); } } @@ -1164,10 +1202,14 @@ public override ulong AsULong() return (ulong)Math.Round(value); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public override double AsReal() { return value; } // "r" ensures the value will correctly round-trip back through Double.TryParse + [MethodImpl(MethodImplOptions.AggressiveInlining)] public override string AsString() { return value.ToString("r", Utils.EnUsCulture); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public override byte[] AsBinary() { return Utils.DoubleToBytesBig(value); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public override string ToString() { return AsString(); } } @@ -1190,8 +1232,11 @@ public OSDllsdxml(string value) this.value = String.Empty; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public override string AsString() { return value; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public override byte[] AsBinary() { return Encoding.UTF8.GetBytes(value); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public override string ToString() { return AsString(); } } @@ -1244,8 +1289,7 @@ public override bool AsBoolean() public override int AsInteger() { - double dbl; - if (Double.TryParse(value.ToString(), out dbl)) + if (Double.TryParse(value.ToString().AsSpan(), out double dbl)) return (int)Math.Floor(dbl); else return 0; @@ -1253,8 +1297,7 @@ public override int AsInteger() public override uint AsUInteger() { - double dbl; - if (Double.TryParse(value.ToString(), out dbl)) + if (Double.TryParse(value.ToString().AsSpan(), out double dbl)) return (uint)Math.Floor(dbl); else return 0; @@ -1262,8 +1305,7 @@ public override uint AsUInteger() public override long AsLong() { - double dbl; - if (Double.TryParse(value.ToString(), out dbl)) + if (Double.TryParse(value.ToString().AsSpan(), out double dbl)) return (long)Math.Floor(dbl); else return 0; @@ -1271,8 +1313,7 @@ public override long AsLong() public override ulong AsULong() { - double dbl; - if (Double.TryParse(value.ToString(), out dbl)) + if (Double.TryParse(value.ToString().AsSpan(), out double dbl)) return (ulong)Math.Floor(dbl); else return 0; @@ -1280,8 +1321,7 @@ public override ulong AsULong() public override double AsReal() { - double dbl; - if (Double.TryParse(value.ToString(), out dbl)) + if (Double.TryParse(value.ToString().AsSpan(), out double dbl)) return dbl; else return 0d; @@ -1292,8 +1332,7 @@ public override double AsReal() public override UUID AsUUID() { - UUID uuid; - if (UUID.TryParse(value.ToString().AsSpan(), out uuid)) + if (UUID.TryParse(value.ToString().AsSpan(), out UUID uuid)) return uuid; else return UUID.Zero; @@ -1301,8 +1340,7 @@ public override UUID AsUUID() public override DateTime AsDate() { - DateTime dt; - if (DateTime.TryParse(value.ToString(), out dt)) + if (DateTime.TryParse(value.ToString().AsSpan(), out DateTime dt)) return dt; else return Utils.Epoch; @@ -1310,8 +1348,7 @@ public override DateTime AsDate() public override Uri AsUri() { - Uri uri; - if (Uri.TryCreate(value.ToString(), UriKind.RelativeOrAbsolute, out uri)) + if (Uri.TryCreate(value.ToString(), UriKind.RelativeOrAbsolute, out Uri uri)) return uri; else return null; @@ -1330,10 +1367,7 @@ public OSDString(string value) { Type = OSDType.String; // Refuse to hold null pointers - if (value != null) - this.value = value; - else - this.value = String.Empty; + this.value = value ?? string.Empty; } public override bool AsBoolean() @@ -1341,7 +1375,7 @@ public override bool AsBoolean() if (String.IsNullOrEmpty(value)) return false; - if (value == "0" || value.ToLower() == "false") + if (value.Equals("0") || value.Equals( "false", StringComparison.InvariantCultureIgnoreCase)) return false; return true; @@ -1349,8 +1383,7 @@ public override bool AsBoolean() public override int AsInteger() { - double dbl; - if (Double.TryParse(value, out dbl)) + if (Double.TryParse(value, out double dbl)) return (int)Math.Floor(dbl); else return 0; @@ -1358,8 +1391,7 @@ public override int AsInteger() public override uint AsUInteger() { - double dbl; - if (Double.TryParse(value, out dbl)) + if (Double.TryParse(value, out double dbl)) return (uint)Math.Floor(dbl); else return 0; @@ -1367,8 +1399,7 @@ public override uint AsUInteger() public override long AsLong() { - double dbl; - if (Double.TryParse(value, out dbl)) + if (Double.TryParse(value, out double dbl)) return (long)Math.Floor(dbl); else return 0; @@ -1376,8 +1407,7 @@ public override long AsLong() public override ulong AsULong() { - double dbl; - if (Double.TryParse(value, out dbl)) + if (Double.TryParse(value, out double dbl)) return (ulong)Math.Floor(dbl); else return 0; @@ -1385,8 +1415,7 @@ public override ulong AsULong() public override double AsReal() { - double dbl; - if (Double.TryParse(value, out dbl)) + if (Double.TryParse(value, out double dbl)) return dbl; else return 0d; @@ -1405,8 +1434,7 @@ public override UUID AsUUID() public override DateTime AsDate() { - DateTime dt; - if (DateTime.TryParse(value, out dt)) + if (DateTime.TryParse(value, out DateTime dt)) return dt; else return Utils.Epoch; @@ -1414,8 +1442,7 @@ public override DateTime AsDate() public override Uri AsUri() { - Uri uri; - if (Uri.TryCreate(value, UriKind.RelativeOrAbsolute, out uri)) + if (Uri.TryCreate(value, UriKind.RelativeOrAbsolute, out Uri uri)) return uri; else return null; @@ -1437,11 +1464,17 @@ public OSDUUID(UUID value) this.value = value; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public override OSD Copy() { return new OSDUUID(value); } - public override bool AsBoolean() { return (value.IsZero()) ? false : true; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public override bool AsBoolean() { return value.IsNotZero(); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public override string AsString() { return value.ToString(); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public override UUID AsUUID() { return value; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public override byte[] AsBinary() { return value.GetBytes(); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public override string ToString() { return AsString(); } } @@ -1684,8 +1717,7 @@ public OSD this[string key] { get { - OSD llsd; - if (dicvalue.TryGetValue(key, out llsd)) + if (dicvalue.TryGetValue(key, out OSD llsd)) return llsd; else return new OSD(); @@ -1693,36 +1725,43 @@ public OSD this[string key] set { dicvalue[key] = value; } } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool ContainsKey(string key) { return dicvalue.ContainsKey(key); } - + + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Add(string key, OSD llsd) { dicvalue.Add(key, llsd); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Add(KeyValuePair kvp) { dicvalue.Add(kvp.Key, kvp.Value); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool Remove(string key) { return dicvalue.Remove(key); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool TryGetValue(string key, out OSD llsd) { return dicvalue.TryGetValue(key, out llsd); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public override void Clear() { dicvalue.Clear(); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool Contains(KeyValuePair kvp) { // This is a bizarre function... we don't really implement it @@ -1735,11 +1774,13 @@ public void CopyTo(KeyValuePair[] array, int index) throw new NotImplementedException(); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool Remove(KeyValuePair kvp) { return dicvalue.Remove(kvp.Key); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public System.Collections.IDictionaryEnumerator GetEnumerator() { return dicvalue.GetEnumerator(); @@ -1958,36 +1999,43 @@ public OSD this[int index] set { this.value[index] = value; } } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public int IndexOf(OSD llsd) { return value.IndexOf(llsd); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Insert(int index, OSD llsd) { value.Insert(index, llsd); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void RemoveAt(int index) { value.RemoveAt(index); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Add(OSD llsd) { value.Add(llsd); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public override void Clear() { value.Clear(); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool Contains(OSD llsd) { return value.Contains(llsd); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool Contains(string element) { for (int i = 0; i < value.Count; i++) @@ -2004,6 +2052,7 @@ public void CopyTo(OSD[] array, int index) throw new NotImplementedException(); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool Remove(OSD llsd) { return value.Remove(llsd); diff --git a/OpenMetaverse/Primitives/Primitive.cs b/OpenMetaverse/Primitives/Primitive.cs index 1ff62c40..aba38b5c 100644 --- a/OpenMetaverse/Primitives/Primitive.cs +++ b/OpenMetaverse/Primitives/Primitive.cs @@ -717,7 +717,7 @@ public override string ToString() } /// - /// Information on the ReflectionProbe properties of a primitive + /// Information on the RenderMaterial properties of a primitive /// public class RenderMaterials { @@ -817,7 +817,7 @@ public OSD GetOSD() public static RenderMaterials FromOSD(OSD osd) { - RenderMaterials rm = new RenderMaterials(); + RenderMaterials rm = new(); try { if (osd.Type == OSDType.Array) @@ -832,10 +832,14 @@ public static RenderMaterials FromOSD(OSD osd) entries[i].te_index = (byte)map["te_idx"].AsInteger(); entries[i].id = map["id"].AsUUID(); } + rm.entries = entries; } } } - catch { } + catch + { + rm.entries = null; + } return rm; } From 70f31cd561010bb31af194ee6c6f1e8882c41fef Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Sun, 18 Jun 2023 01:01:50 +0100 Subject: [PATCH 097/149] fix a typo on prebuild.xml --- runprebuild.bat | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runprebuild.bat b/runprebuild.bat index 93f85203..af3d48e7 100644 --- a/runprebuild.bat +++ b/runprebuild.bat @@ -4,7 +4,7 @@ dotnet bin\prebuild.dll /target vs2022 /targetframework net6_0 /excludedir = "ob @echo Creating compile.bat rem To compile in debug mode - @echo dotnet build --configuration Release OpenSim.sln > compile.bat + @echo dotnet build --configuration Release OpenMetaverse.sln > compile.bat rem To compile in release mode comment line (add rem to start) above and uncomment next (remove rem) rem @echo %ValueValue% /p:Configuration=Release opensim.sln > compile.bat :done From 5f0ec0faf3d559ce664654eca5a60e2916f3b520 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Sun, 18 Jun 2023 01:05:58 +0100 Subject: [PATCH 098/149] update prebuild binaries --- bin/prebuild.exe | Bin 0 -> 148480 bytes bin/prebuild.runtimeconfig.json | 12 ++++++++++++ 2 files changed, 12 insertions(+) create mode 100644 bin/prebuild.exe create mode 100644 bin/prebuild.runtimeconfig.json diff --git a/bin/prebuild.exe b/bin/prebuild.exe new file mode 100644 index 0000000000000000000000000000000000000000..aada172a4f85022fcfcf5064eed16c4a4a345124 GIT binary patch literal 148480 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 literal 0 HcmV?d00001 diff --git a/bin/prebuild.runtimeconfig.json b/bin/prebuild.runtimeconfig.json new file mode 100644 index 00000000..418df653 --- /dev/null +++ b/bin/prebuild.runtimeconfig.json @@ -0,0 +1,12 @@ +{ + "runtimeOptions": { + "tfm": "net6.0", + "framework": { + "name": "Microsoft.NETCore.App", + "version": "6.0.0" + }, + "configProperties": { + "System.Runtime.TieredCompilation": false + } + } +} \ No newline at end of file From 0c3649b081b721be35e9c3837d97bcdf06d6c44f Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Sun, 18 Jun 2023 01:22:27 +0100 Subject: [PATCH 099/149] =?UTF-8?q?add=20some=20com=C3=A7ilation=20json=20?= =?UTF-8?q?files?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bin/AvatarPreview.runtimeconfig.json | 19 +++++++++++++++++++ bin/Baker.runtimeconfig.json | 19 +++++++++++++++++++ bin/Dashboard.runtimeconfig.json | 19 +++++++++++++++++++ bin/GridAccountant.runtimeconfig.json | 19 +++++++++++++++++++ bin/GridImageUpload.runtimeconfig.json | 19 +++++++++++++++++++ bin/GridProxyApp.runtimeconfig.json | 13 +++++++++++++ bin/Heightmap.runtimeconfig.json | 19 +++++++++++++++++++ bin/IRCGateway.runtimeconfig.json | 13 +++++++++++++ bin/PacketDump.runtimeconfig.json | 13 +++++++++++++ bin/PrimWorkshop.runtimeconfig.json | 19 +++++++++++++++++++ bin/TestClient.runtimeconfig.json | 13 +++++++++++++ bin/VisualParamGenerator.runtimeconfig.json | 13 +++++++++++++ bin/VoiceTest.runtimeconfig.json | 13 +++++++++++++ bin/WinGridProxy.runtimeconfig.json | 19 +++++++++++++++++++ bin/groupmanager.runtimeconfig.json | 19 +++++++++++++++++++ bin/importprimscript.runtimeconfig.json | 13 +++++++++++++ bin/mapgenerator.runtimeconfig.json | 13 +++++++++++++ 17 files changed, 275 insertions(+) create mode 100644 bin/AvatarPreview.runtimeconfig.json create mode 100644 bin/Baker.runtimeconfig.json create mode 100644 bin/Dashboard.runtimeconfig.json create mode 100644 bin/GridAccountant.runtimeconfig.json create mode 100644 bin/GridImageUpload.runtimeconfig.json create mode 100644 bin/GridProxyApp.runtimeconfig.json create mode 100644 bin/Heightmap.runtimeconfig.json create mode 100644 bin/IRCGateway.runtimeconfig.json create mode 100644 bin/PacketDump.runtimeconfig.json create mode 100644 bin/PrimWorkshop.runtimeconfig.json create mode 100644 bin/TestClient.runtimeconfig.json create mode 100644 bin/VisualParamGenerator.runtimeconfig.json create mode 100644 bin/VoiceTest.runtimeconfig.json create mode 100644 bin/WinGridProxy.runtimeconfig.json create mode 100644 bin/groupmanager.runtimeconfig.json create mode 100644 bin/importprimscript.runtimeconfig.json create mode 100644 bin/mapgenerator.runtimeconfig.json diff --git a/bin/AvatarPreview.runtimeconfig.json b/bin/AvatarPreview.runtimeconfig.json new file mode 100644 index 00000000..1b351ac9 --- /dev/null +++ b/bin/AvatarPreview.runtimeconfig.json @@ -0,0 +1,19 @@ +{ + "runtimeOptions": { + "tfm": "net6.0", + "frameworks": [ + { + "name": "Microsoft.NETCore.App", + "version": "6.0.0" + }, + { + "name": "Microsoft.WindowsDesktop.App", + "version": "6.0.0" + } + ], + "configProperties": { + "System.Reflection.Metadata.MetadataUpdater.IsSupported": false, + "System.Runtime.TieredCompilation": false + } + } +} \ No newline at end of file diff --git a/bin/Baker.runtimeconfig.json b/bin/Baker.runtimeconfig.json new file mode 100644 index 00000000..1b351ac9 --- /dev/null +++ b/bin/Baker.runtimeconfig.json @@ -0,0 +1,19 @@ +{ + "runtimeOptions": { + "tfm": "net6.0", + "frameworks": [ + { + "name": "Microsoft.NETCore.App", + "version": "6.0.0" + }, + { + "name": "Microsoft.WindowsDesktop.App", + "version": "6.0.0" + } + ], + "configProperties": { + "System.Reflection.Metadata.MetadataUpdater.IsSupported": false, + "System.Runtime.TieredCompilation": false + } + } +} \ No newline at end of file diff --git a/bin/Dashboard.runtimeconfig.json b/bin/Dashboard.runtimeconfig.json new file mode 100644 index 00000000..1b351ac9 --- /dev/null +++ b/bin/Dashboard.runtimeconfig.json @@ -0,0 +1,19 @@ +{ + "runtimeOptions": { + "tfm": "net6.0", + "frameworks": [ + { + "name": "Microsoft.NETCore.App", + "version": "6.0.0" + }, + { + "name": "Microsoft.WindowsDesktop.App", + "version": "6.0.0" + } + ], + "configProperties": { + "System.Reflection.Metadata.MetadataUpdater.IsSupported": false, + "System.Runtime.TieredCompilation": false + } + } +} \ No newline at end of file diff --git a/bin/GridAccountant.runtimeconfig.json b/bin/GridAccountant.runtimeconfig.json new file mode 100644 index 00000000..1b351ac9 --- /dev/null +++ b/bin/GridAccountant.runtimeconfig.json @@ -0,0 +1,19 @@ +{ + "runtimeOptions": { + "tfm": "net6.0", + "frameworks": [ + { + "name": "Microsoft.NETCore.App", + "version": "6.0.0" + }, + { + "name": "Microsoft.WindowsDesktop.App", + "version": "6.0.0" + } + ], + "configProperties": { + "System.Reflection.Metadata.MetadataUpdater.IsSupported": false, + "System.Runtime.TieredCompilation": false + } + } +} \ No newline at end of file diff --git a/bin/GridImageUpload.runtimeconfig.json b/bin/GridImageUpload.runtimeconfig.json new file mode 100644 index 00000000..1b351ac9 --- /dev/null +++ b/bin/GridImageUpload.runtimeconfig.json @@ -0,0 +1,19 @@ +{ + "runtimeOptions": { + "tfm": "net6.0", + "frameworks": [ + { + "name": "Microsoft.NETCore.App", + "version": "6.0.0" + }, + { + "name": "Microsoft.WindowsDesktop.App", + "version": "6.0.0" + } + ], + "configProperties": { + "System.Reflection.Metadata.MetadataUpdater.IsSupported": false, + "System.Runtime.TieredCompilation": false + } + } +} \ No newline at end of file diff --git a/bin/GridProxyApp.runtimeconfig.json b/bin/GridProxyApp.runtimeconfig.json new file mode 100644 index 00000000..e355688b --- /dev/null +++ b/bin/GridProxyApp.runtimeconfig.json @@ -0,0 +1,13 @@ +{ + "runtimeOptions": { + "tfm": "net6.0", + "framework": { + "name": "Microsoft.NETCore.App", + "version": "6.0.0" + }, + "configProperties": { + "System.Reflection.Metadata.MetadataUpdater.IsSupported": false, + "System.Runtime.TieredCompilation": false + } + } +} \ No newline at end of file diff --git a/bin/Heightmap.runtimeconfig.json b/bin/Heightmap.runtimeconfig.json new file mode 100644 index 00000000..1b351ac9 --- /dev/null +++ b/bin/Heightmap.runtimeconfig.json @@ -0,0 +1,19 @@ +{ + "runtimeOptions": { + "tfm": "net6.0", + "frameworks": [ + { + "name": "Microsoft.NETCore.App", + "version": "6.0.0" + }, + { + "name": "Microsoft.WindowsDesktop.App", + "version": "6.0.0" + } + ], + "configProperties": { + "System.Reflection.Metadata.MetadataUpdater.IsSupported": false, + "System.Runtime.TieredCompilation": false + } + } +} \ No newline at end of file diff --git a/bin/IRCGateway.runtimeconfig.json b/bin/IRCGateway.runtimeconfig.json new file mode 100644 index 00000000..e355688b --- /dev/null +++ b/bin/IRCGateway.runtimeconfig.json @@ -0,0 +1,13 @@ +{ + "runtimeOptions": { + "tfm": "net6.0", + "framework": { + "name": "Microsoft.NETCore.App", + "version": "6.0.0" + }, + "configProperties": { + "System.Reflection.Metadata.MetadataUpdater.IsSupported": false, + "System.Runtime.TieredCompilation": false + } + } +} \ No newline at end of file diff --git a/bin/PacketDump.runtimeconfig.json b/bin/PacketDump.runtimeconfig.json new file mode 100644 index 00000000..e355688b --- /dev/null +++ b/bin/PacketDump.runtimeconfig.json @@ -0,0 +1,13 @@ +{ + "runtimeOptions": { + "tfm": "net6.0", + "framework": { + "name": "Microsoft.NETCore.App", + "version": "6.0.0" + }, + "configProperties": { + "System.Reflection.Metadata.MetadataUpdater.IsSupported": false, + "System.Runtime.TieredCompilation": false + } + } +} \ No newline at end of file diff --git a/bin/PrimWorkshop.runtimeconfig.json b/bin/PrimWorkshop.runtimeconfig.json new file mode 100644 index 00000000..1b351ac9 --- /dev/null +++ b/bin/PrimWorkshop.runtimeconfig.json @@ -0,0 +1,19 @@ +{ + "runtimeOptions": { + "tfm": "net6.0", + "frameworks": [ + { + "name": "Microsoft.NETCore.App", + "version": "6.0.0" + }, + { + "name": "Microsoft.WindowsDesktop.App", + "version": "6.0.0" + } + ], + "configProperties": { + "System.Reflection.Metadata.MetadataUpdater.IsSupported": false, + "System.Runtime.TieredCompilation": false + } + } +} \ No newline at end of file diff --git a/bin/TestClient.runtimeconfig.json b/bin/TestClient.runtimeconfig.json new file mode 100644 index 00000000..e355688b --- /dev/null +++ b/bin/TestClient.runtimeconfig.json @@ -0,0 +1,13 @@ +{ + "runtimeOptions": { + "tfm": "net6.0", + "framework": { + "name": "Microsoft.NETCore.App", + "version": "6.0.0" + }, + "configProperties": { + "System.Reflection.Metadata.MetadataUpdater.IsSupported": false, + "System.Runtime.TieredCompilation": false + } + } +} \ No newline at end of file diff --git a/bin/VisualParamGenerator.runtimeconfig.json b/bin/VisualParamGenerator.runtimeconfig.json new file mode 100644 index 00000000..e355688b --- /dev/null +++ b/bin/VisualParamGenerator.runtimeconfig.json @@ -0,0 +1,13 @@ +{ + "runtimeOptions": { + "tfm": "net6.0", + "framework": { + "name": "Microsoft.NETCore.App", + "version": "6.0.0" + }, + "configProperties": { + "System.Reflection.Metadata.MetadataUpdater.IsSupported": false, + "System.Runtime.TieredCompilation": false + } + } +} \ No newline at end of file diff --git a/bin/VoiceTest.runtimeconfig.json b/bin/VoiceTest.runtimeconfig.json new file mode 100644 index 00000000..e355688b --- /dev/null +++ b/bin/VoiceTest.runtimeconfig.json @@ -0,0 +1,13 @@ +{ + "runtimeOptions": { + "tfm": "net6.0", + "framework": { + "name": "Microsoft.NETCore.App", + "version": "6.0.0" + }, + "configProperties": { + "System.Reflection.Metadata.MetadataUpdater.IsSupported": false, + "System.Runtime.TieredCompilation": false + } + } +} \ No newline at end of file diff --git a/bin/WinGridProxy.runtimeconfig.json b/bin/WinGridProxy.runtimeconfig.json new file mode 100644 index 00000000..1b351ac9 --- /dev/null +++ b/bin/WinGridProxy.runtimeconfig.json @@ -0,0 +1,19 @@ +{ + "runtimeOptions": { + "tfm": "net6.0", + "frameworks": [ + { + "name": "Microsoft.NETCore.App", + "version": "6.0.0" + }, + { + "name": "Microsoft.WindowsDesktop.App", + "version": "6.0.0" + } + ], + "configProperties": { + "System.Reflection.Metadata.MetadataUpdater.IsSupported": false, + "System.Runtime.TieredCompilation": false + } + } +} \ No newline at end of file diff --git a/bin/groupmanager.runtimeconfig.json b/bin/groupmanager.runtimeconfig.json new file mode 100644 index 00000000..1b351ac9 --- /dev/null +++ b/bin/groupmanager.runtimeconfig.json @@ -0,0 +1,19 @@ +{ + "runtimeOptions": { + "tfm": "net6.0", + "frameworks": [ + { + "name": "Microsoft.NETCore.App", + "version": "6.0.0" + }, + { + "name": "Microsoft.WindowsDesktop.App", + "version": "6.0.0" + } + ], + "configProperties": { + "System.Reflection.Metadata.MetadataUpdater.IsSupported": false, + "System.Runtime.TieredCompilation": false + } + } +} \ No newline at end of file diff --git a/bin/importprimscript.runtimeconfig.json b/bin/importprimscript.runtimeconfig.json new file mode 100644 index 00000000..e355688b --- /dev/null +++ b/bin/importprimscript.runtimeconfig.json @@ -0,0 +1,13 @@ +{ + "runtimeOptions": { + "tfm": "net6.0", + "framework": { + "name": "Microsoft.NETCore.App", + "version": "6.0.0" + }, + "configProperties": { + "System.Reflection.Metadata.MetadataUpdater.IsSupported": false, + "System.Runtime.TieredCompilation": false + } + } +} \ No newline at end of file diff --git a/bin/mapgenerator.runtimeconfig.json b/bin/mapgenerator.runtimeconfig.json new file mode 100644 index 00000000..e355688b --- /dev/null +++ b/bin/mapgenerator.runtimeconfig.json @@ -0,0 +1,13 @@ +{ + "runtimeOptions": { + "tfm": "net6.0", + "framework": { + "name": "Microsoft.NETCore.App", + "version": "6.0.0" + }, + "configProperties": { + "System.Reflection.Metadata.MetadataUpdater.IsSupported": false, + "System.Runtime.TieredCompilation": false + } + } +} \ No newline at end of file From f0ac2291be9b3319ae9cec90ef2e0976a0aaeea7 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Sun, 18 Jun 2023 01:42:49 +0100 Subject: [PATCH 100/149] update a few libs --- bin/ICSharpCode.SharpZipLib.dll | Bin 188416 -> 192512 bytes bin/PrimMesher.dll | Bin 43520 -> 43008 bytes bin/XMLRPC.dll | Bin 26112 -> 26112 bytes bin/openjpeg-dotnet.dll | Bin 201216 -> 528896 bytes bin/zlib.net.dll | Bin 65536 -> 65536 bytes 5 files changed, 0 insertions(+), 0 deletions(-) diff --git a/bin/ICSharpCode.SharpZipLib.dll b/bin/ICSharpCode.SharpZipLib.dll index 536337c20af0016c789676d85806052b1816d08e..3b268b7c6ea36b5dc50d2e10993b05e5a19e4880 100755 GIT binary patch literal 192512 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 z

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�T^Ycx`>7k69V*t=i;lePC^V04T{=S`+}^ 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 I|2Gi$zZR(3xBvhE diff --git a/bin/PrimMesher.dll b/bin/PrimMesher.dll index c63db93841bfa2ba402afadaaa2ee0f6696a0d9f..1f7b1b9670e736ccf7c20cfc29d29886b644cd21 100755 GIT binary patch literal 43008 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 diff --git a/bin/XMLRPC.dll b/bin/XMLRPC.dll index 2189d090268d0b6e8283f915264d38db18b0c6e7..e6fe0eb3a6f56c3b691d7b28592bdc7ab90e969c 100755 GIT binary patch delta 6361 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 delta 6406 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 diff --git a/bin/openjpeg-dotnet.dll b/bin/openjpeg-dotnet.dll index 6377b8d9702d9ce2f955ca45f38331589fa2f8cb..677b13507e3a412ee6b9fbd47f0b5e2cc9d9e963 100755 GIT binary patch literal 528896 zcmd?Sdwf*Yxi>zOnZO7md#F)kr7~h_gF`*hq;1kkb#}5R*&B8s$i*NC(ZLiHHNr%p zhCrMI*|yB4M+=h$sC8#P5IolWn)z#!cKZ z&i33Hofp1n*E=tqy=3VMZ|(A1f4cm-o4ujyZn@>wu=n~Kyvyru@h-i^tIU|?z4_L~ zH(Yw=nPYOSs(<+8iQAU9-#01wf5)5~Cf$kfjyXS_G*&!oCauQP`>*$2R4JaDE~*#L zUtRPwJU9Pv(WKk(T;6{Fq+C1?KYs5;E5vitMK_4&eOCCUNff`l-65WbAAdl^U$r!} zgxVh2)5@UDws_qr+aLe-%)(?^zipCtY{oc`%{$6wb7hF=fyXfj9`U*sZ{|CakVE_> zpSEh3Imn33uz6F3tg?tTD@i`6FvSF#N89#eg0hX#wp@w~xNQ5W(nF(d_syjU>#x#f z3!h=L^}9yfW+&rL^Q=5$w9O^}wG#72+4h@VIZbYx?b7fKE5k?$T!2OiAnH3IOWL2; zW~;t*`Qq!s*V$|zUysUBr)@EwIRxm?UjWryYG$)NScLe;0gD&U^?0WJ1#Gt1rL|^8 z(MR;vR)q{to{}$c>GBoJLr4;1g0ZpTpY=m8;x9n$F27;ft;k4YWW!k5#^C7^nMEG@ z3D|5UslfjwFM(NVaX|rs3jHJwd*wXPp10S&@>l+!Jt|lYHO)L{?pak`|^nT zu9j!ZbL6@5)i2h1Z8koE0P`K94&;gs7?0#Ui3HVnF6UW#vdnvbH`=D=Z&Qt?oN5ts zK#l4-dHl9N+idymeCKAHO=kmYbaqaj%G&tDf3evVR_apOSsLr+FMo@Y52>t&Lf?6o zLj7uUOltbvX0tKX<#QR+vRSR$SL-xZOke?zK|}YMw0Q>&+-vL2fy-}K*zTffxeZ}8 zv_p?hX+~i*bATO}CI)OZHPXZ;im~aTZrw4>qp`B=scd%kl&MkoB^rxYM1u}3&NEd1 z?w3S1sXSiM91EW-JwIl>OHIVo=v7WYuld?Fe_LIzoM>^J)FN986#uN;`lmJ4#WRX+ zHtNFD=z_*}@js8JdF;!;9I_4O$mH+h#h4O3`bZ89uEypUYHUS7WADq0f7uuC;iJ{3HN4GV1S;u5OpE-XpX2 z#&J0kht1r?*nBAYoH zRkYEZYY}d*J1n!SU9#_7V^+4z?r_V#I|M2!IZKREZ&bD$r8$Z*Ete@dg+}QVl{MvT zLJw88J{Ocs~g3k1UI>>U$bPsP{rY>mx! z5WZfXAFGI#CDE0&=~8*j#8qHA@U>*U+a=I75!3uJ06z>@|42AG7u9{Je0=T*ffD*1A@_sX})=wP5)s?p-arK->2v_N^cmCJI@D%?8TZ*o<7ZyXj!~yw;|i zK@b*-ldg^(k;XUW*v_)q`bw>YOiIYjd>dRhnRZ0-oY{gfGH=N7ATzS&onzJ!Iqs-; z?P$uGsv(ROIvx3Fg)YfI*xcSQQ(@)V3Y#%OjW*>hK^6x5v*=B0z)4K7Rq#!t%GDa+ z1XOF_V|u7Y)qr9I`V~X{LX8G;)JU(rZWr4rzbI0%{wh%&zvG8#R1qm^E6Spo@@&~C zbFuOXc(@hz(`-fB{L={vI~ZA$Ym+v*kd^IK*^!zd`bUIMXUeE4WzphETBuuf%<$-; zojM*W+pDwP6~5iNza2QWx1xEE)C7WH(;_E4(p^M9wdmA@7Im-JqH;oWwCMiW9hsWH zeZ@^0Yf&SI`fE1T$kHumV90Bv>b4r`y0#;-w8lk|8W!JBlUW7MG_* zVgW4@_o$H;kLvHKdsOr934cfT(GY_k$kOx9@v>p7hz6W$q6LX{AIpiYGJ8Xf>;QFM zlq+p;fyIHU#h)Zp>aSosh!+Kjs$Bv659Y`6_oyJ?m$@l@zaU^wp|d)uqW&YBjSA2( zcJYb7x7olH6qR-GSz~QBqufOcy7Des(4+Mbf^3$XD*oO z!7@I((M-(c_aM<+hN<7)I|qlYM**P@%LPfCu~r0jG5We{jo@Fv>{K>{jzKMD1pseF;%v)Ery(} zMFV!#kUjaat-BN^qkK?$J|?rC(^jFPZZ)kMWxXvwrY2<1R_fGCUd&YQEjMOZ9R<`< z^VJB7)LpwEedPur92nXJz6qc=$LhWvSv6sF-I*e4wHY-UHAc4OZZ(%3y(I^X%ImD1 zX%m{;>)aY^=VMSrMpy>qiT1rba>y>Dc2Pdn-r7~!32LD3T>d6V8<1wqP~DVZHMonI zkE2C3#$!NSh{W)y#!Rzs1jDd&N@Ro=FYu`6vuu!@{xVjM>5-LAwhC* z@KlWjIj*ZQO5R|!D#3^>2b&MB^d{*a+bgqKKm-JvIUSFfK!Xo zfVb-NsK&A!3`01_E6=5>^AA>p_G_$HWuGhTvtV{$q?J8YooRGFs^29F>}q7j9Kqr)tzgIK2($t2(W~9j8D1s2Cc*#y(+rY*6?Uv|tTb^g%_~(LY(5$uOB4*# zunXu{UH;px+^z zxGw=ZLBPTpAyIT$)_5 ziJt>4MPbb`;ziLp&&q}~2W`nMIWcy z#jrIKt2CjA#>`j@U2_j!Q?T??{N(5%Jox3^)P`sZZIGx!z0QHiOr6d}r)$k|G@BBG z*-Y7}c~s&NuQXxJUNbg;*gP|qS`Oef)p9k(PmWgN!Po!0KqG1{kJ>80K-A)yM^X|0 z84!gHnCK__5_~GcYUqt2JX?y0l4#bIgqGjOyPVh|M^0u)8v+k@#<<4X)X)ju2UN2VzmxUzT@+j% zu1(>6CqIBF;^3W1v?POf3=91YAuw*CL{mNASc#--k@TxA`23 z4WS(RC(4Bp5zWd+s!6#(SU_FEpe{tidcTWgK@~^#hooI1VG290u>tB6`<$PP+*Y5U zBK7lQ7^p2`;aKf;b0@N}xm6~dzPYnOKoc!$Xb*kwMX;yhPG&|eHS0R+x zu14p({kJIfk5bOLh+_L?8m(>_!*wy092%}}9z+Ci1mo4s&!9w%mkQDYq8y-Ms}%GY zO795rpQNWrd?2D~F#*W?p^w0TK|(dQpYO#OSYy~lWB3;e*W7a5&B;0I;xR-uC&EQ4 z`?~pX!{tI=R6}PCWq1r3)X*&FP)w9!&{H+?sl86fd^aJ+>S`Bt)i27VFr$lKg9x*$ zT_aHg#N1*$y-wsJ1OYA-LdsT|1}U$^tNPoPPp)87v-N1^pT0E;VkDNn$$Shb{Tds? zzdhMz6Lz4&ty0)Lq(OSNYugK&c)oDqRo1b zDS#x9H%-8yvgsU{$zET2jD^qOZvu_;6VYqH%04q$yh0P(#dE>cqwcqWPf*Ny_P*yh zK`j2CVl+s34`Zn$IlUTcQ5_`XSdCEFp4K41@yXdk5RF_x>r6y2f=z^rEA$q0T zSdyiNO0!f)t7_bdK`QmqqA~8w?Y$d0nh)2lQXw0JQ37kq#>%oFSe_Lb$f&yxYZ`e~ z7v^(8AAZZSRTfxKBi#~k9g+Ss_PI1K^C{0L@PjJzsY+8~&|QquEPffmXOu#35yqS5 zpJ6&xHWrA~Ese5)W$<5JOcUL~6ALp4orLH%oB*aKj7Yh6u0{0%Om^lUR>V9h(b_~= zw4fHkjkIwrEh2ExYFgh*bYpQ&tsebu^>}FGlfyZA;95WU9gtX>jMb08PaZ|U)b}t3 zqw@FUxA%QJT9J5h?wmPuj`gyZIG^a~i8`JD}hx3G6OD5jU^!%X5kFf+)MH*g%zfGpfkDIOic0_ zy=NkgqEmlqtW*neHS{@|-kKq5*qZmOIV1A5UE2673_et%Alprn^i?w3Ek{eBqO5}C zBRl)XEB<{AqZOunHrSVm$L>M3dC#g$N|IFnzWPxj#fb!GB$ff=lI)1Z2Qnr*cSHYH z{jb;miDvk6G?KJp%yd>Xx35B75OzwL*<@c}z~3fS#G$Fx9ZbU@6>P*cYi`O)41FYq z@*r%qDzz*%dK>0pg-c_!(War;V~zDrbg%>*`gP+<*#@)nokI|0z7&0J=!Fb-pGYpJ-GiU&xXMYGwc zz41N#kSTd*War65i!nQ=P>y`MIZkmH|Z zXwf?okZN_4IEAq`A)8j~#uGV@qnzkaQr=P^5W) z>;DO8v`E4!ZGgoSV?R3wb{aPXXzWyE{f%Hz8NMX4&?7aP`pRss$Bs#uBP z99t39`dLYFsiBPXu#$jm$XTpJL2wM7xzIK~L-Z7cAHp*a$#@h{GM?FZN_bAd(~YMW z$!=DXL&sq3DE{w$soGiUt%bR z6QCF}ezO3GbJaf0@sEVl((bzwBZ-=-fa za@<~b4u~l%wkrWD%YdH#5}=nsDkC3xv`DYm-dNQkv+X`u(6N9jY4c(&z-PAaVi0Kw zwME)aV*d+BLhBZJs#G?Af*eUW8WzdXI|i{{5<61%?jTSe_^%S&o4#Yht@3r)E($^h z&w+Xg)5LmG>S0gUJkofZ=769I>UCI+Y=yP=6MNlXWOj_kV}5$2{#2!xS(O$m z?5G|s7By<||IEw+3&($_gj0t>;h8nm^7q*E=6eWVNW8ghZU zvfJFgBH8yt#di_E_yp<>wV5K$j=ck|3^9(~TH(9W?e?0%{`A zdj15>q@AEnI@<@@R=~Omw}3tk(B>KjWp=v@Rs`Pb4v3K9(J7` z0uA_zhOQzssKr0bV4tMslLTq8&GO4}=41xs#Ot(f0%Bylx&IfibUPAaNcSMVfSFCv z((__1QdigxUke(`li8?KASi53G%Oz4p9r#T0@VqB9=DpzMU#N@`;gu$La%A@_aK*V zRah4hA|hhBWc-)eY}cTH*@Y1hnn%y=vn)R?6i92gHF+zWrk&)VK{DedcSBitD$#ZH* z*c?7rL&8Sb-f$^R4#_tvhD47}cnatsvjZ}7R7B^yWFtd&>`|fjU`dgD#MZl4oZxbFZv|Dj>8_oxa^wss9Dwd?=O`ZKiGp4y9R)~p~T{^aH?ci91Zcs)h zs3FaxCfW&`3u&=bl7)Wb72v~~F@GRGrWrT&YsLz$8FwD4Fhct)jGKBYj1_Ga#+@-L z6j0f2jj36xuSZ?lLOf4l#V%Iwa$YF$l= z?-^G;0>*tgF(k{49}40&Mox6gk?xanqP3B>tcl!pL^@6;wyGf*6^=sI$q4$smg+Q@GLDgQ&F+T>Dp+;JP&&zW1>~+5;jsXhW$#0pN zf#G;Y^cg$D{|2CJ=&R@?pNB-~oq*^zHDrootq@%|kWY-op2JW9!4<)+pU7E@CRD6Qnr$M;B+rms^PqT| z%NX>SFfO%FER0NBFIuP{79*kmyoQ`Y|2YZ$=RO+b{8;mzhHJ#?2}V_D2R)=6)NJ}j z{h&RmrgWw02ac^mf`@uAq#OLr(ha1IJ~X7U9;ly|cBKjJYCCCHx~U@Q!?ml|g$iWq z2c~uvlO1uW9z#09pVAj2DM9B#sjK@IvpZrVHJ})Jg{+En21$QCjSQx7Au%q)gDqxOL zh-mN&q5WdgM4eDXB~nC3nR=+qDhHbnn)B;_%YqdQCE#?l5Gm*ZB?pCxUrt!q)A*jv zgBM4S8b5KSJQ-qC%vAyH^xx1DM4X@MV7*DLZzje&=n zdL#)=8;>~J13sZawDxC=@W|FmCTGPlY&ulsM_@;3xE{hPb?zHGb=2zAmm@j_*D0%0 zGVB&3o007!J9RTUWscwfj;>use0{_~me_}P?NaI&=#v(rt$mlewC9g-$xvC#cg@jn zQR4$=%0^&7BQkXWwzQ4dOtZo7&3PP|9i)d1&ukze(W?5tu0PmYjI3BYYsO&X0u|2rZd$ZSttHi zx_UYcvSw3s6}^P^CGb@68*}}g+CLLl(Z8c3`!|HGr^6fzTSfnIr^rK%qI>D`5Ow%}RUSHdJdrq69wN!-gD-}O zL=UD!qWOUBbRrS;lb0beO(Y@^M~FoK6M2ZL8j^>u0gNOMnXxH(h$NuyBSRw5zf;7k z<^Qcn^qv2`A`$!~$O|?eWIJIFXc)7502~Ik?=?r|Nc;#~I^@V#_J*@k>xI%=MEXl` zRkF#xovY40c0k_ymE8D#0yb#bw>xN5Ic3AMRo?qPLdkf;L-AW7SHW!vE}X~h(yw9( zc=!zeBcGr2KidC^X03&l9X6Oscru+okO>pI$Ju7)J0;zJe0aL4kInPwfcf>NO$3z-w+TGyu))SqLd`LLt-AyBSasb;oYm zFts#NR!26U)lZ%XBs0|J& z!$+I+R}ih_{!CtEl?Mypv$~1c?6R#H6Ita3H@p(OiOqD=#?9Aar@8Mu1R*{n-G%gt zNY6hk|D9ME_8{OldG<$`G?Jw&Nj|HRSwf9}=u{ou{7huh*f`45g*-Bw>tb)I@%NF~ z!TV8x#zqBMnLEg)W1q^C`8Q+=`nutl3pY#!+E2976O{BeAcsSByuq&(^-&QQinyuB zMifzeou?}@T6OH@m!yiMTKUm`)5@_FV5wHz|4l2~#9*NFH2#&u8meJK$U9|2M-R2Y zU?A<-1B38@vwndVtsGS2AA#w}a5Ha#)%JeWG{nCoPXGqiwQCV4&1;dyuO*!pkq?Rx z9-hF9=Ie`i-EY3`7rNWF3V++`i=p1btO@pYC{uN`RrunPM@EgBS7ep;BIO!yGG&lb2BloYR%Ik3JrwDYa*Cq zQ<5p!l#-p+cp#ZFfl?-d$oJ=UBghCT& zbk^)+F+~=eprM~;WFTTHFf~$c2Z07a zs-^;v@g-;;lTlSduuKI`5#&<|x+EHvcqj#!Lj|X1QHq5zCE1h$BoSpMPzvyZP_HD9 zQh*AgOaY}}_C-5|l!CbyWr`^U^DD|!QVQl(l$lK_l~$Q5N||kySwJZwMogW#!7&L7 zAEUOq41@SZ(6?I)p{L2tqBm7zs1!OOV8GaoA7fRAAskPWIDRVjN?N=sF~Mz8ZgCDM z)G+4{FlL3^P81ku;C(Qgn3|65!<2a&zD$iDKZt1{9?M{foavEYf#{0;tM{BbJaio6 zW!4L4&C;klpc+{@I+#L$Ok^%g-%vyQ9b)6I(7#=Zo`tf~^DXk29ZyP9b0$La(HP#o z0%AaNQ6pbr+BYFEE$W=FwZ_E;SJW-Yjo7W4YS~mZ_Lc5y!?6gL>g(4Xam2p`uxwiE z4l1Mj;P(BM{0a;Mh}u3Nq7LcUqiKzaI$O76VI;u(HD4cD9kBs{-JqMcexVCV|JXai z8m}FD$8^wwkRXPrHAYpD%n+RhGTsY=-+p-LK>RQ_%P@r4>z|#Io#NLe%n81aLrk=9 z_KUTEr<5tV{l;DOs7PkYll?}?T9_WVQPPAI2Z9gcISS85@U-LkIFdg$N}eFwS}qh% z8{%F>+5n!fpo$mqj3Eym+Yp_B=YBk$c>V*~sj5Rr{=z8vz{IR2G#uz>fOr?Ylf*$S z%pELm8~~DS{1Bcnzzv8XW>fd?m7=BaQ3HVodx187D6;~tD&R1z1Cw=)c5FYk(6ngQ zI?eYcI=zz&+=j_{0K{E`hWrm~MH%uTgdWBdut2kVz4sF!LH<#5=2zgI=2Q>8ZX$rW z!)YOaxnF5cwlJ(?d$S@s&5p^Q5p_>XqJX)p>Fc*PHFX@0g1Ckwc{^zCG}Z@!7x3!0?S||iWUeIOYWJI#Ft0< zE0DsA@wO3y;XPY(#5I4*nu`hXjFLg@b{0|i9GN*^G_cbxpQPYuAjE)C;-n%Tvp7^+ zY#v#~eWlFlG)g8=T%{FvF5*TTC0=nD#HwS^D1n%Z0W#|-r1xsHDN`dkC;+@JhB$(e zpqOs~iYJYdK!tzj8aVd?XoX5FF-t?1QgUjo*1m_hQAWuEid$*LorMY!SB>JUsRw{? zG0btWUd73Lz1BqUUQDgPY?WmJICFpRzd~-+e`NKIgxGor-kv+AN1Y1^zo!A2E7)F; z8lXA0g;h`m-`mW20%%P;vDBsb8XEjx81i5R-m_SSVaH@UC;`SC=fl`624!)=hzGe0 zlo%-gsur37HKE+&gLnA3WN#5tbxq0myAxHNzD^6@EIL|vO=3rO%GsvpvqyF96wUzM26HHL6pkodHUe( zH_z4QP}zBE^TF_~*B(A7bp9Aq9ECpwR8zhM%YkMcM9vF4AU0Z6=HhGr z0JxyAq#Cl6bkgde-wyZ373YJ=M^a}W!C8CD6!cSO1JS9k^N)W>77i{BQN2imdQ(S% zu`)|%Ul~;%zJpSYU^bHLzWWmTW#jp;(ttq0JG=d(OdBtzfn=ThIi$fY^Umgj4dMKw zTJ&0YCmj{^ZFM#)9nc&njnS-h&?tAZvy7`d5cM1<- zqZ~!DjPePL4qLYyH$%TTAQ zFhpK+X<5TA`i_qG9{GVdf<*Iki|`*6W&jOcZ4V2zxG+Cabf>4`$0qk-yV)^w|5_PG zP=qDgdVUm@;Otd4_B>Z>dJ@x+(v>j`cuMx?#e+OIAatZ*P^xbKie+c)c7ky;a zV%w`U#>Q{j zqjL!VW+)7eqmxHd;n5UqNCnHmny}xQ3YTIGI{Ct(a506a4}}3c_EQlyN(&Sw(Js;Y z{{WDYH7=X9;Wy&ViML;hH#go4ywUJgCqXCwuUdX$4=@tG8U-|xN;Otgfhovvtrq&e%1Z0is6jQt&+a*UTOW11v>vb9tk>2iyZ56+0#dxq zs>9z?4+rNJ%eE8%FYp2{%@vD{6*#&-!^5AxJOfrCJx5oK#{H<4O;d3qdlo=zLBqhg zPtx^06^s+cda8&oK}oD0!1D(I&khJ%lLyku`}^y=i72=T8$<2-JA>3VYMYdH7Q(~Xr*(@cS_ z$$(Mnr0`!Tj9~-fL1Ea%e>aqlW0kx3FA>HQcVO@VywY|YXP?SNYdj4>;oXE&a-jbp z^uiAzLZ}gW7e_DMqp0{3C`0}UUHoY;IbByopC_D<{kMARJA^Ni%5Gmw9tPF4RZvBA z9j+)x!`BegCf2{9-2V-W6Mf*R3kAv7TQ>go*Ww_x|^&rwvYf9J# zTaWM-D=SX48+yi|Osn!W40o=)XgEh5!A}LHwnjcV%zS8=mxy6rs)NEN=W`w%1>!e! zVTkBZPve~)a?6t*Ye}^58HhCrOlUvlx)NcPMQNzirF#ir!#PGAWwxmM@Iy?s6OnH? zzrQ+peo1AwfkzzI*=$sIbEk& z6~q_wj~4yqNdOcc!(M&@&qQlq20JM?4ic2D5lX^8TawoR>K*)^U2wJL8Buo~c3Nx? z9m9zyoZ2cbtOy;`{9RI1_`xiV--kps`toxquQ~>F-)Cv(U(D$T2Ps8e(Ybb`e1Q1L z4-hg}U-=+~ze{0i-w=HEoMdLfWnBo#{%tbbC9+6*n=wOh>rZj`8)B3i{X2m`uB~0`)FC0sh){>kIksk2USP>fVt!5e1oLV2eicxwn=-skdzA4 zARv^dL*}fa73(0`2>h{HO0Ax5?xT9B=hWnWJ|Qj0B?MSod|*`MkUf6f$$CLxBLB>A z^hOJ8(dikE&S>c%W(92MBDNnU9nb@!Io*8UP8w`jf4X@GUIl1Ee}NP-Y>h$xPswL# zh|KRtDGRDDobFwRVB}K=Tq9>vhw{?K1B)1-cSSyR@@nLQe;1%hOETx=td1= z5*^J4*L>KVSR;<#0itx7E`2`IMk#X$9vY>i?SNk{5N9MGxRpV7KUlvtHg!Cio#$; zp+lDau=!w}CprrprJG-eqHKTUuu~7+UW;eC=&nL z(IpOd-ZKS3{;NL;U5kmVk=WM`NJt_Dj{;;c?pE-thBi}SjL!E|_NAlG8lNuS-%8_S z7Kq+%PjswT#$maxdD|kbI1Ouvq88Gp2yB{)N)w!&Zcm1GN`eMm=fajQ5CZ~!e)&Ou z7g|dOc^v|JC|IS2`eBo(12w9sG%oAA)I8-gF@I0f!8+J>f|W%D8Pa`QVIPB)MfSJV ze~1L=%fZSLqhM_!SS2Jq5*RK*jbK=)Oo$&&3PxADtj_M@4r-q86oOVQ3SbrV@1P5CP6&=`&*fm4CnnW0V(?C|TTX;e9(YkX8+JB;osCq;wY$}8oRK`lG zk)kern}ks!D=UpKPV2r*IV-=QoH!3yZOlH;ZN67lGyU6cTmb>cUj5ryv_eX%)ummj z;)=cAo~15@6e^;u3KZj+^K@##3d2Bg9$6&d&L74FGB_8E-Fx^S^B->}$R1%D@g)!5)~-c9Y_+VF zJnAOwwrs+V?BfVOj_|VxKZ|e-;TXa_2=^d-2;oBr_aod-_R6|Hpe~rhw8j_-Y|{7) zqwDUQ5XVY?hZL+^xk#x|CET5|-ta z9dFRl`3IjN44tNs4Sos9RG}$u)xm>ck~v9#F|p*Sb_Z%-@BA0I43di&r*c7iG1gKk zEDbm~rTFV}s;3(6Tyc}YO96l&DRC$_2@C>QL9NLOQillA<)0xTfCS2fElJT|2)w4`KL?Q}=%(Z!OohSM3K3A*Mxh1>=5Oi(f@&L0 zV{&O5Cn-S*d>|dr3%!u|6c7yxA3G3PIVD4C`Uu^G8C7s*-v2&r4w0#-4fh^FI6uT! zyJ50q(-s8tkIL*5rRcUQY2#xkL#C9fAUnB<<`+iv^id?ZdS9vN#ZjfGwyNPr z=#FWxBOn1_sCY89jh2t|4=<#aff&)7opfxl005OP@Yhz=_cVq?E0Jj~FO7FKvBo80 zNiJMO4udq9(DUEOG&OnZ?X)f!{UdaOysWZhPz z5nk^!Bk7`xWMut%;5agpeK3hOmi9#Of`9!@z?-xgo1mg8I&nI+S|%F<%F5CU95w}_ z0IX>&dE~PD#*&de5km)ljI-Biup3Px3H$|A=4znFhVuf*%C|o$m<}-<5n*O9t3#%- zlnERvfK8)Hbn#x%JtKUtlceB)q1+2fQ(m2D%BJ>D*ChhgBlZ`BQGJBu!ekXoL)t9s z8ty&H{~&2PdwU|856ZJ~2V$uTo0^XMEH^s9oFK2{A13P|?$#kH;MLik^*}S-aS|?7 zMVm=+s)st4+ApU4fVCJ-)8ih#$#gL4SeStA7sl)DNJO-GHlyK85fC>0F2#YnoBH{i zD=?%ugf8lC*i0Sw5(TTJy@&NE4e2Pm%qYmkb1_+>FT>3NAjZ$Ri0x}3oaX~$CZmXp zdc`V0>%rkg4WJ%G=+Q}>=OyMteN`LdG^wzSPzSZhcBkmBe?ZzW4l7S)+i0Nay!$Y| z^diy{eIKMS$$VjFZ^4C2*!B4f9+4A?u*bhU>}Hj?p(Ex-xDHG+<{T0*P5ajt3=lv) z5S<$3*IWRo(JhB+WD~xQw3lO92@JK$9H%lDQyFn(L)a^2#sdRl~HXaCsjPd*;-GL+Drv8>XAUU-`K)O|M86SMy#mi>@D z1XA;5*mYD58T0WuZUzH?H~`1>@Hnyywc)atCAhD_ZsXT{Xvxul9JZsb)>4v^&^^v4 zzC!vg8)$qNcT*=CkJIgKb&J6<<{}99!{$n-)buVgHx_Q9B$%eBEr_g|Vwakl5UaC* zi(15$%Yf0f<{5v0j*~JK70cWY#~S2D&}95WoZpYIE8;xeHL|$9lJ-I+P?2fXAt3c?(@M zCpFRbFV*-bgk@i=9~SJoi_@EI0|=C16EaYfI9fj-HAhj*nz0U^i6me~e>!GJ&0WZX zU8+JHM`JTw%_^|tx1uo|&;TBQmUaUTX1JoVg#uue9sH@61YFJJW`Z32p<`s}#mQz9 zZlWZWbPM8zmqP}ibC+ZZ#I7}s!5=XH=>EFhY282LJ?ehn-y_Gx40m%C6{6M1ac}rP zkl9X|X@+T1|M4z}%Dq(8^{9%#c^Kdz*YA2VZGGobf@UQ&nhDnQC7 zbtF2N{P`&~Hiztkg0ZP|Q5`nInh#1%s|6U-0<>-ev=x}ix12|`h0y{sBc4J8C}@7d zWE2fQB)VBh)^3IRfc*@%;W855_!={(8ht)VYZI;hf%=1{Ne4OkwW9J4K1V#MO^ksm z0v5X-GEE4)CWx(Dw@3rm6ceViMUffBW@xk-0^Ms5|3GDpLRZ3syFqC9N7>Y$89L&H zgqe)rW5x4!@v_Jq5V{0d^oit}l?WuaLm+bI_OeX29xqJF#bJ8&v!ip87W-Bde{W0KAP~{d^+v(zDP`jk4LTWtEF5uJ0THzuH;`tfe{b z;MEtH&z0hgSqFbysMsAm8;7&x$d$J6_k|C6(P~e_MM?dOb`CoD?KtaYzD+rgBnkg& zPyIjH98Z1%C$z4Fyp)oU2zCqTlE^EUkuGBkpNUSH#lL?(Dw^Yg64$tc)M@{T`c5sf zCSW5ciVl7ORuz(QA)wB-lL_$5qqJe1BcMBna%{Lz!0I5AQwP7|T=WQ=MrV@3F!QgV z25m+e%rRs62m5GNuT}wD5YvMze5K88xFMUaQ6WDF%>2f601kRJNI~HU_{So54~Wu^ zU70`v9GR7)Ww?@{4Ob99Nu!BB#OA@B&?`6{&wPuBS!s3!F4#6!U>&}$g}~V{!03>B zy=+v#s?|xy3UDNc34wM zMNdUx8<(W>F(^4AMGb8bNe~n@At=6+1zZSCL+Raw+pwutLqH!Rgz-}mkgEJ8(163N2Sh7<-1Y#E zbl4zptO7H3Ira9jznB&bIN(%|Fkzfxx^S?F$`ZKBx@ zSo6%c`g2nFYN96icjOfp^~FXEvV)(%B*CMSpe4Y5NPvw>0}QM1zk>~C70nd*uLXXi z7OCleR7W+v@@GN}bnmo=np1kIuLn$Xp;HYRb4KLBeLaMN#_aV1A#k@AZsFNUg_72v z5e3NVF7&Ai{5`HkbrZx16h ziTd@yp9G>NcAgGZvlNJhd1_-Tu|-;itc4aK7F8^{{=}+N{Qc5~pAVAw(aC@NA&pok z-+7R5Z(26L@LR;luwPCGP0{XnYIhmhg)@b(Y&NzIgqIdXl&Wv?t~32(($w@JdEHAl z`9d?cUnZ1L9ji$FgY?3`b%bWFr|?>j)Vu>}iu8PNJg!VuejKYivo$D|w!)4` z&u0{uhKq~!aBgvBIIH-oIvGaX`%o8qq{xW{(Rb-k*iGRJhQj2%);De_>_QkGj^Y$- z(@ZofJzrv{2FJ*5f)>w4i$SXfX|vVjWoZ$jO>bI+XjDpz7}hFA zpIXf*434iGk8T1Yo7p(U{{Pl+xCYfbsL`=#l(+_kM>JQG2DBL3|1bT-{vR|#VJ#t> zgSl4(5yCt#O7a((+Q^^E+Fr)#vD+4q!K_jby;nEh^t~`myN>C?FsQ-r;?8BJlC*S? z_?qf?iTF0Lu&I9pTZ+LkuBa@h{sQwNzkOSAtjgNXzT$cvkDYC8-;K(KN*I1 z7S9+N<>sIMA-N|~4nNOs{tm(*z2#X)N87^{WHk)1Pm1nvHWbsYovKG)corj@tdu{C z>u;6O7Q_4%G*e$I2b34vO)i?&idDBOHCz3FFe7C5`u}8#ZJm7DGc?GuaQutBJ25_x3Bl1= zmxF=AnanyTJJ9!|LuMK@OkoHhpyvh68FU9K znpBN*sJV>OWed2>eD0xqj??A?6QugGhVnU2n=jkUH^Is`ln1@YOzVT!%$GA%->9Ly zY58)^d{c(g+U00zR6oQpf9E!u@zS$D>&9*aR;GAax3iMX;HqS=LdX)O0b_E@6HqA9wiO3Saimp->8IyB(=8!%0mzqG}VZ z5cSP9n_7UTVEDtW@cpd;6?6^P&Fb`E8wXW1>0%pg8a3@?8=d0C&8BA=Dv%P+rtn|H zVuE(5MjE`f@DJEJ)9|qF6%Kmcb&bWe27j|Tbq-EH4 zY2({Q({Pp5=O3gr5e-S8nlzUw#LvM?m*8SCc);L>DVQrr9`KSKeWhS`DSlVM8X!Q% zn3xgWaa=aa-7um|RoOl*dXEaJQS-f#razHe0b2A*O|Jn9Fs``lXN=3Rv!*dCA#WRv zyZT@?6vtDXL4UcszKfOR;qwrv*U4zC%3ac{>&DO!8Rai6^>3gis3dz zb6Ma{N+(vV}r*I6P+;E}PI{wY+Zno}Yq@o^t8l`AmKi;ML zVhCn25jeJAZfzt+PBQZO?GaohU})L?KYoFXb?38n19%nBd z=B)pqHyinmmgU*;H56Eb8xYDri1VdtXh2#|$LQ&TQ))zyKH3D;829r$FbFXHZ?2v% zvj|m;(OErOz|-f+Z>OO^{+ABEI*8ymugS0+Z7|3Pp|ukUdRcR<)WD~NsI77MOw@R42HmmsO{5d> zG^2zFGGG(IHD8t*W+r@j1a}SM9wHp=`qVBN=b=+1<=2AjWaGkm+)U`q=I=j&=owgt%3IDZdT|2oW^DH&UnM>1@prPU^6SuuGtY4YX+q+z=o-=M!H^ z@4mPA!w89Q5zs23WU>e2(|*ubmMF%OnXd~0ErlV2<{&2m|pP)n8>gJJ|W z)th0)c!u)yKaQo0&Al%E01%V%bRmX%j(7C@afDJmr{upQ0zIeKCQ4(|g~{6^x&awq zVcYqy-=PGOIDkt)C{j_yR;GyA~%{& z?3vcn8A?-co91}VPVB_&5JaN{{Hl8RXaX4mlE8mBgrgiq_diO}7G@1aA3(Gknwvrt zoWC+-vXbM}$^VL&qoeF$xD%seIEmKa#8Dc|ZJru^l<0HH{vIK^XBMP8sadDPL2ZXo z0iAZ3@ANk~>tUi07$XJ=+B%Jbd2cASmW|m9RaZVAhNWBQDO3?}kuU$x)VAgoEcUB>@v?IAVM)`n44F3x^4yi*#^~!h^$UBs?@N9s6$|Z4 z0*C!zL`1VLrK%QD8o98FHBW89vzLhE?Qc@T>4+q)cMp-lN1P{?8Y^FwNk2 zxuXn+Q+xPWz<^Is*y}7Q-?bEDPyAakF1ri;;R)KS{b&`odQ78EW z+4{!D4~;duD3&kH(VrhiA0k^_;!@8Gl=R*3l0zk3SVHHSW&(QJu}|Ve zH(!UMV!h*;el>F~kd!0KSZv{KG}Jcp9qNTjb9SyRWsXT~LL->Z&?We}h&UW%eh!$UlD)8UpsegjX7bD8z zw&KfBZYnuM3vm7h5y>w@efle!-{g9uX|QH>rGYbbZ<&Fb z%n{(Ppb0f{=VDuU0)h7%3S#FUA9oYEpw07#U=KIZC{6B3wlR_(S-wAc`0k?4PT=SU zm^viGr53ls6&g&2|8J*J;@a{{fWiF&fCd2I6Cb33XJ#iqM}RRGV6+MDK{?6bN^6(D z1b8A1ZsBg#$@?C_22>d~`e7?+0A)%@O=L)73#k>}iBys{(I0(jdle=f2V^c`a|^{r z8C)AnjM*-H;I#}?scf;9bhtL1tzCUV_>IGo0uO#m$U+obvJ(!a!SAA3YvfSU;M1%SSB(xojw%LtE_ThYU{SCSVzocnMagu8x= z7`zLxr;2%0U9F8O7C-&b4Gp8=TqWKCvj2XX%}yNGxDan_u3L#tJE^mnkTghZcylX8 zuL0sNw#Ntf24qrviRjg%D8ezo=OaQ3y^~y0M4k8@q9!T=PjX&_kT{)Dgby&m&J}4H z1rJH{+mYWv8e}m`AfU1Y&#=laNw19Xt}@M}Xju~%^}cqW$rDH7pXrgE30EV6OQN-ilb_XPYV2iUe!iMA4zEQ`D=2KS~))GS$IvGm}$NV+UU&VsLs~5DZdh zK@HYZ%{NdAo)vfw@z#kVe;RMS0udH(b%+u;w*p(}`H?l)Qa_u{rN2nP!wno9)XV>l zFVT%TGzz8OInu^8Uovn*|XRD}&fRQHI`1#AEz($*r$2arWfL;jBR(eu=Zs!7Dy`j8B<= zu1c4{Q-dDJ^trSUCy~-G*|N@OM^@2+mILrN`U=AjisUAl<2<_9Bk4c&izC97-pvj1 zGL|wVzsE~4012+FL+9-?stL%^M{u-uOE2I`L3UY<0?*sXKI$K2e{9MvbV@Ja zJ20TG*uQ}nwxfnjMzmvw!2H3QL|YBa4Nc96r~oHWq!)Um7dmRNUvty$0_~=q1tpRv zD+50ZGCcTQoZ&5FdPW{zo%RxGypxi2JCerhB7GqRwEndOE1`K60sWC)L>m1B`hn=GlU3S0a`{}-sBIL zkuC<`t)t|P*2NcmPNP=g=Ckmk8>`_bOnf7C?uGiDcD31X=Pj&6ISb$JkX~3aNoQV# zeW|jQ**aV4QCTgM2lf>ZJj7PSPA4-&eKK;7!7qRM6NelW^iE zNCP)1&j{ufPOOup7tA)N8Ve>(>6=SQ?hdS`9)G~0l)az0Nsf42^0?vqfVU&h+zjhe5u28 ze3R%J6hMsyvkg6V8_(G;c^ zx~0u}Ax3p};S`|u55*aVuN4;8eP9{RZ;20sZS5N^`{S}SBQ9-j#c{<4@qL0O1Iqw+ zDA6@``%Kdt4kAa%pOjo*S%U{G;d|Epq4WaKwyj_)(~G9i3d-a^?zh{3%t-LJEfh8|n^yv6YOVB=l_fx8lz9Sxn zLomM2RLE;~gL2?(5aLY7aavraU$aSDuwi2P2oR-7a{?ctcU!1(sBzJ$5Ak)UHjzKF ziR=GIP0*P9IPJa~7r*3nBEr)wcSyHrX_{(|-N{d=YaRS3Jp}{_5NFJgW%LC4$jWkPQ{765u zF2$jbhYsK_9e8TH20Ke9pm`~Sf7&<3e{d8CNMvGA_XSo#pg^gQ?B$8 zT=|4U>0k!=2a6VE-=1`N?&2AM3Cb|;WX_t8%@`b&@h{3=eu#+d)kyN;+^ZnL@Gtj@ zh8{|9Xz}SAf{js4b*~chG>o}h^9A~h^JijFX}FRYMqF4OPe{!#1EZ7L7!NU0Gz9DV z9W4w@ah~+T5wbcKf`{C$I@hufE__ce?w67 zoBL>C@_ewJtt*0R^je2S|5D?XPvC=e+0dV_3H(XPi1nqI=WhNjgx6DVu#JJOqgz%8V5YwR>6O>6ngAiP_*7RM&40A!EOyX#)Noo<%q!&@}4-BiQ_-k$|re`&M}Pt%3S%i ztHL$miD=}|P$OM@@3Ug%W5wYUqt}WhUulu2PTE|q=Ht;>5rh43q9k^N#W&K7GWa8x z_dgVQ&k=QJ#E)kf(-q<8dyJbBPnlY@P-%ek0*+F$uadR$*xf`yrmMJ5!ATTE8uTwz z>JQPNR8a#SG>{}Cm9oE;Hn*w;hd92li_$`i?bs-q5I=ph^4cxH&4z z7cW^V$kfx1rRZS?|J&vy*$$AkpKux!$?8EjKe;Y7B;ZHg{1Xb3LM7ybZvHmHEC!JQ z3o#&ukiHo6#o5C*h}GG4~26m%n-)YD9h#jc%|`4QP|Px zpl6&GbU|cN%hu{o8Usnm6KO-$0g}V_4w&QQ^;X^(zL5AvdSmy)8PHt0fe}M=uo;KC z#@s#TOi`#ay-@YYLe#(W(>q1&{5ieI_fIVXqM4d4VXDuFegmiz@~C8B&?Oq?j|=DmYLMERM* zRu3qS)%}fYCO|c|)k#+RODF{K>6)~9_8p~0I(P#b!$OpzU!s7pF9XD%EMInOs4l3p zE~^BMS=Na}qL)q)UuwI!O%OGlGd#nyr~wky1U84rb)?0`H%2hX zsiEA2P+F(o{nG5TfoSUV1`k9hadj2WPa!Tpwzgq{9Ud6Hmm%ld>i<`eeJtzVtn+;xV&D!AVJar z$piby#~v<8sHJPgm4FDhaVn4|sM1R`d`Ao!BylB{ z+}&4FQM5r)Q64|}2GH;@9VhmJLi|7My$g6$)w%GWWCj=@vWJ@1^hhPGv5lRS#s=Ha zK|4FylkAZR#DWDYDs3!%%v z6)y`hTVZ!(NruAtAg)a_XV3ySvqrD2=b^9y4}}3-7FGmBjAyAxzKRsI^&*tz-v}NzW;sobY&_QW?9K=%aYfYsPE-sfF_h^NwNZ%na}#Mh;lS(I$K;S zEW5`;O3uEYySRLKnL&)L&qJB)VQZx&`T*H>=ekwi`47rNfI3TFg|W&Abay-RNrH2_ zD*r|#4(tcS>~KuESC}q*)y|O%HoKh*DVE+8zAFEQ7v=S1ybjrII4kL(=t%sGP_oC6 z?b>Z<`0_~Z%mDi~P(CvNum3~*EsV78`fn(dp<@KU$g3dop|9LelA2xY^_0)9*9qvL zWKpCat8@Z_jB``J3s{F6T*-)Z9TW+Ainc zbV6jP#1Baj-q*TuvbJZhvIp~2-rdeEWV3QtTQ|HWjKqAYt}SkMVR18sw_zjOA2NzdDjXY~;_&t5Bsw<9bt)gytMd z`U6SQt0(y#>eV_)9p0;7l5qN7)sh3modj<}WEPl%_HXF>*v?2Jw#U>y7o|IwP%+b8 z(I|aZ-i78I>fDz|lFm)$H!gQg@#2968>R)l&hIyAq6IHs6Tn(m-Z?4@J%w}L&xHQy z|BBS=`v>72H(SYX5n1Vv$tcIzuGGAM^J~&a46cg=RI4)Q&Ye8FBE^U+Z~#BnxTh;f zQp+>7#ri4ppTQr?XuuoRZt%w(c@;7>Gb;S=k>s7VUwj|t;TD(7#P&s>$Ui+gm_7HH zJnnWTQ)37%{PpG${m1_v*{4SfTPf;dJRM)}iXc&gwZTOs2BqXWU66yf5UABQ@n`cO zv4xkhTo+WQDtcl`{nyJcp@u6CIzQ7?aQ&I0!6|UQ^@fm!qptftP63LLdIdPvAeWsL zPfE{4mRo6JA=`hZB-S9ZMOLfnoxWCHRFjtVdLQ~Yi z)-+K&A9TL%_KFfElyCz(gBEK*6Tw5@kAiNa#sA@9qtS?ryTqWSnI zk{E+#OT>xLb99ND;(UF#a|3zWl0(|$6ffs}5Zy?DZ;&9C9P)ggWCBg|T$}@@$#8wH zTi*wps>b+hwJ#_j{@_Iwv(!q0Yr_)Cgd(+g8*JKiVbiyBp z5;}CkPUj(hU3{~X0j!qPp~GOOa~}yGVwQF(*{Ae3;}2QOs)&8S;A6FYI@I)0=PT40 zKI4<+{pRI2EOn8lOjI#RgPoUzvvmTUmqS|;#!022^Fxvj*O4ShgBMG+J8$yN3E~b| z3OuJ1o*imri_~DPJ#tUVJVKKE{*d3{>-zUnH#03#AW4F^u7W2b!_E)y=(xJ?Ldxhh z1&I)Lnn)D<1(W7!;tgi_Cyk}`D4d@!OQ)M!Z^r2Zw{E*Q8Pq16Yd0J4n)6j$QjQ(4kGSz_=@r90O&?` zaGNvAO!WHdicM6Db?4~+gJSw$KLuT?gAVgxe_`Zz*)-EX$!)G*Tng2s2IU{mIM@D& zO@F8(DBP1@)-3U+F+Q9ON1M_&=W1%naZbP)`%2T1Mk03yOZO&k;gs6t?2+V(fZ2G$ zOVtYP-|N&|H9II}e#sj&ACKZF{U^K~!krUmMV)RZU&qMDtCXV`zHQVHgsNq`f8n5ldIp1xBpI3JH#hb?3 zM0V41Dzy2e^xQNy7T#ebL|<%&yX5U%Be6zWP}^6(%xTxSVhr&@w;fNn5!?;(h#*{Q z2aaCt&~{C@#zWgN7viXC2VO7~x;{4>Pku2hgWff+CqCQt__`#b)kS+Eb1s9LJ;i$9Wi+tT`@^Tmi|h-*u{gF|B%x zaEVGHCUV|DQpVL@OO6?C`|gj`9?|oAggHs1ncjmuh(m3p+BKMj#!^$iU!BTbPnT~R zOQ<6wv0dge<-a2yZoO%2JiN_Fi2sDR%&r~&tC0{1BF*O(Vte_DH^bW#+mELS7kA;8 z)u=4OKNnpzk%v&bWfYA%izh;k@OVZskFn6+YC*;at3%Ma%=)nV)kd&5sBgP$@?)Pc zDPRN(hOjmvisXAvt937}^hm%mK#LSx?R#{4d9K!^f2e~&RSD9+B} z#Ib&aFXkfkW}I=tuOg%g?>15sAczP(__=S~CcPqVUhu-1JjOy2A@ZUs9^bWy`&lX3 z35g4MGuw=U)v2%hDKslJNfF}C54|E3I&lJtKo$!fQ|avm9UjWSY-16H9A6{(AWR%@s)9X zFoUf$>H=R)%HS)(Px1%eItq>x+;tRu^$Ihy$`*7bNbAG!RrzV~RTikKQsruN1#&7k zLtUnCTQt-O-qIKgY=yOzhpu*yL|4yfOeCH_H1#j!8QcJp3<>iCrCSycy&`xCG4g<% z5`lQ=XgoQ!u)4O-l_%S^<6^b`v#M*S;tKeyetg9I3kZnoEfV?w$ODIS-ieux_( zdvV`F{8d&je(sL3kT#1?EF47%Q(8$|+?*c^m_zcLd5LAzW% zV`j4(#JX*h`~J1T_jC-_vkd`o_bXA39^dw8GSIxO{(@LKlKX^6USlefYpo5)kJ%9k zh~2A+L2P4LT3gKu?}*nfJK)(6(byOE(i~%CK$`Yi z9c(cf(A>zTXF7z0$?7omhiDTEImnVdYAo()vdl(q?EW2ywXHADPL}7c4XpkY1XWf? zc|f|l$#~-Bvu|+o&m77hBl*(rP3DPKYb~g|9Q)-Q<52=2Lrs?FHXcdWPc~QgGOc5* zWDay$9>qpBP2!ne;!u0gGjWxClBOAUOl7O!`Iq7;DO&~1X|{jaC^I|I&+T(t(y$^% ziZB-1ux~k}wXv}RU;5Bmr&5-C#yw~94o9Rv8 zu5H=g7c~Fob&@#bxL(A~P_`AqQ5BYs(q)LCHYXTvHxhfOnsmQD&u@j>mtmt^6X=H! ztO=UheUKI6`uP4>a-uQ=s>@PiqnzUEazD&7w;N=o%t;Ulb(a!mIveV%ZWQi=`bTXL zeV_@*)PLq8(c#@_Y!J7cIxdpwYww@Z);kslcDX!jnCt&UTQ3B@n;8s*D4_?H+IIgytPl(wP`_>BWiQ@C_T%jICzhHKM zk}JhgOqZPRA}BEji>!Jb`=MOcw2sZZ4YX6#S0jQM9x{EAPk8M+bHK{fb(?cO?KS1S zp2cgXwJ~hUSQ1cj8?sYoA&|g!*W-xQw%TA{Km-17k`B#4j6@)#KLCPY>-Gk%BylG9 z0(?f3<^j+qoeYRyM)np9)X#E(@!a9S*qY4dFh~a5J~_rrWFP4;{Q^>(08sQ+^4(;% zhZav)2z#GQApzUdwWL2LpU=+L@PE28-rC3ym{3;6od$O)VT9Oz=Hr}YSR9+VULRe| zDZ5PO%M|DE#A{@YLT293ipY9^23T_U{51D`(#QRBGmsW{0uq~Io3j?Fn!aDpZdvx? z$Q2#5pLELky!rSP{@3^Rc9^M4UvoqgX+F+c4<$};*6KvRn<#ehJ7|-@U`t8I)AGJo zMrW~_EVEh6-&Fpl^JnoF=Wh;w_~^v#aME1DUmbr9fI}1Q@gtX0_>p^y{M_sQJmCKP z!u|OzKbaXg4ZH({0`ikIyzB8}!s7wDo3{!%*EZ+7B)e*gVK8o|V+5Ty3%zwRH^{1} zOTk`xvE=v~u|9Hc8detw%k7cI&#qJo?+4OfEGyl*8sqAFkBL{Zol^EldQ;-qsD`&Q z2R*vSXVgRlG`>sy=IYKgC>7ubao;f3Of_aT!ro_R#+?DFij?1u*S11EN0203_3~%} z9{XFlA&kG5w!%%%c*k(2_%lQOd!j@}hB@#a=cY|!YNjoYztjlz~$QC)<=F1f-elD8mX_z-!Eo}XdgKiod}{V9B3 zNQUP0^0O1^?3E$u#6;=D7rai$XFo0d_%*dgd{z>d40W#V`P1|R*zS|9oS6{tD=uld zQ$pawSRT}?$Zh%v>uQR(tFuw17xZ;%ad<4h?<@bp$Q2L&!dKkLsZ!tFL;BvM)Gn_Q=+wjO9Cl2c?-E&cQZ@Ejwq}q6)rm5}QnIQ?1xR+CO}W5X~i} zhq%CbmC(&Nb%9JIUZkyVSwJvTTyHt|OLOXWxm4xc-9Gydi0Bk@`} zY!W^`d=iegN++3wOS}vr4WYFvZ*SB>Of$+Eg0a+QH&T`7J{*zl{ zS{cT4y70$1Tw9DjDa3h2Jv;>Mtvgpdji19J@iReI=p%Y<*Q1}TE9%?(X(E66o@Dd4XtX)=9n zWzNr~xs=*Wu6$(@_|^Fzqyfz-C0GH-M%6jr$vde|Y(H+6-D$%ObD zTALWp|5OtHEFB5CM<=d!lL_(3)RB0N_XzJD32`4IPiWse65{wp#?z6=qh;B49f^GJ zX>CG08ZqceB3&JD267&+fYOEt*3hVBmstD^ZoXpye)L*??8Y5 z{`w4-FZIfEzAPU#i2gM`eOhv)R#ipq0GgEVOo!jtC zDJl~|Gnhf?`!=}H^z5B+cUw1J8*yRJaHaHhxAP#sS}c!;(E({wr04_AYDr$cc#$Wa zmy+v9QnRPV)o#>A+{|~ra|KX!VA{1)jdfy#ZSmcM{KnLKmU^I2rrZb;SfHV>2=|Ic za7Iw<3M1-Sk?lpW(=vh;j1CQvD3{PO&Cu#5v`iIR-L#Yx)J;u=jWmkJslwGb-N&0~ zoYwQ}+{S;&(djK6mHy?6zp>Cx-IyD`c51_|(ia(xmv+a5E1o}djFt}MIAR7p`6-#&dkX`M3p=XSn`H$u>L>ROm8_C> zd7V)WHd2J1pYiHVi0IS+kE6PH6jA3=5p^y=cKc*uFQwi^eHpKPOCn>J2tYc)s08nD zgPT7kNd5P2Pj@XeK0ja-9W*NYxnR{vhVwe>pt=E*8YJAZc$-PE)F#%CDPf`hAPcqE zN>#j1Wzgv^;~(3djU;03G#&6D4^PZpv^BGK(t~DdMs^e@CTl;>NE1f_#+pyd!$rS* zdvq4_@o`@0_DyBRTp0VR1;*S13yr0RvR1!5W>8#>UnhwEP#fZJtlCnM0+)WHn(a@t z2lxdow#jeJasFE{z<=`^kRem>n|pY%7xB=`L*yDB2q$=5`9h;C@+XoOI3(%%_%d~?Ep-c(MP5Xh^b!K_W0ae>gjAZBc63cQ`vtQ5W5|xz z#aIi<|AmAt3yozx^!WsByDxtIVj3&|oS8on!7bnz7J1xKLEyD}V`_hOxZAj0Ko!Cv z7HStx9wgl`6J7cO^j(&^x(upSE#Icw~EgMqRShpE~iLvwZV?LsuScUTd2BC-9M(gDlCt?o;DP1Im zuh!7z85X&Aj3koSv;yb7p^CQv``e%h>$f)<-a-d-dt;# zPD$r45!p!CZhrK_x=~rq0G5~ix2SfeZi{aV|F^>i@w3&pwZ9tw@Fbfjr(dXxxB6s; zrnARnhIO# z8=koI4z^WGp~Jh(e9=6X11p9Q#WMNg3wo%;Xi7-vi$Xj{W4LWcecSmV&YnB}h%XBZ z&F~?kZih&Qo&n5P}swfZybrI#d%NTuaFx`c~zxWp*9MchvdUJwIu zY+F}cV5%2G`!eeX%m|0H%UL#8y5zkqr-{@dk@qd>-rXBU|e;;T0|QrktupyA>4ran4t zz6g=x9iS4O#5LK7)efNe6o*}l4+}{V_ubIg-8>T|iNzV`qi$IRo8aOz{AejqQx zEh3@N4L*9G_ff(8USTmYzE@wfB=Q>jWW8?8jU!~KKDwZ{Q3OP82_+S0?UZ4um(@Pi zanIqEc5Lx6>3}8DDs)c|RhHSl_vHXxYWZ+97;cLivpTKh?Xn`|PRG5w-&Z*`+(t4k zL6W!sfs7~e+}tv915_h7-ibnzY?)@SUang&-kH4pPoxqVA(*^%Gfxub*{OI`27IeP z0OK{99)pNWJSEv#c-xn4l zI~e!%5u8xWz857Y;IbfJ#e@DQf|N42pssAd_u zrF}t}+GXVtCQCKTxV5paL~ysTYG{_BN{YC(q)ex3mSGN-Q8*pVqUt&sL z!f%Pz%WMsXuL~G0c??SUr=`M4EssN6xyyi)J@ABpgCLej8e?Zogs}c-py8MR2|V^` z4|R$5sn9D@HvFIf5?g5qS~Tz&Ezf`xgyxaOlW8i5Gi!E7RX&T7MX*qTQjS1;Yl3Gt zdyYe>zKvk&8R`|1wrgv#Wx7UAWZ1JXpx(h8udT7a6 zezvf9NEL)@WuTv}+I=TY#C*@GHNT)DE+*8P zhxNl$wMHCfQA@3n^+;AtkEJSnM2nCb<;s6S={DL?Yr1si9Fy7ZsIth*ig6R{>bQqa znC4#6(yf|Cj-zO@t*~RXbRLsgVy;~bBQ)vVl#_esYxzA1H)W0mY=LaT70A>&ufaZH zK>3u%k7D2L#WO6h)z=%KbJ?$A-SAFq@jEh6BFJ=I^T!sq%OGsuUz67r+dh1dPS&HS zoZ~&=EplMgO~stHlerjT->q8KOy`@nZ+rS>*8+#EKP?#riwMo{JYVBO*1j^x`rM0x zOFW0vkDImx>bSXucez%vzzPF&M(RD@6m%a1^ zrY^I>ZomG6wZBPicQ7Y6Tza4{N~Q!~$$VGFDhimylX|tXja%imu*}QH>A`V5FE&pS zod5^GeWNIw8Hmnpnmko!Ng;WXfy5bzJoo*PIrq{t1CfUGK>q#O_Xs+zJYB;Kq=8Hs zNG4l4w}>?9`ses&Q1|K@p7Qn65}qVTLb7rZPm}c1(mpvnWH>8Ti>{F=-ZWXlt0Y?{ zm&wme91b<bWuW(8R(UUH1z)awIx7D^0W;Dy-$-V(3|NQ_I0J;klsr&x9SNQ zv2gt}d$Y2d_8^o$6>w)$H9f(mU>Z7UQ}Uex8HgBdxtTtX4bQb(i8BnucSQ*b* z^tp7edIw6sXxd#;&RF+tAR10gQ>SXX{LGX8YBKz9400C+=PBKY?`TZjCEgfq-yR(C z&^YvT($Hn-YnC4>)2=Po>5b?8|?N#hD9> z^PFaJb_rY{p;3Po7Kf+<043K0qp4cNoZBs~;ZB#h<#f2rN-cuh!TLX*`mu02LVHrr zmERFPUicl`_ngb_cuvZbIZ@^7&+W+3+|CC1-@@0Q=0)H^&Co94aFBH9ME3F;#_M<$l==ZBK8*+Rc<%`?5dt z%A~2=9hw2T;7_WP2=W}@&5}aK+iu3Fa3{&hW_d-pC*OiY3`WCy8h(hDhdD@W&5MQ~ zbH{ZJGp1QB;mk|&BRQ_~)oq$3TO((b$FQxD)6C=0 z)(A(S);vQ>(q+qT6C!}_ue?gFSwga$E6hl)5mM0=btKow zdFhHYl52!qRC>LVYYOzUtP}y6V<+w5hH0(F%%-X-O1Jm@Sf;_8iq%c>(qc0li5RKbbOmLSD)$Sa-C&+w;G1$4|AOCr>+Wsd zFWcyOwo$jK5UkuSpF^KgH^vJ0m_{5c%tl$DG`FI@i@h*tM)ibGH2f56m@F<+s75&e zO|@1|J3{STLyA7Zl98o6${9!MBJAvzV6Ug_C1!H%YmykYml`QkuQrvEjlDWCvdBmY z)H5?BNO=mP*n1!?icYJUPG{`t;XOtQ69@7y!1OHhb%L9!4blPRU}}SIUTr6Ofu-Is zyI(VXo3TLkSNp!3drwrw{Gxq4jGSr;BQd*Q$ET?u6MYes`?lX>cE4;Me&6)HC4ybu zeL2`R!!jKQ7e>6%N!k|D-Y3mA5r-nSL$O_Kh0{j!MBTsbY7@BXah~byO#eMJuG^-Z z(Ios7UGC*a?d*O-51l@x&Xr(Y((vJ`=;yvitH#-LD5(=-7jUu%dG49 z(F#L}8BK~*o@}FOwQg&spR05-%I;&*afFQel>_aFsV2zym~+bt?T8u=ZSNjHIwxUo zcum@ctVEF+t|?nFjTI~e&)fNUI+(;mB+u8$V}U#d^&@9fyAO*^+i%~!FfrZCs=F@T z-v5-DrjV+EG6ZD%&O>$|Rci&-0G(cblq>oSZ8uZ?v2LL^Id3SWk+{-8GgQd8%`NjQ z%Fy&A=}zh1zKzGd+f@sboJ{RPlnxK@sO@05EIAB$472wj8hTcpp-jv-i#p6=Iz<4+ zv-$hSb1U;>mvyvb>R`MIg@#OuoazZtzks6ZMI`XQ;~K8XfHb9qndIxadf~b@yt_6AkZ+8gU>`14vZu1Iz^<;Zh~u zp20_()Wt3~>LTpi1F=L0cWk%vCsy1yF$>YMg8yaowDxr9N%()jjrd7`okrFK93rKr zg!2THH4IM=;^_a2#xl6@|6DZo&C{c?4EE_eD5xld%sk{K=K>*i1*i2r=H|=kq}n{Z zmdW>R>r0TWFEjpEP?z4|8T?fOPRih~^M~WFIv0Nl?)vN?zG^rtZ5Du4z+y&fopeqk zz(MS_X9V_&r~J5GHqov|0xKRS#;uFMYCaHweeXYsz~Uc_z)p_Op6?+r^T}+wZ8ZH& zI{yK9>YvCPfv32Cm_b#`PC-=}{_+1Se076|uTXV0dUVth9yMk4!6cQ6Kq5s7`j-QO zMc^NOL>ny;!A9PZDEO&i`G-K|Fv6>$l5(eoPN0`^nyd;(mNw+mI%he5;RrDEDHk6u z>F54Jd7V6v}Zn%*U-z7et$k6~9<4g`R*kehD7b zUsT*ic-L-wlVkE`7_%x!0wLjEHoM<2(PVbNc8`^uT4)|VA%cOW7)_-rpmH?9rW__w zC{Q8SwzAhw2s=w!M!A|H>lUdovirSCq^OJbFfcS1IyURq!@oh?sjM2#j1tu3;FrTi^NL_thEmo^nWGQ=Ip zek-(7s5(pK6?UJH+rFl66VrhtqsHpSv0SGRcvfha(0YB3YCQFyCi9HudMe_jtk6VE zf}}5h7?njZv)2Cp;mi`xnjW#3?GLvXG&ce#p2^@D&RiJq)0zxML>fJ4FSy`Bk%H`Y zmh*cWd%;U3dHLd{!|VmGB58!Z;60>W_n$Kx)ZF(_JW=ZZU;Dw( ze>3~Rn=Sy1PPQNXrknWx2m8T?@-y~>f182*;07!s|2x|cI-h4bzy_fYv>)6`iT`Hy zgQdDlp8epbdHFBe5AMh2WVrp{zljaXaQngSBxLLd*Gb_IwI6)E2)x-h<@U_|RD=kq zZ@6>VT95cQMu3(81>|z773PZGnOn2*<7DGBC8ygFzn7QzH#JU6*N-zdjPc5G#R?(A zqq)TOHM8YX@Hn{$NS(n7!;f^)UpD`I-QfL5v9h}~pIdZmk&IzEbAkvNjiH5Q-UVAuvbIHoj=({Vk_#W2BzoW-l+APnhC&jxH zRd-49mJ)8!t^J=!-ogcj83nUa{x8zf5?b0ItOx!xlgqdrB$uvGxNvXByTKzqo5ioXJ8V5Z z_dc3B^7wQrI;&H1>S~{4s1pV+ZAqMobvTn_7y(C!J{|~ht4GD%FMj#ZDVMrzwV5#F z;z!vv8Py){lJgGgdoYU}Q3)>X#RX|{c@K_dyW+`3NJ}wmTi$A_wnT4%Xq;;x$80?) zRA8#t+;iL--)kOf3m8qJ6_DsYzbM>5*QZ@uY^?hlT1fMWbPbZB)YqR-f17q~k+H6g zDT$^`LZZ9o!h`x|D_l`*q@JL%no%YYWvkf;v)UvU$U>`mPI*p!Imu{Vh9`Yq5i>-r zmIn)cf zzMJjxk6i8|Tu(}@Wz6tE-Pm-erJfBB)Q>hbpI^&H zYH|-{r!X}IjJ+1m1{HXl_penIWy}Y9_)IDSr##f}JDew34XFJ{x+BwhsJ!r#x_?H? zbSa;l3ct)|&at^6|-$E@BS638ZJ4iHj2#m)gG|Kx_dN?*x64B>}2%Q zcI^zd&g=rc;BB$m!=|r;nA4B3@Xbrgi2#6IGuEyV0T8kVlkanreJ3R+^*0uwbilxU zM1^mYb1HOvuGNK(9gN~s=rG82p<@(JaiBv+3v`TcWAw&Dov~Ej!!or3DR%9)IDV9X zlPu;?3rCOOT-iw7&6m0ES0)<72<)+MD;|L=JpE_*mf{tbU0YEWhIMNxY^9-UwN*oa z+^I`V#jxx-`~zAnLjNeInn|T}QM!Y|@{Q`$)bE+$_ZuG5%PdTibkRb!CQW7fre+sK zQ#SXw>46ETgpV36YcvlzyR7tptY*r87v)hY;IpN+6Qe8rD%)9)Ej9gil0g}nB~SDo zuTD*xfyPDF-U_!GEoTa_bm*_TU$;~K33?>4)btAA8s%KI$mfZd!j#A`NX*PC$zIvK zhZ*)7nGHlbj zk2G*|&7D#g8oV#c^@oNZ;4ac;r=e^Y6+V{C*Ay<7-Zn~0*c`9bzi#NJj7e?XlvBZW z-cuTEof_}g_I@M$W=wB~pHEypz+dFBqu1E@ciJC6j)?mXZ_1MG+Wc>P+-!R}5UXv& zGeCEIe3u;997%XoO^v$nm!s+8u9)$(KgUjet&rKqCglej18;j$d-}eFb)WJ%Mq)hO zC6HZ7AwP|{X!^I3!>zBUdz^bH4@#>!ysxxJbsH9sW)iC6Ms3}sAFF&5%i0I*y zh8&@wkR@V?!~}Y$ua`Tnzjp-r;oiTN@iOR4(AT)SJis+^%h>o4{F5W+5wDmDbU|_B zX<&Xkiu%G!QvS{uH!zt6CqQ3uO(T6h@cUExDqY1Td{vp#tH;Cv?{%h{jt^1_5D5|| z>VxSY>5g87?*>rPu734#ZBu;|AXz{=ecXC~p67X4^^wdH-9NNM#-lsz@mwexb??8i zFsurfvt}~kxoqHdG6?3{DWUTmnzAr=g-AN>!ko=Kcngzt>R^X0%sUj^;I7G-4eqF9a|^Y>W=^qJ*dE-($|yE!OiPJx`Si;Q(E!J&inN$CL$?cDR})1=2d zb^2hw?C+Rh?CFuHvC$tfRqJ`OAuh@aV$3)j$}mvc8f}7_>N4))&RpvR^W5&35hc{N ze@mfEw2vv*z6+ez$LZ;WX39S6_R%z=e^Bj*dpI3q=ueZQ7g}Q{^TncgYPv>Rz<|F> zP~gbVe*N^H)dZ|veCiC@baGi|%|Glqo-SEHj>-K-}>ztDA z{g4GQZ7t+CH?qiCax?93@4E~sm>FmsJS^Mfu!J~k>&>z6<}T!I8pJ$^txowPkb|6* z8g?y+#g-K9^yjEOr3b{!O^#NRAQZJ*IL6lqjA^nfB??xLKKPJzxa{;$@BzSA@t7>Z zhd`g10Y7G8EB*OFcv*2nqqY|lR@@!Adr!}1m&wUlAQ-nuu<>%S@9j~_n@So)crirytbnmG3Q62* zuI?2i-HdBUi+wg6QHcG4>H<#;B8fe$)9E(qkA637tLUK$mN50+9)>I2?OL4^e$i<8 z9J40lS^(*fJs{M)*aMo0El~3^kzppXls{-7BhNq=b7#|VSx#M?FmhzZs^-Py{1X{@l^o1*9-B{%6YIfP+{;-n2&>>HCs7yR+ zTWYJ^U0x4+QLXy9FI_tuvU?e>(f-USGEr=EH%>3-L@19m5xQFL1|05iDMC@N!VyG_ zM|b01EGAUn-7eAb8TzV;4)MhYB^dK4!Hth-f@20cn!|f!?6D=In*gI zSAUDA3Y#ebF^*7S*Oxa+WSW=j~)`Y1T(Aj z@u4BD{N%|)5?aV3*|Qmvw@`09{2v<9Zfcw|BzK{>r^H2dy*g8?PP;UxAIp>XedzL3 z(=nE3F3a;s!O3G8wmcWgK;7l}JE{OwvNCWW1I)JiqhYxTW-_;lA?x+Y88(>Fq!a;p z0*x~7F>tS#T$d06T^x-_V_Z=X;-Mgl{W7~%iXq_4z^_|Qh zU^pKW@?&}e?zUWnKB?EGXHR8Cq>OOsWh_gjNFwyIq{z*H*lM0-`PelhKn#9kqMf>| zkQsFuL3gjT{z@;#B`n5ylZO@~>M?@uM)^0%aaUqJuVgB zoQn1ceKx3^_!UunZ%Gib8sZFT5v0UZ=)_{ZbI+0Sovb6CCWO zS2K&lM~qaEXR(Vw#F#6z%Rt>IF1W)ExgDx3Qk`*iW59T5x9Qty*Y4qZkD3V$Q+S7( z2@T_=k|s3FrN+iNm*yzEc?5Mpgt`*Iw-u=NNpiSuP>yjC@w?-U-vOHr76@gnnJC2{p(|szn78Q z>N>fFf#rus6IHrYDzs~5nVU*DD^_^AZES=nI+;X;9IdM~54Xy3UVjmr&UyNEy>jQu z^CLWC?7~9k9NuRp4Y?ClS!SnZE5d(I3-1#OlSjq@!lRF28-KJ`_| zrz3IojX+441XPO>x39?gi5`y8Bo^ms9VH{;yRraJN#;gUvYg!@m}qKNF}TC={1XWYhM?{~egu`+ zthW4?49N>slq+oC2_&3R;ht3!O}y)^7#}&bHM?#UfeHG3L?s{|yX(=SMu4gIvViSl z#L=LRHh=@bIHBr)@EU9+G#dSty|XuYXJI4XG^bsbYplzso*2O=Udvgy9y|3YI)^HW zh>$O#5Ux+n&bHL9D56#H@KelC|79fcqCYT>Gr~FiE~#IkTYU3Ibr%g;uU^D?qQB{KK3^t!R=GD`L(*sBTWbD=SbI!oGX3_VwI;sUzgg^ zgk!TIq}vfoWc2e+0)ul3SxV8LveMkCsZ5ttF(WT_+RcGZ)ak}y-! za!3OnAOUz5=-n^=YJQ<5s+`pYfDD>27AhR&5EdgXDa3YnmsF_y2%uSGUImXdg24qp zRC6B0lC$wfJOkHSFuShjGgZz4^@MWb>MfeL5ZP%&F@0Kj&{(&N(GcCJxAYKbf>WTD zQ(##qCqb+5N%j!DRIBC6t$!Q-_dM=QWYnpz{u@%ZlAE#Z@#vUVB*)eTj(QB&|o&rk=(`ZEddwX8rH^a6Ni@VbHP`er4+yIVfDeRT;CS@Gm1FG}zJ`R@{ z#&2U|91yWYe|G(j7%ptEA+LV~`i#@yUR_0;RrF9*=r@@%ySAawVslQy>&;=y2mhS7 zB`-Tx3x_jxtk(^b!Kd#=4tLNx1eiT<;P_5pLksIRw zBivHSiH8nV`wn{j_fNo&mj9km`<{WMdE8F?CA zw<^5eHrX>U$uRQ#T>+FPJucy03=7-0&xtw zmT;jWCUREk2Ti7ImfU&zcBXrk8s{^Dk-8ZB;O5NiR=qW?aIevFB^ys9Z%e_IM!qwJ z27%eBTy!kah#=kWq5}30et-Fb_^~<$RVT+rx{VtXg&K{71&y?{N`_T9UEl9s%a_@{ zxC#aVnc-;AXjw(RxYCiV_#iIy*csCABVBOhgYxTn8@zG^dX)R^b@|(~;K5ex*p0p9&NAi<3!MPIA4E!qRtQ*Vk z2uG~xx@t~cGFtHDJkJF==zImXY2{%N}E#ivv) zKDp}IBdSX4V_lBG>BpEwGZszm^_^MV=IX?#U}x!m->#waMnnqAzuLv1&711SrJ*l7 z6UY1wuS5K}))l;YG5{gq?`n76{3!&{F~8CD8JUM}Pb0a9+vbC27@H|Vj@l)@mmlNB z0?q1m@m7QW9Vp$8HFhYP`W7PF7o*|#jFh<07cpE-G_^8YOf50v3-=hQhe+3xdZrnE zp>A}#Gu%@ja7`@weNhgx<^y$SK$MdBIDLZm1rf58kjr9f5fM4P=GI%u^o%M*#*3*1 z*Y+{U7&Nu0@=PsU%Mc+hk(=&D7_otx7Lw^AeIg2Xlo?VQ8pH)LbiZc!Pex0n9CHj~ zj^|DeC>6lc&^K6%d(>_%V9=DyulJ!W$jBV$xKiBjkmPBIF?@F=?_iBazAk7-HYyu& zJwK2tSE67%NxzthH&>wbw%o$jIz~%E&i0wB-xU6jyUUH#CjgNp%Eskc^_OoD4q;() zm(i@}-PHnPBj(AI%5ES1K{`fLW!sp!}bdFA7Oh^hPX{6HFROhtyPj+sWDo=MICn)W9=F_t1 ziM5|^=c=I03kC{9ib+k@VG$$vMVNb0!VdcfzOmNY1sc~#{6sO`0!<(Bf^*J zJBi{IR#s8XEe^M@SZ)dp{;|}|bhxc3{en%=WCdbs@>MwImCMb z{T2CKQzC7dq9Ggb2e5@*bk!GPL$upjB;Pe2z0;LOZbJ0ETDs9lvM2qyBlgj6|QLwg0aM69W>B$vi|Ah zB*x>~-;IEmMH*fN?LdBwgcq3`;H6siMd7D4xJ+`vrQl?6kx?zoz{_@CPJtH@#>+z8 ztutMEPs5F8fA*h*ok&z|7hw@*OdkL&#-pwU)LJ-f07r97V)jxbM`D4qK=w$^OesTrO*g>ua)c3`BH{zuLI_WTI!cBrn-RAbaZL2&?L+n*KrL7HPw6RHju6j-^rXG-{^AO7@sV&%UN9l9Ub$ls` zR7T3|c9xEpZNO+ev5YpuV28`TJUzDa;Mb+EY@!Z%nkjKWDo{l%n&P;61&-%(#FDr+ zxH-W8$wi$A!i@8mK4{E6M7#hBiuV9x-S=fm6UT7JEGR5-(K-Kvdle03lGQk4lB)vNT(Ay}vOb4w%c%(Hw=<2ua>5?-${AnM8ToXNTJwy5))gBu=1q zdt7#r7d3EM4}Op34adiO?b_|twVPt$&J~m62tgrlk{UDUyT!BGk;{XC$ZmLDt{k6( zEGTg_d*wv8KjxmJusbBI`dez=F$8b>QAfoQ^~eZKIsRQyQq#ShJFX~6OOkdwul!i2 zh$JaB7eUf)r^`*r2$FU?8%c<%yh6#WWhpty17HJ4T9^sZ-PRauKMU1~G2{6lDSUH3 zseP6wdPSx-M{PN`gWq}Rya(x3@$FGm&5{QRp@$<>X%EgfE8Mff5Mk4}$e}ISb^b@P z`*VmZwHwip_C{QaH{$vwVw=`W;drV=v%XxtSt3gQT~7Ub=`=M9>TK!jKQh?rvoVwpK=9NE`u%=4)SS8AV+@O4lp{Lb!k`e zJeKh|KqgUr8}M7iK$-sn=bkaZT0`L+(#7t%sZa#vJVy#B7%8Y5%ed>$ZQj3XvYwno z>v1MybaQ&uSct|cl6k(KlyhZh_ulQ@rLX9)rsUF)c$1Y$l*j(@I+dra(ru-OkUVL@ z(?M78q_E?u`y3G>&Ue4#`1#I9anQaZsM{YW?Jv2L=|M2G+xZ9!&hI-F#>BcQe&=WR zq|-k4Qw(NaRz=c3rA`;zM~=-^fKQ1}=o`j`9NPA-jsH zR=gxb*e{qi7wOs~el3P~*sRHGdy%vClpb*W2oPKEd%*@~Tt6&;yOrPM7{vlRnxI*e&5Tt31(Al#dwsyR=iCsxOY?f*2IDfh?pL z!OEaSS~R}i>ipmv+3>xt@=$X9?-<3M_kdwUxVGrrW+PSH0QP22dW%oJ`mutup?-_EbD#ry_h23~Bx?OW!Jdk0ms(oE?-wScyE-jOLv`@B1#4DhZ7>BMO-6TAP?-$+)a~# z`wC^9AH+dCU~Zj{?~gX_O;9WY;o21aV^pT@5-?_=I68MHiDFAC!q)jnzWy0G8vT?l zj9Q*;*-GcC)$8824$HP~iAW*w51pB`cD#*)UjTi&k3X#5%a zN5r6t*S3-KwP#PH6Gum{%u8KzG=?9aMDMC{rE&1>H@uDD#=x(-{>MJ3 z{=*~c|N7MW!~0j#bZY-R`2&ZFFnuM$-DRV(lk36-66XG|_0uwxdfg;)m;35JsyU(<67*J-EVp0vQr z`O%9xKv<8X&Vfac1AsB=SWVrw3OJYUBv;09)$m{hz{be+DuB)hNj;v=JaOPUTfc^2 zmWy%V4PlF!9XHt1COhf9CFgm0$>q4;b8Xy*gPiPDBqQ`+kK`mvxaD#7gu}-qT&?6P;FtGEE4dSZWpYsYASus^j6R_v*f>#)PW|>aO6_`3~7w za=l=;z3R7pR|mAD`q^*Fgv=;%p5Z}Nc>MGxDxLE zkH%CkV;;3Kn2E;q+ezH4f9NgHz{(}u^BJf=!&X<#M`OR7=q>#viH+0qpkeFJwAD|F zd9u{47C(}g7gbwgh+9Kgl|5%cf(nHKG8afFaVGVja6QxrdcU0)j_c+hxh0(4d{5H9 zM7qe7d_?Tt?Mx$;?)&RL(HKtG=QiGw{r&pUc$du~d|m2{SB+6w&KJSYay}fSAqfsP z7Ec&vXeYN(rTg_0)y(;!9d`1n`Pnm<_w9q4%k=;6)UDF}5CEsgk*$Z(_b5fo&uU*%F5g=Mi+eTjfb4VFm}abzQ4wP=ukimNHA^1Zn4EfH=k z2v@#sG#vy>sLFwGo$Dn(#2XpSZ3Ql62HZyiEVy@Uvfn-H--{rKUE5#`ZyS+`<*#RBlkN=^Lj*3DkNLDrDmY;j0vLa(XqF0oUI8ROl3@Qq_^Dw)ld2jt_ zD>XB_|LoKatRIn*Umj)qW(0^FHqFefFHr9Y;!wA0Qh4!BIq^7=18ndejzyE|T7(1c z*(Fn6VAq~N`8aBXKSJ*I1=JRtdFF-UU(V$^94~?o{g?@;OyGUp4_dq;h$GxrYvZ&Uxp;)j#JG zTT_4het{})_n&pz-P7-jt9SKw>E&DQcDa&T7)BJWXTFZ341CXMk_cP8aji8vU^KY| z4CJ6#7Nm;VNw4Fq=Q{xmRhZd4(U<*=){uYNY6W4HaAs4SWi*LXe>Io0;_3jK3#c1otr};7+Xx_H!`-~14k^!PgCCr?=JQ{*Tg2}S=G8~cX z0X)o~0FR`E?feyIWQzAaNI!+Dm8Fe_{zix?JM0FuB3LkSgRH2qBD#%Kd(3-QI9 z#M!o3gUlEB=1wNs6QNWG=q#AhcJED= z_G0$GbTD3vpJ8Hl+P+;gQvPII-637&V(=Q#_Kv~dLAtenaa`R~L$Z{JDr?PqRblJg zKts7OIFV?mGi|X<{8v+zjGqgBT`h$xlU4yH3Y+slfGiiQP_ckPjFvo<{h##HaIkSj zFsp8~$`Nk`T$9cQBgIp*(!S1Q4vz9K31pZ1(@be?2Wt`c4LENTW>b#vn>7rwZeTl` zK%{!kRJ4KU&N8cl|CY*fhwseR3%%}KDoEBmLHRQK!q-K_OSL5{_Z4h%1M$UsWJ+SS zo1-8nR!+K%KSVYisj4N%8`fBcIAcMzY8odARmu4Qe0Dc^*!Nk1n%7a|txn4l)dixV z6KKeYdM>XpNka3TezOSuD&*Z+@j-tSnn2d{CRDO_)6kV|{j|bp>%(7GLbhm(X|#)XefNc|Pw@xnEz&h}2z)%|ZH(EWcW9bK;&ysNlvG-1R?$ zvnic!y~lWTudlsrAYiUFKcL8YX|bo#Rj83}txkPoG^Iz$UV>tEx%iBnSvF%$GhSxz zq$i-%=(H7(G-4Ztr0xpamuB4UNEFi@e9CwicwHZ0S`9;H6_F;J;a_p*UaS7Q_pSO81whXQ(9?!>>V( zR7{(HaY?-~gZ^nU@TZqSspLugSvdly&DoMAn(-yfmJGc_k$`lm>3VYAs-Kq$?xn2x z_?rNo{zOHGb#XB-S<-BgGm|z4YwH5ekH(T&JLh7~Tv|oAvn9*ID{*+wiY3g=#RNR{ z-z5#ieeE+-{zlWc+>gme0zc22l_dJ<{_pC2@4ZRMcZuMVc$W5n3vTMZBD&Zy^{Cj$&8yY6BNCdMoSvIy~@}yp(?&VJ-eeKBwuvrAU~HIpDVvwdo_e+ifI7#U zkMJe=D?TC?Je;HMQuOW9pyM(h(GY<-+U1CqvqvO_G9g0>5=|ct7ujg~P>X^X^#{pR z76&B|pvx4B4PH#WgroFo^{oa|eJ87W@m8Vvs(roE&OCEky?^Cc=oVfqeJxiOIg9Ed zyp*Vq+}TslI$yv*LPK&~)IE@q&yg*M)NA}=Yql-%z7Mn>G45=YXtK1nU|PJ;GS)57 z%{-u|C6@YXk!HX%_*^p#FyF|YHNIgkh1HNt`cJw9v)V0t$Wk3-iB^ujSdeDJJyr9xz6^zC||o-f35y5FL^FZl%KDU zBACvqsF;D)h>H+G6zL8DWZPc7MR!*w!49MN<^DM^l5Ugf49gs*USeRHQSIA7&eQU} z%mV8s1ZT-Om>k(FKY---K3_`EQnji70wIT6Wz4BjYft!Hw$WB&oomOrbe_!&%Q9a< zRhRNQnMdIhvNSUPgJ0V&Yr~r?4Bdxids553WwwADas&(UR^WVUJs(>97k6Q_Rn|^t z=0Ca2LK&kKlqH#BKjQG~(l@jq+i6;~$h|Ognw67znP>WT%aX;_7Cwf+r{Sd4dW{4vyxo$K2$1cd8&CvTw z=uT!m^~<0LRm*3!{Z#3G1iswIaE|;@WJq=SdcSy-*6#Es=VhHUOyu2OG{h2&aBL}6<(~pRMn#oHH_|UDl`n;@BQi`m<*IAP#3#p&3 zg@RsZ&62Fv^W0Q-NP0Xc`D3wbF-O$K!X{RU+V+O^vf zL53CpNsE06GMNG_OX|mq2h;NGzNJ$BXij~A%6+x^Wz?#PiT3y1aF2=Yxqa0-wQyBl zqW!430n#pO_4Zz%u5T(CtB*cFg5>QtHw1NFBWy-rK6x3v&rtvA{o^$ha{hX;m|u%O zy1L2Qd=6)EdCq=GO;$`Ix&EWFuI(f+-Gd_ls)hrW2cfpu!)5G=YB-PvZHh7h=kMm5 zVmpLgQLOf_a+k|EKe9Hiug84X!kwGmu!LN&)t}>wpNq@>Sp1xvP_~K$V#GcG+t0I; zCI;@B@Gyz;S<`^q!RgL9mxxV8v{(*uI?FLQv#MQ60cvLOTtM&5L6OZdt;$L5Az>|e~mBYAuTvxIAREmoM5tP+#=BV z@U%SA-uBX@j3%XWG!q^3ZL@p>=AqHqb;SB!-2nDTHl4pzla(_Tm@1p9@A20EcO7oB zLEnTe?`X=Aba_Q7tM9_BZWp41P$FMKlUb`#@RGuLV)pe5eLRZwrwmDqn5PO8xO%f2 zH@8C@08X{=sc5u35AFghOF_sOLHA<(Dwtdpp@PY|y^C`;F4&8NpzY-x=lbaafn8d_ zv3RFOxyd`T1<`V4s)Fq>P|czu`bId+%FW}_8g9b{l#4v#b2nGo1RUV!P-FbT+48m& z*^U0I|1TVU$K-&lKSyc<7S0iWmbsDsA%(088So8z(k^eQpHL) zO0imHWujEM1Shl%hq3gw)vn#8m*3W1ZMDDcdh0DANWw)0V->V2R$EURwGl1EOP&Aw z^PHI^sBP{4zkhgT&NWll9I}?| zpt+x=xdw`@n*Gb-*4hJZPZ3|8!&jUD1H9D?I`46!9sQ~AHz~bOI7i3e(8fW2TDCt-=mKa%Rf4efh@OVZTe{AkktBg+Zgu1+OoraYKDGnq(gbshE>V_ggG1n)mvk=5wh!!@wZ(>OX%eOE6zznxAag1iBP zc#U+fhfN>o;qNdeYIYXQjHGVT!Mk5ItvJ725ly4DaX-?|+Cr=ndl4Z9*@sqN8h38d zI>glQ8qP*R<{6)qT1BHm?jM!`{R`sGoN`$Ib^(&X(N44%w@O=Dw8|kreQcJ=OqF{z zHP?6cUjW*1v!5d?+=+pjZG1&^^@p@yxG}ymgAXp6Vcq&ViLxgeLq`%!#$*nn27Or< zLm?Yvl|(mW_GgVHHaO)Xdcz54Y301u=;_t=Rr|H{Slg$gJz8=`d1Gqz=~V>;T}_t! ziXlU`@><`^9M}B|K`qeO_dBN-{`T~M*|_@-!pxq|BJ{|s%nFPj&cIUX4AaxT-_o&Z zna^h%eb<~GjH2sl@+D6%Cv1G*d-JGgNj{lQvVWXkPt;_~3|3<=eJq<1p5{T74XKclZNxwf@ z`>ZrGwtRCugyMsfUUOwrrleA0#c3n_KHN}kBU0FVx@&zApPGk7*;$jE@{JMSuR~9* z@jFiq6o;O)=0AyK;Pff*-0{|(XxY-`8>yaBSN}o|76u!64T<^=a6H^_)u9C?*5;cT z;{K=dZQrRe{yW>gcDU_YeSfq40E>U4HMQr4F>hFlcMSO7V5z@hP1*ZVJ9Xzr=+r;a zDFrVT5u?$LV~;h-J$5=SV+n{GmZw2*u&L{rK!cx*Qo}>`zhn>!U^tLgkT()KpVj** zHVh&EI@uboaPOU+Tg4G;Nhj-Q@K5hYR42Xn9`OXS52!5oKv}x9bIW!NH#ox8j?#Nb z)pgP+f3ZpK+;g=#>~?4C3h6YO`^A0**sk>CyPU$7Gh4<~L8evMWxVbuZ@>E=v?Jln z$FRDhkEE#M1KDy$S_!#l=&UrZbzB2nF+0OSdY+Q1+%J&PY4js5y~oE&UMRiRIiQBT znV(FDw$P)zq!vC^K4?o5IY)^t_*rlYT*U^{5G=m2ieST8;g(Y{26MBpwX9gh%b1gx z<)=|G$3M$!Omvo7M{A<9)T}D^g+DWx^&CA3TNrCtJqyD_iO=B!*a#O7pQo6dRZf`; za~0B<Hh5dA`VRbz71n|B#n@ead|Qr$xGem$4>I`RVj*&RSXl^RlO~;k+P|B1c}wv z=tAKJmPo&Oul6UIAWy>X7)8}pzZM^naFz#}!D?vy_|ms6zlbHX)WF7>>Y1#t>Hr6} zK)Sd+=Vh~pBC>Y0?S`KkIhfUP(A2jE<Up!i$kF}7X#%C9je6r79H#cii`v&GAg<<2 z+@H%R>OORNaCK%NkZ%Ii(hPGrG5hJ9X#|vJJ9Xbi1+OfEyA_O(M}B(}QQ?~9Xq)Js z&gg8$i=C8Japy?0^Sq&F5=5wmSn*dCB#R?Xc3>iuh`-Vh*PN*Pa+6c;k2(_|Rs5_Y z4D7svXmsx1+l=xRKo=G>iNQ*eh6a0}-@`MsAGYv#y6q(Lzk=oaE80u0w{ztPx56c^!k`st( zQ%hTX_{HsoK7-&(_@@w#sy0edj1q+NS3Sbx1aNuzMj|+^sm|fsh(o;F3;ne{&HSck zzYFPM`oK4rm)?pq00h{-LdG=LP#h$qCNGYF-3A#z$}8=^xg< zu7eXq8qI!pxQPcxH4%G!Z!=@PEGNo$jp%|^q6?(R065~Q?b9N^QmcfQRxvrtJwNdy zX8r%bQ@rP7*Wyf)|0vqoBi3`2`)C4P1ibB8^gyc@z(CCUtVkC3<;z7~quFL{t(_Nl zvLp1A-D(ueOcOY|B%j?`I94D)2~(bd1sR8JNwIsjVmNVlLXXFOTozo7y?3Iz++B`x znb6V*E~Tf0NBq`fLc6=&`CYntf^LZd@poJYrQ1>6PM=e&Dht|9Os%RaXd}AC9(UWh z8V3*WnBf`tN3Anan#7}EC}s02lRBB#?Qt8=eE;VkAFj$7%;(HyQ{`iOnvDO6j7sG> zt(Jf0Nd|_yl4j@OsB=DT+m98U$ZIII#d@P4AT3m^1UurCRC5jMg`XQFTD>Aa>Og)q z!roQx&tEoOCjkDogSoOfff+%4pzU(^G32n|y(Qp1Q$I9b#~(&$yc|mOc+&bejaoNY zu=aG+3n04=8leGbE@$CSnB;zYN+FU4;^JOfgXTE6`ge|w^%XY%i^_cV12J+^S@buO zooC{$h&o(h>`eB1J5pp4K056bq<^+=F(ej}fz-_s#ayLHAm~>8PTW9pF_~HkxN`NV zfGeIeK^{LhmM45&3b_L5z_ubp6KSx)fDdyg!pjP z6PY%|3?NPD3w!|U4}(O;KysX0pM@U0td8*r)rin7cGpZ7R3t*^tMqs+kK|xcl0!iq zP)tHJHrKh)T8$n@Y(0$L{mO#XKLqkT9OyMiaayZH${QI@uHE^za_%l0{RKJVq9*Rx z$b1BwEvrwuI=2jSC)bD`d3V;$n_-YIFK{R&lAMqh8r1S854=!Smo(9SIBs0 zd5)e&VM4W?t|7+6Z&L)>o~c`uFh=K31ux;~3+SPH=0{3M*4na{VOl?T4V zHo-AKiCVW-kfS;CIUIDZ3wra9cVKnYIl}nIOdOq`Qo8N@aTGjXuKBAq6E@!c#XqRU zt9c~N%;|XdKXYj{PP8`Y9AV3@6~Q^z?3c)^YAbE01pceP$h~&5c$+3A(#0Fp`7tQqHsh{<|K^;W*ksX)al333EYD+EKU(9)K>7g4C4z7fnZ z&#ZnorUVCRbb3VqtkF&hp6NRBW*g^g8TTkKh;S~#Ww82N!W?jc*5p+Wa2P#d>l0V) z_ozPwRPSo`EnW>hvC58O@{LlDL0}b0&q4IW zx%cuO8lo%kGUvVXdq1GqSS~TrJ5O=y{Ke03dzwo!*E3(@DtschouGAA-%VrNimjU6 z1J}xkE>b&((-A)tjBq-1r1m)Lp1s6*r0L0RA?jMF7UJW=gw zdDp7hCOL*Rwd;nDar1<}2@aH4Q~PfiYa%BMM$}=5k2o=N6y#?!XS9jO1dt*PNCt1c z3nh_!HWs|#ho$B2JnVh|g1f6_A}W46Y_4}3evy6+@U&@%2xwJ&#?#7{ zgL-hpDt#*$&aJ;WmCepw9$#=RsG(of|5jc*B|bt?WZ57+Zy;aS?ML2{swa z2HKzP^+k{O-+pBE@%~6UIu+8Ekv6Xayz)=D{m9G-dI1Rw2%cYwF@@%5R5l|!)+bEb zHo;O};P&6ApDZOJ6ZHNb8Z*zGU4xX^i2%4Oi2g*>JCsK>XC;=LAg4 z7Sp?SenAN3Q=_#n#+~HU^6V}{hsy|b;R9r0SUg9lSSC>o9kEl)*3!Nn-&0J(lD@Yi z>GE?U&cdnw>@MF^dR%xeu_+c#4U9aqau!Z48F?<*@Qjf$;$csx&aI4eEGkHH0R0vz zB4SSEz_`dmQZXP0j5vNuCsbzi+(6%u4$|DMEf)F4xqk0?SKn{5*jFv7o)YyTpj(LW zqi@I*A0gZ#G;kHqWQ$P~3n+SSi82V2^F1*nbbvYEb#kLm$}vlIZ*oLx#K)lby`5e_Z*#*vu!vZUP7mg2sL><)U^2SY(@a>$dYV$4 zo?JOV)wXCY{L(%Z@n$5`;uR%RTrceyxUeBcm6zpe+Y)babG8fg%1zX zdP1W?iI*2R6Ckd$BCd}_9bYJM@AM#l4mGC9p;VW<HzT1w5}pQTrXvC$ z;yByHUIk%IFPzSTpZ9Jo)D;8&%K~hgZ(D>F)c0EjS?YU-I8@Ff2FPmx?8NjE!EtXo zIz1T4L|KZyF13$iSy>jfSZyzmMB0^w#`9m{VN({#IpcwZEsrsf0 zVrF`!M?juwxQxW~9C>*XkIusB<$M)%KYPZ=gR)e)^GVTN4MR`yreqCsKI&3bhK6IES=dmMbH_eDW!H7Bj>4cVL%xuC8vp;7178u~9%2=j^z<<;I4;EEHU+lH!Z}V0# z?|6VEFBnB{PR}xfh?#;BZ^1} z+-Pln4DV1$sB!{4IRprG!=$EIbw0BLdaus2^H#>Q^r>M2m@n z7d;1iMft1j^VZ2fl8Uc^&6+M^KqO!fefXct8;GSQR}%l-4T7&gDHk6SfQE1U?% zTb#Qhv%MPrO6K)MpRA#1*shBp3@X443a2C&tK|oYBQp9dJEP7QU6kiHo6+;hdmVdu z{sOZbqJ@-k2Y5rQ+rsL~^POlR9NRPcWQJCne@?@aBE-%Y@=bHbu1okJ0b!&)egH%J zqG0__Mb#@RPnT3{dHDDep3l$|&CX;aDc3wAwwogFd#p$G+0Pgc>{xGL`xud5%*W`s za-OrKP{%yCjcrOVESxq_+~jbh(q%;lm0#8EO-~38k`^m0IPu2QSHJnzaq9h@#R747{AOqYu8Q3B|koJ42T#y z?e}=NeugM2Q+HpF1Rc%!llW7my2~*?i>F>IZ2J)+yuxXSLDZ+5ixX2Mg9gEvG;&>O z|3KSBy9fI~QVROjS}c$YgY#O+8gJbuOL~Ux+pn{v1 zyS$l?r?%HI`--SOp0A~(^m}F#)dq$P#LNi^kT&lGXHZH&TV$2W3oE{&$CoQvP&hjz zxZHf5J_Y1+oHus{pd%pwfAiS}_Yed|%+X@;TuXCYw#Pz=)0XIDRJ7zhd%}uTz5bO| z#hSX}`{s=)uXb) z4i-tb771cqX~efds}KUQ6V386>yo`0f0(^j!9e|K{U*}H8ihN8+W9nV>(jf?;&$pq zG>uK#AWvPqPtShSdq0KSAro}=Ur<7`1+9vqyxx2Xo0egLo1Mqh_A2eW^iHG%aKs>( z=_gLe8NmW)2Qyc0-8u&}lyIKc7}<$htN}3y$8;^>;1`I{&%zrm6&v2A@8hhN7*+moLVWOvIe9Vq%UEH->#hFB*s-X)h2>9jZVqQ%^O~7 zJC0D6wOs^(g{Z3UY)nUk)12OcQx!vNU+rF~gw+=BeS5Wq7g+XQ9Kkw4RKaOrm>@31 zflT>@scr8KjC1x56leSw`1X2u>W$e3M&k@6V#ZmNi1LZ-fF5$K&HrNZVbHB)0ELoy%QM?JM?7ff3N0)H z*E9=t0Szh>ksOd?;D(qNWMqkIEt9!K5M!W1nQgGo86cR0AQ%H-iJTzNcq{;H^86I> z;N|W@PsYj=z5pjsMFLD13lYY8^R<{&N%5yOEP6!iS`>p;yQJF&6Yy*>0|gpP0j(0& z`}#fZYa&)%?$Wk+^#jhIKziC> z8mo-F#~8F^EKE=A2H=wX!*8(!XCXzm&uDi&L}u4FNdre`pEYq4AXn@poy%Wp|s z^|+b>^RmWH_%47SZ^jm0lALDe5=;;eL>(*QYesB^SY-arSbDrOp8<(UZq*s_#YPFP z=1RFmq|EsN((|ILFruru0lk>%%rD7hK&F+Ri?X4qQbH0K+nj8~XT%(eB#TiqqLB#_ zjZ8o^(#V+x2=Z9?UH~O54QT0XmcJ*p9@h8qX+R3S_^3~#0i!Cc@tE7$C1TY0u0#aR z$0MQFqgLY4(14ZTP%q@P^WTexhPYrl?@cf9+$1PxfWcHp1cd@)XF&XbA*7wxwZB)v zEh0%@Y;C@sHH2|UWyElm=t_=9?r@M$4$<0&YoE;Siuj&1!jR)}h-!iSZmNvYr(D-3hv%aeiz0M)cT|ny=a=z=&V^F=I zEYk34k<~F}fsfuvq}8w(m;rv~dT`)wAihCVMP^ zq;}tV1o7l#j}?&YuK00`C#=b%#ByKXVNyJ&0}1L%U*CtZ97u(Y-lDb@aNxZem5Bd=Bz#<3TU1f#dV8L&~a|UH?*TQgUhb%MlxtG)%wEAE1 zQ;am-8$cYVzg>90ig!Vmg9h$fG6E*X`?LiWm01-Iy+) z0v|8IT%Vp6PVw_7xm@lsz@x-+JQAx~ACy?phuKA^R7MVuEleKE2t}O#^vr_^!Gr5z z$uA_BV{Y}-=%Dd_1U6)f-&+RQ@k}vdI##Sc(2BsJxPwrs?DoEG>;u(C8n?{|E&61D zQ`OW^GNr9VzHa)8@NcJMWtH7&))o1Ya^zllf{rfY@q4AKp+t#eQHIdm0+Iu`p-PU& z#-uTB;(a-r{Aoy#BLs_pL-*=Hu=j{+&hAu$NHlG2xDI*D!|}`)rXY`L0@2Se(e4Ec zBLPiQi5D+z8ue(#@a=hJnEsPIZ^PrHwwPU9(!Az^_lxqLL6j%?hxISrP!V-tGv`qw zg^LZ2%u;&Mn5g_-3 zy?8e-*y?*L()U74K0nb=i3HOuW(kvX;y~IYF?9@Dm)3;!B!7LLqM@MkXii9oL^m2L z*PhMzT-`g(O_U-6To^)<7lJ&BhAQ2!9mi;lN~v<&Nzpq3);r|3?x94D+r5B*2=tkV zJtVveA5EW!Dw{KxPQ%{Cd5rBl1Yu7!R&0Kc-J_o;9Dj&*JQ?xr!8jG^o@Io3tk`3J z!&n_hO@1Q*RLVh~@)ABhzr?d7e7Gqe`!200kf;yWTVA=tO_a*AEyn;s9OrCMm~-G% z)`C;Yv)c?TNNg9C$j&yCubI~f2|Q@iW-mfPZYzNp)#f0hpM)sXtvr}zA`LprrA0D3 zaBB|17(761xGB)oZB^*BJmqRGvc&8SwIXKzy%RaC>XWQld=>JbCb;-WJ~nb_Knr(eamR!1|Pl6lEd;oxmg!2y}Ptc!{ph zhp-+njy+K0aIL=UR^NVP9Sih)RA5rdibmOMChm&?XP0%){2AK(dr9%lA5qMXjYu=w z`MDNb2X4m~C)$E+Vp_&a#HG9GbRI_DP4dRK#j|~K@sW05% zvugH8PYdpX>|v3%jYGrxh)L1_j8@jxNE6gL2lC<@B8S^~7O3CJRl{OCKk{fk3;=xn z0)kH782u~<(Bzevd2$c+Ear=qjPht61d>hK+1#5E?JVg5AWP{+Ioo8EvpL4aC};VC z={ia``!RY8Vx2z8ZjBv96W%vgUJ}Xa1ggUd8^SQ=yd%#7kv~Q<^)m>=L|$QQbkQE! zA9G%ms7)veiZE7tBu5cSW?UfRZ;7D|X}qYAJ1`=~-g5+WAOYimKl zQ!4+mvbGU=kR4KJcUW2Lk-I|3@7LE>=k&Ez>}DhSTJL*paL#TKa6y%pSJ~ElKxJ!a zJPB^kfL9XPlJ(TK-a}qD0#dWu_GzT4B=KGW=bm(7>h zA>OtSf$Ab$HCds`+Zk9Y;bZ6|%@`=E56W*TM4ylZOzZTcDL=@*9L*;UuJ}_?eUWsN zh`Std9!X#P?g-r%Nq=mZ?pqF#r#N@}P*LtS)E-+29A%CaG}0|Y-%-R6l%FZnkbRHl zlixj>?n9YPfxPr;f##F*_X~AZ!oo7A8?kagtW+oZME)fl-*A-HN_&e>F zhWLB$7b5;VF6^Vwf0@5X|B3Vixgaqx%3Vx%MEWtT<)dgnPnZf)iF@>)UuwN3^zF}h zw4c)_HUtZ6serrq8Z)XU=4%xF5(l{wU$HKW759?BkREk2n7?szC3SiwdBqTZ5oI|{ z1g=IZ8JG~Al+!L(84!-5h{0%~uglpcnlsYZ&1FhoC%<(lnSrVn&URRVVi_s|sF^9p zDp7P=y^F=ZS)RP~I<}QeeX09Po?ig z()!*;1&yvKotRo8AlfbZvbHZ(<5gK4PHNqeNB4gsYqmvBsa*o+eU!fZ0J%CdB~GN2wNno zkg`ZiQKQo&zxBWjzcS#X1=#WwPMW}lqCppHd~uM4O#Op|J|-$cNhXSV%4l1vv%{K+9aZxi9Uk)PXS0xA7h-LU?vfX_smeE(N+rRh==H`3-9l$RHX0Mf|%Bvw&uSfiXJzDVNWfoay4^#eN?lv!05BTVc>#-E&(N&!!q9`pZ7cnx-O{{2Gf~Mfs?J&>7+8*!pDhZ~fhrsfN)$4_S zU&Cjt=;8I+>?pz`ID3}i*Jqg}9^xapPoWP&t20Z{JX@0|W77JbpCjrtt@ur`sIL9< z7St_YBf@LjF`RP{TzI=5!s2$+{-|~)DP@ULN=WJBY01Ld2MOR+E9FdQ@pD$%p5mN|qk1#HIlGK5JxhI@C=(j_^wl?oG za%gY*rIERl>CBsOc#!8op&fd1%_Xpu8e#v}u<>sgI=lPIfX8m9Ff1jnwz z_L_;r0DIj9?X= zNjKAO4daHkUrtsL*)#htTbfSQ@q`$<%1)=Iacj5Y+0pfa&%OAa5eTr;zWQexKEwIG zelQt0ZgcetZW5XQu-VgiMtsGyoyoarTa$lK9X1J`RGu%e+##Xa84y2q=Jl|#iCTA5 zhM!hf@m~DyKYZ~ng-EEQ{fXKkvf>lNE9EU))NFXB zP1Z2MSk1u1c*g%J8O-==I1gv+vZyt6{|zgwn)mqfNgG=qYr_;n;N)lkHo9do>n!BS z-YjC}jgGK}Ln|J2zkj#-=S`=?O6|0w|9kxWjrwlfVw&~U|KA4S?f;t_0BggkbVjxH zS8>Dk%9gFoJHIZq06&q(3*JKPHQtU+Y^g2#B;O7Y;WR__Y@}xq6G@+;a{An92MEuU z8`(KE0~3rH($qQ)t4h>L2Oa9v0V<8Bwi7rm2(6Iq)|&CC3WFA?U~GQHgcg@rn+HH3 zwAou=+<1$S8*jC8+EycN!kxAYC_61OJO#zvdIm6H-hP>CX9+E%*!+`L}|RWCo6 z-j=7TMh6*|^+>?PlR}9&Q{?Dd4U0?Gej-nQc-kQEG{vn3#G7VjyJ`9A-$|E1WaOj5 zBboC9u-)M}IOC7u2^WjcI(?W9t726+Z#hptC`#OIJ8YI0ySLS$^NAsd(-0gmEQ7NtN*72c`oXrP{sY<(+{IrUea~|5-MRw~QKi$d~nVYjZYHQVr z%eExaz)5F0aiswRbIW#DjxW#`e-}C2RoHf1Br`9I6-=^}n*O!f+18vX|Js0$>X669 zLc3Sr$015~=ufNvMT=3@vN-J?Dq%D~rOku2tLDa?9Rr*J^{6|Zj-lfPPBip_lU1;8 zf)h*pMNa;Gs&wUQg7Uo4;#MJ8J$o>cY-oo<(>rj@M&2+HGfc$y}$r zeQsuEyU36e^YCNiADfr`At$OmH(k2n-Yfc+akW-p+vc$iPX}$?>+cb_h%s7`P9mU&Oitz8)Lck-ly= zXX4$#v3>M?{dV<7oCVJ3UPLS}9-0?!ti*lp4GrLK0rjQ*`*_$BHr$3>i*iHJTK#tp z#i>W>e?N3Qh?V;OVfa)|KBdt(P6u2)st{pr^CpNyjl#QkY%2Q+eCd z6r_*r&>uEPw~Zc}ePRM(Qv6^&bVl_!l(918dKUI7CyAAY-`@?zpoj8hq0W zJ{v)$ng|Z*oo-NnMFOjT-7UY&OgZqNEdDJ_ck-BMLpZROufo7UfdJq&Z|pt)K=99~ z_-`gevj=-(gPhq@Yz{NOXEsufe!vD@0|JUj=He1}_93B;gD@*dT9XqZ`27)VamiOD z!FtS1a)nUQbYkH;3oxj7%(`bmU9+4UA*Dqr zFp$AUagm;-ir%eoH_^!SnC!znbNsaL3y300Xn?9G*76oL^v*4`Y0&Fnr1prrif6m^ z$&sFXiv*-cv-I($+{+`7bLXthzXe+4d_3lLZ^fG-#qs%446d)95qDOGNAC%m6|*0V z%!h}`^NOFX;FqZLLcDc<+}X+5^_+0!PN2Tg13kb1YM{R`(!3#(Z0)g`1Tl}UdP94z z$rAVNuruj)2Ef8sH)u1U?dGX0(ryLATdlJA7LxC^$|75N?&SGip7-+H$@4*;_wqc* zv+f7&6z6sQh_WINh!|CgR#_omR`E8-V;x^s@f?QyZy`<3VQj%#w1;n@S>#=2TWh

cV_HyWyvG(n+sfhU6pQ*;`uoFBpnEK%xN8 zeUBpv^1=U#+(Di=UchTyq;@-B;L-0MAlYs`b|hD?63lpAT9Vx{JLJ`}`UfiU4wbP# z4-3z`*O<(GBZKXb04#*`@qF%u=rwOnw}SDyMWe3zzpVw}=6ZVelZ7m41fPzkr7g=Wg(|(fLw;tB3f0BFR#vx=! z+&`@>HfK`ml+PEHZ}4^Vf(-glAIvy!z$Wtat-AXihlFk)J|y&D{>dB?%G284Hn$#V zZtZOj9awX2vom{X{Hks>GQPeu!6o7AY_8qy%`Yd$HfP%P68E3;@j8pA`U~6oyPa*` zD1PYr(e|;Gv2tE-)_F>JAAvWYcK2@1Egi7CC7z^wr%avE?7f<-C;r%@Dy?QF-_B7tZW*Kr3o&gh$_Z^h=>C!YH|F#(iJx7@S8kSP zr;qcM^l*p=EYD*o)OmVIuVPbp!ql>k6k&qLyu^BR1Tk%R>CJ{llWyXC+7oqNXFrH7 zWf-hQ;t4 zdIT25+Cgfs&JK=g%-n`fw=d@Y4-<%-5#Lla1z>G(H_jxKU~P@aj`V5Ik|PeC#( zpZrLAu!Hs5Xl>REAyuAXx&T|l73Q`oG_(e5j&~xdmy2q999FL6i8M(F^HH}ut+C8K z+@}XrgA>g=C?U>ECCMC(_z1&jEU9C4_*H3T=IVNomLZ?@Dl{@CMfnvM#+jvG#K!bd z_k0QwHhq$ZNbPg(Nh-9J8H0v=)D80lDy`SOpL;Q9os@~G!ust7phq9sl09wjH~j_K z(;nw{&z}BwKzQt@{ZsL4*1jq`3Pq+^jz(n#9MUQ=NU2v?I-h2+3C7Jda9|2s&7=1bM$$p_#Lfiq5`K2b>irFqup`8G)}$7 zea?i16Ygbnlhu`CXoK~gJ;mRtWTT=7^*eitGu#7u1=jbl1H>Z~^RV@U*CwyLCbItZ zrYo;)i#m@x#0lY4-`Ip+>wA&)hpxKz%6Qse9hO zsJ(^Jbn#i-4vZ!3G;SUMS_%mA@JVpM_o&)=M>XfGwH|tL+{y{$DRT%<21tvsLN3ilE-xyqifS0=?(wpL*En3-eR&T)!wCQqt2 z&{O<*ZiEuk#ml)1AMUA29-Hc|>M6c}$71thK6e7N8u664g=y9~4Uqxo*y#wMybB<9 zOZnE5Po%cj2qwY{@CIkoi=8%0+^v zc{SbcMX)+JE}zcDy06ou>F8J9^~(sBLt3qG>RiW~{z*(zZVyiinAkkLb;=rr*R9{_ z?x2v4&bCVR->f$sf{2bYztr3YfO6CRjW7V=`wLU&^?y>N&xW5;Pfzgy9s~$(2Oo8G zCg;0X(*XB5rrrHBKSW9U-Zvy)ExnnG``(v|urF?#?4II%Ud8)My!Z3;ei`q3iaRJ& zKps9PyJ@%kdpO>32XXi>)yCK>H7&;Y2qKf!g#U4Cc}>NY1VA#OOxf6N2cD+%(AN?9 zX7^=_zgqu{hWckVbgnyQ)R=@B&Z^71 zu^BFI;l29__R{dCA%bzegPbg~p2lrgM<-X4N7}-_ xx`UO-}a(_`+5w6y;5 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 S;ygnc*zH}iv;Tkd@qYm1B2nl7 literal 201216 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�t&S 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

(ioPEbpZ->4)VHSn?eyKA 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%0A9w^9Q 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

NWNwD4vH6Hrgy)A}nvulatH^V3xCrZEv~ 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 SuYvm-xUYfx8u*uJ;6DJBJgk8L diff --git a/bin/zlib.net.dll b/bin/zlib.net.dll index 9d156547f336ff1e7b51e28a2369a344fec2831c..1ce10afe689046d562c3e1e4b91b7bfa02da6399 100755 GIT binary patch literal 65536 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

jx_v`c>z~O-$%myPF# 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 Date: Wed, 2 Aug 2023 00:33:55 +0100 Subject: [PATCH 101/149] fix xml apos escape; some changes on wingridproxy --- OpenMetaverse.StructuredData/LLSD/XmlLLSD.cs | 8 +-- OpenMetaverse/Messages/LindenMessages.cs | 72 ++++++++++++++++++- OpenMetaverse/Messages/MessageEventDecoder.cs | 1 + OpenMetaverse/PacketDecoder.cs | 2 +- Programs/GridProxy/GridProxy.cs | 30 ++++---- Programs/WinGridProxy/FormWinGridProxy.cs | 2 +- Programs/WinGridProxy/ProxyManager.cs | 39 +++++----- Programs/WinGridProxy/SessionTypes.cs | 24 ++++--- 8 files changed, 132 insertions(+), 46 deletions(-) diff --git a/OpenMetaverse.StructuredData/LLSD/XmlLLSD.cs b/OpenMetaverse.StructuredData/LLSD/XmlLLSD.cs index dd9a5bd4..23fcbe4b 100644 --- a/OpenMetaverse.StructuredData/LLSD/XmlLLSD.cs +++ b/OpenMetaverse.StructuredData/LLSD/XmlLLSD.cs @@ -265,7 +265,7 @@ public static void EscapeToXML(string s, StringBuilder sb) case '"': sb.Append("""); break; - case '\\': + case '\'': sb.Append("'"); break; default: @@ -295,7 +295,7 @@ public static void EscapeASCIIToXML(osUTF8 ms, string s) case '"': ms.Append(osUTF8Const.XMLamp_quot); break; - case '\\': + case '\'': ms.Append(osUTF8Const.XMLamp_apos); break; default: @@ -325,7 +325,7 @@ public static void EscapeToXML(osUTF8 ms, string s) case '"': ms.Append(osUTF8Const.XMLamp_quot); break; - case '\\': + case '\'': ms.Append(osUTF8Const.XMLamp_apos); break; default: @@ -355,7 +355,7 @@ public static void EscapeToXML(osUTF8 ms, osUTF8 s) case (byte)'"': ms.Append(osUTF8Const.XMLamp_quot); break; - case (byte)'\\': + case (byte)'\'': ms.Append(osUTF8Const.XMLamp_apos); break; default: diff --git a/OpenMetaverse/Messages/LindenMessages.cs b/OpenMetaverse/Messages/LindenMessages.cs index 2a80be1b..75ba3514 100644 --- a/OpenMetaverse/Messages/LindenMessages.cs +++ b/OpenMetaverse/Messages/LindenMessages.cs @@ -1813,6 +1813,76 @@ public OSDMap Serialize() } + public class LargeGenericMessage : IMessage + { + private OSDMap RawData; + public UUID AgentID; + public UUID SessionID; + public UUID TransactionID; + + public string Method; + public UUID Invoice; + + public class Parameter + { + public string value; + } + + public Parameter[] Parameters; + + public void Deserialize(OSDMap map) + { + RawData = map; + OSD osdtmp, osdtmp2; + if (map.TryGetValue("AgentData", out osdtmp)) + { + if (osdtmp is OSDArray agdArray && agdArray.Count > 0) + { + if (agdArray[0] is OSDMap agdMap) + { + if (agdMap.TryGetValue("AgentID", out osdtmp2)) + AgentID = osdtmp2.AsUUID(); + if (agdMap.TryGetValue("SessionID", out osdtmp2)) + SessionID = osdtmp2.AsUUID(); + if (agdMap.TryGetValue("TransactionID", out osdtmp2)) + TransactionID = osdtmp2.AsUUID(); + } + } + } + if (map.TryGetValue("MethodData", out osdtmp)) + { + if (osdtmp is OSDArray mdArray && mdArray.Count > 0) + { + if (mdArray[0] is OSDMap mdMap) + { + if (mdMap.TryGetValue("Method", out osdtmp2)) + Method = osdtmp2.AsString(); + if (mdMap.TryGetValue("Invoice", out osdtmp2)) + Invoice = osdtmp2.AsUUID(); + } + } + } + if (map.TryGetValue("ParamList", out osdtmp)) + { + if (osdtmp is OSDArray pArray && pArray.Count > 0) + { + Parameters = new Parameter[pArray.Count]; + for(int i = 0; i < Parameters.Length; i++) + { + Parameters[i] = new Parameter(){value = pArray[i].ToString() }; + } + } + } + + Method ??="MissingMethod"; + } + + public OSDMap Serialize() + { + return RawData; + } + } + /// Base class for Asset uploads/results via Capabilities public abstract class AssetUploaderBlock { @@ -4528,7 +4598,7 @@ public class GetObjectCostMessage : IMessage public void Deserialize(OSDMap map) { if (map.Count != 1) - Logger.Log("GetObjectCostMessage returned values for more than one object! Function needs to be fixed for that!", Helpers.LogLevel.Error); + Logger.Log("GetObjectCostMessage returned values for more than one object! Function needs to be fixed for that!", Helpers.LogLevel.Error); foreach (string key in map.Keys) { diff --git a/OpenMetaverse/Messages/MessageEventDecoder.cs b/OpenMetaverse/Messages/MessageEventDecoder.cs index d82e5bc2..e8e1cea2 100644 --- a/OpenMetaverse/Messages/MessageEventDecoder.cs +++ b/OpenMetaverse/Messages/MessageEventDecoder.cs @@ -101,6 +101,7 @@ public static IMessage DecodeEvent(string eventName, OSDMap map) case "BulkUpdateInventory": message = new BulkUpdateInventoryMessage(); break; case "RenderMaterials": message = new RenderMaterialsMessage(); break; case "GetObjectCost": message = GetObjectCostMessage.GetMessageHandler(map); break; + case "LargeGenericMessage": message = new LargeGenericMessage(); break; // Capabilities TODO: // DispatchRegionInfo diff --git a/OpenMetaverse/PacketDecoder.cs b/OpenMetaverse/PacketDecoder.cs index 64af8936..0ad11faa 100644 --- a/OpenMetaverse/PacketDecoder.cs +++ b/OpenMetaverse/PacketDecoder.cs @@ -1938,7 +1938,7 @@ public static string MessageToString(object message, int recurseLevel) else { result.AppendFormat("{0, 30}: {1,-40} [{2}]" + Environment.NewLine, - messageField.Name, messageField.GetValue(message), messageField.FieldType.Name); + messageField.Name, messageField.GetValue(message), messageField.FieldType.Name); } } } diff --git a/Programs/GridProxy/GridProxy.cs b/Programs/GridProxy/GridProxy.cs index 9448a540..8a259a76 100644 --- a/Programs/GridProxy/GridProxy.cs +++ b/Programs/GridProxy/GridProxy.cs @@ -639,9 +639,11 @@ private void ProxyHTTP(Socket client) public ObservableDictionary KnownCaps = new ObservableDictionary(); //private Dictionary SubHack = new Dictionary(); + private static Regex CapMainRegex = new Regex(@"^(https?)://([^:/]+)(:\d+)?(/.*)$", RegexOptions.Compiled | RegexOptions.CultureInvariant); + private static Regex CapUriRegex = new Regex(@"/?\?.*$", RegexOptions.Compiled | RegexOptions.CultureInvariant); private void ProxyCaps(NetworkStream netStream, string meth, string uri, Dictionary headers, byte[] content, int reqNo) { - Match match = new Regex(@"^(https?)://([^:/]+)(:\d+)?(/.*)$").Match(uri); + Match match = CapMainRegex.Match(uri); if (!match.Success) { OpenMetaverse.Logger.Log("[" + reqNo + "] Malformed proxy URI: " + uri, Helpers.LogLevel.Error); @@ -657,7 +659,7 @@ private void ProxyCaps(NetworkStream netStream, string meth, string uri, Diction CapInfo cap = null; lock (this) { - string capuri = Regex.Replace(uri, @"/?\?.*$", string.Empty); + string capuri = CapUriRegex.Replace(uri, string.Empty); // detect AIS url int indx = capuri.IndexOf("/item/"); if (indx < 0) @@ -665,9 +667,14 @@ private void ProxyCaps(NetworkStream netStream, string meth, string uri, Diction if(indx > 0) capuri = capuri.Substring(0,indx); - if (KnownCaps.ContainsKey(capuri)) + if (!KnownCaps.TryGetValue(capuri, out cap)) { - cap = KnownCaps[capuri]; + indx = capuri.IndexOf("cap/"); + if(indx > 0) + { + capuri = capuri.Substring(0,indx + 36 + 4); + _ = KnownCaps.TryGetValue(capuri, out cap); + } } } @@ -1081,15 +1088,10 @@ private bool FixupEventQueueGet(CapsRequest capReq, CapsStage stage) { if (stage != CapsStage.Response) return false; - OSDMap map = null; - if (capReq.Response is OSDMap) - map = (OSDMap)capReq.Response; - else return false; + if (capReq.Response is not OSDMap map) + return false; - OSDArray array = null; - if (map.ContainsKey("events") && map["events"] is OSDArray) - array = (OSDArray)map["events"]; - else + if(!map.TryGetValue("events", out OSD oarray) || oarray is not OSDArray array) return false; for (int i = 0; i < array.Count; i++) @@ -2188,8 +2190,7 @@ public class CapInfo public CapInfo(string URI, IPEndPoint Sim, string CapType) - : - this(URI, Sim, CapType, CapsDataFormat.OSD, CapsDataFormat.OSD) { } + : this(URI, Sim, CapType, CapsDataFormat.OSD, CapsDataFormat.OSD) { } public CapInfo(string URI, IPEndPoint Sim, string CapType, CapsDataFormat ReqFmt, CapsDataFormat RespFmt) { uri = URI; sim = Sim; type = CapType; reqFmt = ReqFmt; respFmt = RespFmt; @@ -2271,6 +2272,7 @@ public CapsRequest(CapInfo info) public string FullUri = string.Empty; public string Method = string.Empty; + public string ExtraInfo = string.Empty; } // XmlRpcRequestDelegate: specifies a delegate to be called for XML-RPC requests diff --git a/Programs/WinGridProxy/FormWinGridProxy.cs b/Programs/WinGridProxy/FormWinGridProxy.cs index c203fd6b..681daae9 100644 --- a/Programs/WinGridProxy/FormWinGridProxy.cs +++ b/Programs/WinGridProxy/FormWinGridProxy.cs @@ -310,7 +310,7 @@ private void ProxyManager_OnMessageLog(CapsRequest req, CapsStage stage) } else { - capsSession = new SessionEvent(req.RawResponse, req.ResponseHeaders, req.Info.URI, req.Info.CapType, proto); + capsSession = new SessionEvent(req.RawResponse, req.ResponseHeaders, req.Info.URI, req.Info.CapType, proto, req.ExtraInfo); } string[] s = { PacketCounter.ToString(), capsSession.TimeStamp.ToString("HH:mm:ss.fff"), capsSession.Protocol, capsSession.Name, capsSession.Length.ToString(), capsSession.Host, capsSession.ContentType }; diff --git a/Programs/WinGridProxy/ProxyManager.cs b/Programs/WinGridProxy/ProxyManager.cs index eccab021..731b71a7 100644 --- a/Programs/WinGridProxy/ProxyManager.cs +++ b/Programs/WinGridProxy/ProxyManager.cs @@ -171,30 +171,37 @@ private bool CapsHandler(CapsRequest req, CapsStage stage) /// private bool EventQueueGetHandler(CapsRequest req, CapsStage stage) { - if (stage == CapsStage.Response && req.Response is OSDMap) + if (stage == CapsStage.Response && req.Response is OSDMap map) { - OSDMap map = (OSDMap)req.Response; + if (OnEventMessageLog is null) + return false; - if (map.ContainsKey("events")) + if (map.TryGetValue("events", out OSD tmposd)) { - OSDArray eventsArray = (OSDArray)map["events"]; + OSDArray eventsArray = (OSDArray)tmposd; + int EventID = 0; + if(map.TryGetValue("id", out OSD idsd)) + EventID = idsd.AsInteger(); + + int events = eventsArray.Count; for (int i = 0; i < eventsArray.Count; i++) { OSDMap bodyMap = (OSDMap)eventsArray[i]; - if (OnEventMessageLog != null) + + CapInfo capInfo = new CapInfo(req.Info.URI, req.Info.Sim, bodyMap["message"].AsString()); + CapsRequest capReq = new CapsRequest(capInfo) { - CapInfo capInfo = new CapInfo(req.Info.URI, req.Info.Sim, bodyMap["message"].AsString()); - CapsRequest capReq = new CapsRequest(capInfo); - capReq.RequestHeaders = req.RequestHeaders; - capReq.ResponseHeaders = req.ResponseHeaders; - capReq.Request = null;// req.Request; - capReq.RawRequest = null;// req.RawRequest; - capReq.RawResponse = OSDParser.SerializeLLSDXmlBytes(bodyMap); - capReq.Response = bodyMap; - - OnEventMessageLog(capReq, CapsStage.Response); - } + RequestHeaders = req.RequestHeaders, + ResponseHeaders = req.ResponseHeaders, + Request = null,// req.Request; + RawRequest = null,// req.RawRequest; + RawResponse = OSDParser.SerializeLLSDXmlBytes(bodyMap), + Response = bodyMap + }; + capReq.ExtraInfo = $"Event iD {EventID} Message {i + 1}/{events}"; + + OnEventMessageLog?.Invoke(capReq, CapsStage.Response); } } } diff --git a/Programs/WinGridProxy/SessionTypes.cs b/Programs/WinGridProxy/SessionTypes.cs index 0b6ad489..582b3ed9 100644 --- a/Programs/WinGridProxy/SessionTypes.cs +++ b/Programs/WinGridProxy/SessionTypes.cs @@ -75,7 +75,7 @@ public virtual string ToRawString(Direction direction) public virtual byte[] ToBytes(Direction direction) { - return OpenMetaverse.Utils.EmptyBytes; + return Array.Empty(); } public virtual string ToXml(Direction direction) @@ -202,12 +202,12 @@ public SessionCaps(byte[] requestBytes, byte[] responseBytes, if (requestBytes != null) RequestBytes = requestBytes; else - RequestBytes = OpenMetaverse.Utils.EmptyBytes; + RequestBytes = Array.Empty(); if (responseBytes != null) ResponseBytes = responseBytes; else - ResponseBytes = OpenMetaverse.Utils.EmptyBytes; + ResponseBytes = Array.Empty(); RequestHeaders = requestHeaders; ResponseHeaders = responseHeaders; Protocol = proto; @@ -665,10 +665,11 @@ internal class SessionEvent : Session { private byte[] ResponseBytes; private WebHeaderCollection ResponseHeaders; + private string ExtraInfo; public SessionEvent() : base() { this.Protocol = "EventQ"; } public SessionEvent(byte[] responseBytes, WebHeaderCollection responseHeaders, - String uri, String capsKey, String proto) + String uri, String capsKey, String proto, string ExtraInfo) : base() { this.Protocol = proto; @@ -679,10 +680,8 @@ public SessionEvent(byte[] responseBytes, WebHeaderCollection responseHeaders, this.Name = capsKey; this.ContentType = responseHeaders.Get("Content-Type"); var ContentLength = responseHeaders.Get("Content-Length"); - if (ContentLength != null) - this.Length = Int32.Parse (ContentLength); - else - this.Length = 0; + this.Length = ContentLength is null ? 0 : Int32.Parse (ContentLength); + this.ExtraInfo = ExtraInfo; } public override string ToPrettyString(Direction direction) @@ -728,9 +727,16 @@ public override string ToRawString(Direction direction) StringBuilder result = new StringBuilder(); foreach (String key in ResponseHeaders.Keys) { - result.AppendFormat("{0} {1}" + Environment.NewLine, key, ResponseHeaders[key]); + //result.AppendFormat("{0} {1}" + Environment.NewLine, key, ResponseHeaders[key]); + result.AppendLine($"{key} {ResponseHeaders[key]}"); } result.AppendLine(); + if (!string.IsNullOrEmpty(this.ExtraInfo)) + { + result.Append(this.ExtraInfo); + result.AppendLine(); + result.AppendLine(); + } result.AppendLine(this.ToXml(direction)); return result.ToString(); } From 0141aa285804b32a2dbcaa5bad1aef91b087a050 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Sat, 6 Jan 2024 02:03:20 +0000 Subject: [PATCH 102/149] update _packet_.cs --- OpenMetaverse/_Packets_.cs | 166 +++++++++++++++++++++++++++++++++++++ 1 file changed, 166 insertions(+) diff --git a/OpenMetaverse/_Packets_.cs b/OpenMetaverse/_Packets_.cs index d8b02907..eeac1cdd 100644 --- a/OpenMetaverse/_Packets_.cs +++ b/OpenMetaverse/_Packets_.cs @@ -628,6 +628,7 @@ public enum PacketType ChildAgentPositionUpdate = 196635, SoundTrigger = 196637, ObjectAnimation = 196638, + GenericStreamingMessage = 196639, } public abstract partial class Packet @@ -1046,6 +1047,7 @@ public static PacketType GetType(ushort id, PacketFrequency frequency) case 27: return PacketType.ChildAgentPositionUpdate; case 29: return PacketType.SoundTrigger; case 30: return PacketType.ObjectAnimation; + case 31: return PacketType.GenericStreamingMessage; } break; } @@ -1084,6 +1086,7 @@ public static Packet BuildPacket(PacketType type) case PacketType.ChildAgentPositionUpdate: return new ChildAgentPositionUpdatePacket(); case PacketType.SoundTrigger: return new SoundTriggerPacket(); case PacketType.ObjectAnimation: return new ObjectAnimationPacket(); + case PacketType.GenericStreamingMessage: return new GenericStreamingMessagePacket(); case PacketType.ObjectAdd: return new ObjectAddPacket(); case PacketType.MultipleObjectUpdate: return new MultipleObjectUpdatePacket(); case PacketType.RequestMultipleObjects: return new RequestMultipleObjectsPacket(); @@ -1866,6 +1869,7 @@ public static Packet BuildPacket(byte[] packetBuffer, ref int packetLength, byte case 27: return new ChildAgentPositionUpdatePacket(header, bytes, ref i); case 29: return new SoundTriggerPacket(header, bytes, ref i); case 30: return new ObjectAnimationPacket(header, bytes, ref i); + case 31: return new GenericStreamingMessagePacket(header, bytes, ref i); } break; @@ -79522,4 +79526,166 @@ public override byte[][] ToBytesMultiple() } } + /// + public sealed class GenericStreamingMessagePacket : Packet + { + /// + public sealed class MethodDataBlock : PacketBlock + { + public ushort Method; + + public override int Length + { + get + { + return 2; + } + } + + public MethodDataBlock() { } + public MethodDataBlock(byte[] bytes, ref int i) + { + FromBytes(bytes, ref i); + } + + public override void FromBytes(byte[] bytes, ref int i) + { + try + { + Method = Utils.BytesToUInt16(bytes, i); i+=2; + } + catch (Exception) + { + throw new MalformedDataException(); + } + } + + public override void ToBytes(byte[] bytes, ref int i) + { + Utils.UInt16ToBytes(Method, bytes, i); i += 2; + } + + } + + /// + public sealed class DataBlockBlock : PacketBlock + { + public byte[] Data; + + public override int Length + { + get + { + int length = 2; + if (Data != null) { length += Data.Length; } + return length; + } + } + + public DataBlockBlock() { } + public DataBlockBlock(byte[] bytes, ref int i) + { + FromBytes(bytes, ref i); + } + + public override void FromBytes(byte[] bytes, ref int i) + { + int length; + try + { + length = (bytes[i++] + (bytes[i++] << 8)); + Data = new byte[length]; + Buffer.BlockCopy(bytes, i, Data, 0, length); i += length; + } + catch (Exception) + { + throw new MalformedDataException(); + } + } + + public override void ToBytes(byte[] bytes, ref int i) + { + bytes[i++] = (byte)(Data.Length % 256); + bytes[i++] = (byte)((Data.Length >> 8) % 256); + Buffer.BlockCopy(Data, 0, bytes, i, Data.Length); i += Data.Length; + } + + } + + public override int Length + { + get + { + int length = 7; + length += MethodData.Length; + length += DataBlock.Length; + return length; + } + } + public MethodDataBlock MethodData; + public DataBlockBlock DataBlock; + + public GenericStreamingMessagePacket() + { + HasVariableBlocks = false; + Type = PacketType.GenericStreamingMessage; + Header = new Header(); + Header.Frequency = PacketFrequency.High; + Header.ID = 31; + Header.Reliable = true; + MethodData = new MethodDataBlock(); + DataBlock = new DataBlockBlock(); + } + + public GenericStreamingMessagePacket(byte[] bytes, ref int i) : this() + { + int packetEnd = bytes.Length - 1; + FromBytes(bytes, ref i, ref packetEnd, null); + } + + override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer) + { + Header.FromBytes(bytes, ref i, ref packetEnd); + if (Header.Zerocoded && zeroBuffer != null) + { + packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1; + bytes = zeroBuffer; + } + MethodData.FromBytes(bytes, ref i); + DataBlock.FromBytes(bytes, ref i); + } + + public GenericStreamingMessagePacket(Header head, byte[] bytes, ref int i): this() + { + FromBytes(head, bytes, ref i); + } + + override public void FromBytes(Header header, byte[] bytes, ref int i) + { + Header = header; + MethodData.FromBytes(bytes, ref i); + DataBlock.FromBytes(bytes, ref i); + } + + public override byte[] ToBytes() + { + int length = 7; + length += MethodData.Length; + length += DataBlock.Length; + if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; } + byte[] bytes = new byte[length]; + int i = 0; + Header.ToBytes(bytes, ref i); + MethodData.ToBytes(bytes, ref i); + DataBlock.ToBytes(bytes, ref i); + if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } + return bytes; + } + + public override byte[][] ToBytesMultiple() + { + return new byte[][] { ToBytes() }; + } + } + } From 1ba434a06aaffd6a3ad082b1ba424349ad048d8b Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Sat, 6 Jan 2024 02:04:59 +0000 Subject: [PATCH 103/149] update _packet_.cs --- Programs/GridProxy/GridProxy.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Programs/GridProxy/GridProxy.cs b/Programs/GridProxy/GridProxy.cs index 8a259a76..f210b25d 100644 --- a/Programs/GridProxy/GridProxy.cs +++ b/Programs/GridProxy/GridProxy.cs @@ -709,6 +709,8 @@ private void ProxyCaps(NetworkStream netStream, string meth, string uri, Diction byte[] respBuf = null; string consoleMsg = String.Empty; + string orig = string.Empty; + bool reqrange = false; bool resprange = false; @@ -862,6 +864,8 @@ private void ProxyCaps(NetworkStream netStream, string meth, string uri, Diction } + orig = Encoding.UTF8.GetString(respBuf); + consoleMsg += "[" + reqNo + "] Response from " + uri + "\nStatus: " + (int)resp.StatusCode + " " + resp.StatusDescription + "\n"; { From 708053fed70675ad22eb436f5fdac8235c4a9ef4 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Sat, 6 Jan 2024 02:09:34 +0000 Subject: [PATCH 104/149] remove debug code on last commit --- Programs/GridProxy/GridProxy.cs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Programs/GridProxy/GridProxy.cs b/Programs/GridProxy/GridProxy.cs index f210b25d..8a259a76 100644 --- a/Programs/GridProxy/GridProxy.cs +++ b/Programs/GridProxy/GridProxy.cs @@ -709,8 +709,6 @@ private void ProxyCaps(NetworkStream netStream, string meth, string uri, Diction byte[] respBuf = null; string consoleMsg = String.Empty; - string orig = string.Empty; - bool reqrange = false; bool resprange = false; @@ -864,8 +862,6 @@ private void ProxyCaps(NetworkStream netStream, string meth, string uri, Diction } - orig = Encoding.UTF8.GetString(respBuf); - consoleMsg += "[" + reqNo + "] Response from " + uri + "\nStatus: " + (int)resp.StatusCode + " " + resp.StatusDescription + "\n"; { From 3f705d15e6a796414415029727bc6987bc065aeb Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Wed, 7 Feb 2024 22:43:10 +0000 Subject: [PATCH 105/149] several updates. This may no longer work on BigEndian CPUs --- .../LLSD/NotationLLSD.cs | 6 + .../StructuredData.cs | 6 +- OpenMetaverse/CapsToPacket.cs | 2 +- OpenMetaverse/Rendering/Rendering.cs | 170 +-- OpenMetaverseTypes/Matrix3x3.cs | 2 +- OpenMetaverseTypes/OSUTF8.cs | 78 +- OpenMetaverseTypes/OSUTF8Slice.cs | 20 +- OpenMetaverseTypes/UtilsConversions.cs | 1339 ++++++++++------- OpenMetaverseTypes/Vector3.cs | 22 +- .../GridAccountant/frmGridAccountant.cs | 2 +- data/message_template.msg | 18 + mapgen.bat | 3 +- 12 files changed, 978 insertions(+), 690 deletions(-) diff --git a/OpenMetaverse.StructuredData/LLSD/NotationLLSD.cs b/OpenMetaverse.StructuredData/LLSD/NotationLLSD.cs index 0b58100e..14efc824 100644 --- a/OpenMetaverse.StructuredData/LLSD/NotationLLSD.cs +++ b/OpenMetaverse.StructuredData/LLSD/NotationLLSD.cs @@ -470,6 +470,9 @@ private static void SerializeLLSDNotationElement(TextWriter writer, OSD osd) EscapeCharacter(osd.AsString(), singleQuotesNotationMarker, writer); writer.Write(singleQuotesNotationMarker); break; + case OSDType.LLSDxml: + writer.Write(osd.AsString()); + break; case OSDType.Binary: writer.Write(binaryNotationMarker); writer.Write("64"); @@ -608,6 +611,9 @@ private static void SerializeLLSDNotationElementFormatted(TextWriter writer, str EscapeCharacter(osd.AsString(), singleQuotesNotationMarker, writer); writer.Write(singleQuotesNotationMarker); break; + case OSDType.LLSDxml: + writer.Write(osd.AsString()); + break; case OSDType.Binary: writer.Write(binaryNotationMarker); writer.Write("64"); diff --git a/OpenMetaverse.StructuredData/StructuredData.cs b/OpenMetaverse.StructuredData/StructuredData.cs index 2e30aafb..02aa8859 100644 --- a/OpenMetaverse.StructuredData/StructuredData.cs +++ b/OpenMetaverse.StructuredData/StructuredData.cs @@ -389,7 +389,7 @@ public virtual string AsString() case OSDType.Integer: return ((OSDInteger)this).value.ToString(); case OSDType.Real: - return ((OSDReal)this).value.ToString("r", Utils.EnUsCulture); + return ((OSDReal)this).value.ToString("g", Utils.EnUsCulture); case OSDType.String: return ((OSDString)this).value; case OSDType.OSDUTF8: @@ -695,7 +695,7 @@ public override string ToString() case OSDType.Integer: return ((OSDInteger)this).value.ToString(); case OSDType.Real: - return ((OSDReal)this).value.ToString("r", Utils.EnUsCulture); + return ((OSDReal)this).value.ToString("g", Utils.EnUsCulture); case OSDType.String: return ((OSDString)this).value; case OSDType.OSDUTF8: @@ -1206,7 +1206,7 @@ public override ulong AsULong() public override double AsReal() { return value; } // "r" ensures the value will correctly round-trip back through Double.TryParse [MethodImpl(MethodImplOptions.AggressiveInlining)] - public override string AsString() { return value.ToString("r", Utils.EnUsCulture); } + public override string AsString() { return value.ToString("g", Utils.EnUsCulture); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public override byte[] AsBinary() { return Utils.DoubleToBytesBig(value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/OpenMetaverse/CapsToPacket.cs b/OpenMetaverse/CapsToPacket.cs index c925270b..80472be7 100644 --- a/OpenMetaverse/CapsToPacket.cs +++ b/OpenMetaverse/CapsToPacket.cs @@ -242,7 +242,7 @@ private static object ParseLLSDBlock(OSDMap blockData, Type blockType) } else if (fieldType == typeof(byte[]) && blockData[field.Name].Type == OSDType.String) { - field.SetValue(block, Utils.StringToBytes(blockData[field.Name])); + field.SetValue(block, Utils.StringToBytes(blockData[field.Name].AsString())); } } } diff --git a/OpenMetaverse/Rendering/Rendering.cs b/OpenMetaverse/Rendering/Rendering.cs index f0ca7502..0c033504 100644 --- a/OpenMetaverse/Rendering/Rendering.cs +++ b/OpenMetaverse/Rendering/Rendering.cs @@ -289,119 +289,109 @@ public static bool TryDecodeFromAsset(Primitive prim, AssetMesh meshAsset, Detai break; } - if (facesOSD == null || !(facesOSD is OSDArray)) - { + if (facesOSD is not OSDArray decodedMeshOsdArray) return false; - } - - OSDArray decodedMeshOsdArray = (OSDArray)facesOSD; for (int faceNr = 0; faceNr < decodedMeshOsdArray.Count; faceNr++) { - OSD subMeshOsd = decodedMeshOsdArray[faceNr]; + if(decodedMeshOsdArray[faceNr] is not OSDMap subMeshMap) + continue; // Decode each individual face - if (subMeshOsd is OSDMap) - { - Face oface = new Face(); - oface.ID = faceNr; - oface.Vertices = new List(); - oface.Indices = new List(); - oface.TextureFace = prim.Textures.GetFace((uint)faceNr); - - OSDMap subMeshMap = (OSDMap)subMeshOsd; - Vector3 posMax; - Vector3 posMin; + Face oface = new Face(); + oface.ID = faceNr; + oface.Vertices = new List(); + oface.Indices = new List(); + oface.TextureFace = prim.Textures.GetFace((uint)faceNr); - // If PositionDomain is not specified, the default is from -0.5 to 0.5 - if (subMeshMap.ContainsKey("PositionDomain")) - { - posMax = ((OSDMap)subMeshMap["PositionDomain"])["Max"]; - posMin = ((OSDMap)subMeshMap["PositionDomain"])["Min"]; - } - else - { - posMax = new Vector3(0.5f, 0.5f, 0.5f); - posMin = new Vector3(-0.5f, -0.5f, -0.5f); - } + Vector3 posMax; + Vector3 posMin; - // Vertex positions - byte[] posBytes = subMeshMap["Position"]; + // If PositionDomain is not specified, the default is from -0.5 to 0.5 + if (subMeshMap.TryGetValue("PositionDomain", out OSD osdpd) && osdpd is OSDMap mappd) + { + posMax = mappd["Max"]; + posMin = mappd["Min"]; + } + else + { + posMax = new Vector3(0.5f, 0.5f, 0.5f); + posMin = new Vector3(-0.5f, -0.5f, -0.5f); + } - // Normals - byte[] norBytes = null; - if (subMeshMap.ContainsKey("Normal")) - { - norBytes = subMeshMap["Normal"]; - } + // Vertex positions + byte[] posBytes = subMeshMap["Position"]; - // UV texture map - Vector2 texPosMax = Vector2.Zero; - Vector2 texPosMin = Vector2.Zero; - byte[] texBytes = null; - if (subMeshMap.ContainsKey("TexCoord0")) - { - texBytes = subMeshMap["TexCoord0"]; - texPosMax = ((OSDMap)subMeshMap["TexCoord0Domain"])["Max"]; - texPosMin = ((OSDMap)subMeshMap["TexCoord0Domain"])["Min"]; - } + // Normals + byte[] norBytes = null; + if (subMeshMap.TryGetValue("Normal", out OSD osdNormal)) + { + norBytes = osdNormal; + } - // Extract the vertex position data - // If present normals and texture coordinates too - for (int i = 0; i < posBytes.Length; i += 6) - { - ushort uX = Utils.BytesToUInt16(posBytes, i); - ushort uY = Utils.BytesToUInt16(posBytes, i + 2); - ushort uZ = Utils.BytesToUInt16(posBytes, i + 4); + // UV texture map + Vector2 texPosMax = Vector2.Zero; + Vector2 texPosMin = Vector2.Zero; + byte[] texBytes = null; + if (subMeshMap.TryGetValue("TexCoord0", out OSD osdtcord0)) + { + texBytes = osdtcord0; + texPosMax = ((OSDMap)subMeshMap["TexCoord0Domain"])["Max"]; + texPosMin = ((OSDMap)subMeshMap["TexCoord0Domain"])["Min"]; + } - Vertex vx = new Vertex(); + // Extract the vertex position data + // If present normals and texture coordinates too + for (int i = 0; i < posBytes.Length; i += 6) + { + ushort uX = Utils.BytesToUInt16(posBytes, i); + ushort uY = Utils.BytesToUInt16(posBytes, i + 2); + ushort uZ = Utils.BytesToUInt16(posBytes, i + 4); - vx.Position = new Vector3( - Utils.UInt16ToFloat(uX, posMin.X, posMax.X), - Utils.UInt16ToFloat(uY, posMin.Y, posMax.Y), - Utils.UInt16ToFloat(uZ, posMin.Z, posMax.Z)); + Vertex vx = new Vertex(); - if (norBytes != null && norBytes.Length >= i + 4) - { - ushort nX = Utils.BytesToUInt16(norBytes, i); - ushort nY = Utils.BytesToUInt16(norBytes, i + 2); - ushort nZ = Utils.BytesToUInt16(norBytes, i + 4); - - vx.Normal = new Vector3( - Utils.UInt16ToFloat(nX, posMin.X, posMax.X), - Utils.UInt16ToFloat(nY, posMin.Y, posMax.Y), - Utils.UInt16ToFloat(nZ, posMin.Z, posMax.Z)); - } + vx.Position = new Vector3( + Utils.UInt16ToFloat(uX, posMin.X, posMax.X), + Utils.UInt16ToFloat(uY, posMin.Y, posMax.Y), + Utils.UInt16ToFloat(uZ, posMin.Z, posMax.Z)); - var vertexIndexOffset = oface.Vertices.Count * 4; + if (norBytes is not null && norBytes.Length >= i + 4) + { + ushort nX = Utils.BytesToUInt16(norBytes, i); + ushort nY = Utils.BytesToUInt16(norBytes, i + 2); + ushort nZ = Utils.BytesToUInt16(norBytes, i + 4); + + vx.Normal = new Vector3( + Utils.UInt16ToFloat(nX, posMin.X, posMax.X), + Utils.UInt16ToFloat(nY, posMin.Y, posMax.Y), + Utils.UInt16ToFloat(nZ, posMin.Z, posMax.Z)); + } - if (texBytes != null && texBytes.Length >= vertexIndexOffset + 4) - { - ushort tX = Utils.BytesToUInt16(texBytes, vertexIndexOffset); - ushort tY = Utils.BytesToUInt16(texBytes, vertexIndexOffset + 2); + var vertexIndexOffset = oface.Vertices.Count * 4; - vx.TexCoord = new Vector2( - Utils.UInt16ToFloat(tX, texPosMin.X, texPosMax.X), - Utils.UInt16ToFloat(tY, texPosMin.Y, texPosMax.Y)); - } + if (texBytes is not null && texBytes.Length >= vertexIndexOffset + 4) + { + ushort tX = Utils.BytesToUInt16(texBytes, vertexIndexOffset); + ushort tY = Utils.BytesToUInt16(texBytes, vertexIndexOffset + 2); - oface.Vertices.Add(vx); + vx.TexCoord = new Vector2( + Utils.UInt16ToFloat(tX, texPosMin.X, texPosMax.X), + Utils.UInt16ToFloat(tY, texPosMin.Y, texPosMax.Y)); } - byte[] triangleBytes = subMeshMap["TriangleList"]; - for (int i = 0; i < triangleBytes.Length; i += 6) - { - ushort v1 = (ushort)(Utils.BytesToUInt16(triangleBytes, i)); - oface.Indices.Add(v1); - ushort v2 = (ushort)(Utils.BytesToUInt16(triangleBytes, i + 2)); - oface.Indices.Add(v2); - ushort v3 = (ushort)(Utils.BytesToUInt16(triangleBytes, i + 4)); - oface.Indices.Add(v3); - } + oface.Vertices.Add(vx); + } - mesh.Faces.Add(oface); + byte[] triangleBytes = subMeshMap["TriangleList"]; + for (int i = 0; i < triangleBytes.Length; i += 6) + { + oface.Indices.Add(Utils.BytesToUInt16(triangleBytes, i)); + oface.Indices.Add(Utils.BytesToUInt16(triangleBytes, i + 2)); + oface.Indices.Add(Utils.BytesToUInt16(triangleBytes, i + 4)); } + + mesh.Faces.Add(oface); } } diff --git a/OpenMetaverseTypes/Matrix3x3.cs b/OpenMetaverseTypes/Matrix3x3.cs index a807808b..7d06ddc1 100644 --- a/OpenMetaverseTypes/Matrix3x3.cs +++ b/OpenMetaverseTypes/Matrix3x3.cs @@ -357,7 +357,7 @@ public static Matrix3x3 CreateFromEulers(float roll, float pitch, float yaw) public static Matrix3x3 CreateFromQuaternion(Quaternion rot) { - float x2 = rot.X + rot.X; + float x2 = rot.X + rot.X; float y2 = rot.Y + rot.Y; float z2 = rot.Z + rot.Z; diff --git a/OpenMetaverseTypes/OSUTF8.cs b/OpenMetaverseTypes/OSUTF8.cs index 6bffbacc..67b7f29a 100644 --- a/OpenMetaverseTypes/OSUTF8.cs +++ b/OpenMetaverseTypes/OSUTF8.cs @@ -51,48 +51,56 @@ public class osUTF8 public static readonly osUTF8 Empty = new osUTF8(); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public osUTF8() { - m_data = new byte[0]; + m_data = Array.Empty(); m_len = 0; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public osUTF8(int capacity) { m_data = new byte[capacity]; m_len = 0; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public osUTF8(byte[] source) { m_data = source; m_len = source.Length; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public osUTF8(byte[] source, int len) { m_data = source; m_len = len; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public osUTF8(osUTF8Slice source) { m_data = source.ToArray(); m_len = m_data.Length; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public osUTF8(osUTF8 source) { m_data = source.ToArray(); m_len = source.Length; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public osUTF8(string source) { m_data = Utils.StringToBytesNoTerm(source); m_len = m_data.Length; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public osUTF8(string source, int maxlen) { m_data = Utils.StringToBytesNoTerm(source, maxlen); @@ -120,26 +128,29 @@ public byte this[int i] { if (i >= m_len) i = m_len - 1; - if (i < 0) - i = 0; - else if (i >= m_data.Length) + if (i >= m_data.Length) i = m_data.Length - 1; - return m_data[i]; + if (i <= 0) + return Unsafe.As(ref MemoryMarshal.GetArrayDataReference(m_data)); + return Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(m_data), i)); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] set { if (i > 0 && i < m_len) - m_data[i] = value; + Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(m_data), i)) = value; } } public int Length { + [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return m_len; } } public int Capacity { + [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return m_data.Length; } } @@ -168,17 +179,17 @@ public override bool Equals(object obj) if (obj == null) return false; - if (obj is osUTF8) - return Equals((osUTF8)obj); + if (obj is osUTF8 osUTF8obj) + return Equals(osUTF8obj); - if (obj is osUTF8Slice) - return Equals((osUTF8Slice)obj); + if (obj is osUTF8Slice osUTF8Sliceobj) + return Equals(osUTF8Sliceobj); if (obj is string) return Equals((string)obj); - if (obj is byte[]) - return Equals((byte[])obj); + if (obj is byte[] byteobj) + return Equals(byteobj); return false; } @@ -281,7 +292,7 @@ public bool Equals(string s) public static bool operator !=(osUTF8 value1, osUTF8 value2) { if (value1 is null) - return !(value2 is null); + return value2 is not null; return !value1.Equals(value2); } @@ -389,6 +400,7 @@ public unsafe bool ACSIILowerEquals(string o) return true; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Clear() { m_len = 0; @@ -415,6 +427,7 @@ public byte[] ToArray() return b; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public byte[] GetArray() { return m_data; @@ -448,17 +461,17 @@ public void CheckCapacity(int needed) } } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendASCII(char c) { - CheckCapacity(1); - m_data[m_len] = (byte)c; - ++m_len; + Append((byte)c); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(byte c) { CheckCapacity(1); - m_data[m_len] = c; + Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(m_data), m_len)) = c; ++m_len; } @@ -524,7 +537,7 @@ public unsafe void AppendInt(sbyte v) public unsafe void AppendInt(byte v) { - CheckCapacity(4); + CheckCapacity(3); fixed (byte* d = m_data) m_len += Utils.UIntToByteString(v, d + m_len); } @@ -738,7 +751,7 @@ public bool StartsWith(string s) [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool StartsWith(byte b) { - return m_data[0] == b; + return Unsafe.As(ref MemoryMarshal.GetArrayDataReference(m_data)) == b; } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -750,7 +763,7 @@ public bool StartsWith(char b) [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool EndsWith(byte b) { - return m_data[m_len - 1] == b; + return Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(m_data), m_len - 1)) == b; } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -778,28 +791,15 @@ public unsafe bool EndsWith(osUTF8 other) public bool EndsWith(string s) { - osUTF8 other = new osUTF8(s); // yeack + osUTF8 other = new(s); // yeack return EndsWith(other); } public unsafe int IndexOf(byte b) { - if (m_len > 8) - { - fixed (byte* a = m_data) - { - for (int i = 0; i < m_len; ++i) - { - if (a[i] == b) - return i; - } - return -1; - } - } - for (int i = 0; i < m_len; ++i) { - if (m_data[i] == b) + if (Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(m_data), i)) == b) return i; } return -1; @@ -809,7 +809,7 @@ public int IndexOf(char b) { if (b < 0x80) return IndexOf((byte)b); - string s = new string(new char[] { b }); + string s = new(new char[] { b }); return IndexOf(s); } @@ -870,7 +870,7 @@ public int IndexOf(string s) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private bool checkAny(byte b, byte[] bytes) + private static bool checkAny(byte b, byte[] bytes) { for (int i = 0; i < bytes.Length; ++i) { @@ -881,7 +881,7 @@ private bool checkAny(byte b, byte[] bytes) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private bool checkAny(byte b, char[] chars) + private static bool checkAny(byte b, char[] chars) { for (int i = 0; i < chars.Length; ++i) { @@ -969,7 +969,7 @@ public osUTF8Slice[] Split(char b, bool ignoreEmpty = true) if (b < 0x80) return Split((byte)b, ignoreEmpty); - return new osUTF8Slice[0]; + return Array.Empty(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/OpenMetaverseTypes/OSUTF8Slice.cs b/OpenMetaverseTypes/OSUTF8Slice.cs index 21c5947d..ef8e4249 100644 --- a/OpenMetaverseTypes/OSUTF8Slice.cs +++ b/OpenMetaverseTypes/OSUTF8Slice.cs @@ -54,7 +54,7 @@ public class osUTF8Slice public osUTF8Slice() { - m_data = new byte[0]; + m_data = Array.Empty(); m_offset = 0; m_len = 0; } @@ -131,10 +131,10 @@ public byte this[int i] if (i >= m_len) i = m_len - 1; i += m_offset; - if (i < 0) - i = 0; - else if (i >= m_data.Length) + if (i >= m_data.Length) i = m_data.Length - 1; + if (i <= 0) + return Unsafe.As(ref MemoryMarshal.GetArrayDataReference(m_data)); return Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(m_data), i)); } set @@ -712,7 +712,7 @@ public string SubString(int start, int len) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private bool checkAny(byte b, byte[] bytes) + private static bool checkAny(byte b, byte[] bytes) { for (int i = 0; i < bytes.Length; ++i) { @@ -723,7 +723,7 @@ private bool checkAny(byte b, byte[] bytes) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private bool checkAny(byte b, char[] chars) + private static bool checkAny(byte b, char[] chars) { for (int i = 0; i < chars.Length; ++i) { @@ -1078,7 +1078,7 @@ public int IndexOf(char b) { if (b < 0x80) return IndexOf((byte)b); - string s = new string(new char[] { b }); + string s = new(new char[] { b }); return IndexOf(s); } @@ -1159,7 +1159,7 @@ public int IndexOf(string s) { if (string.IsNullOrEmpty(s)) return -1; - osUTF8 o = new osUTF8(s); + osUTF8 o = new(s); return IndexOf(o); } @@ -1279,14 +1279,14 @@ public osUTF8Slice[] Split(char b, bool ignoreEmpty = true) if (b < 0x80) return Split((byte)b, ignoreEmpty); - return new osUTF8Slice[0]; + return Array.Empty(); } public unsafe bool ReadLine(out osUTF8Slice line) { if (m_len == 0) { - line = new osUTF8Slice(new byte[0], 0, 0); + line = new osUTF8Slice(); return false; } diff --git a/OpenMetaverseTypes/UtilsConversions.cs b/OpenMetaverseTypes/UtilsConversions.cs index 565ba078..b1f0d423 100644 --- a/OpenMetaverseTypes/UtilsConversions.cs +++ b/OpenMetaverseTypes/UtilsConversions.cs @@ -40,9 +40,7 @@ namespace OpenMetaverse { public static partial class Utils { -// public static readonly bool NoAlignment = CheckNeedAlignment(); public static readonly bool CanDirectCopyLE = CheckNeedAlignment(); - //public static readonly bool CanDirectCopyBE = CheckDirectCopyBE(); [StructLayout(LayoutKind.Sequential, Size = 16, Pack = 1)] public struct Bytes16 { } @@ -100,17 +98,7 @@ public unsafe static bool CheckNeedAlignment() return false; } -/* - static bool CheckDirectCopyLE() - { - return BitConverter.IsLittleEndian && NoAlignment; - } - static bool CheckDirectCopyBE() - { - return !BitConverter.IsLittleEndian && NoAlignment; - } -*/ #region String Arrays private static readonly string[] _AssetTypeNames = new string[] @@ -385,51 +373,50 @@ public static int CombineHash(int a, int b) return 65599 * a + b; } + #region BytesTo + /// - /// Convert the first two bytes starting in the byte array in - /// little endian ordering to a signed short integer + /// Convert the first two bytes starting in the byte array in native endian ordeing + /// to signed short integer /// /// An array two bytes or longer /// A signed short integer, will be zero if a short can't be /// read at the given position [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static unsafe short BytesToInt16(byte[] bytes) + public static short BytesToInt16(byte[] bytes) { - //if (bytes.Length < 2 ) return 0; - if (CanDirectCopyLE) - { - return Unsafe.As(ref MemoryMarshal.GetArrayDataReference(bytes)); - } - else - return (short)(bytes[0] | (bytes[1] << 8)); + return Unsafe.ReadUnaligned(ref MemoryMarshal.GetArrayDataReference(bytes)); } - #region BytesTo + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static short BytesToInt16(ref byte bytes) + { + return Unsafe.ReadUnaligned(ref bytes); + } /// /// Convert the first two bytes starting at the given position in - /// little endian ordering to a signed short integer + /// native endian ordering to a signed short integer /// /// An array two bytes or longer /// Position in the array to start reading /// A signed short integer, will be zero if a short can't be /// read at the given position [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static unsafe short BytesToInt16(byte[] bytes, int pos) + public static short BytesToInt16(byte[] bytes, int pos) { - //if (bytes.Length < pos + 2) return 0; - if (CanDirectCopyLE) - { - return Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(bytes), pos)); - } - else - return (short)(bytes[pos] | (bytes[pos + 1] << 8)); + return Unsafe.ReadUnaligned(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(bytes), pos)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static short BytesToInt16(ref byte bytes, int pos) + { + return Unsafe.ReadUnaligned(ref Unsafe.Add(ref bytes, pos)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static unsafe short BytesToInt16(byte* bytes) { - //if (bytes.Length < pos + 2) return 0; if (CanDirectCopyLE) { return *(short*)bytes; @@ -439,26 +426,24 @@ public static unsafe short BytesToInt16(byte* bytes) } /// - /// Convert the first four bytes starting at the given position in - /// little endian ordering to a signed integer + /// Convert the first four bytes starting at the given position in native endian order + /// to a signed integer /// /// An array four bytes or longer /// Position to start reading the int from /// A signed integer, will be zero if an int can't be read /// at the given position [MethodImpl(MethodImplOptions.AggressiveInlining)] - public unsafe static int BytesToInt(byte[] bytes, int pos) + public static int BytesToInt(byte[] bytes, int pos) { - if (CanDirectCopyLE) - { - //if (bytes.Length < pos + 4) return 0; - return Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(bytes), pos)); - } + //if (bytes.Length < pos + 4) return 0; + return Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(bytes), pos)); + } - return bytes[pos] | - (bytes[pos + 1] << 8) | - (bytes[pos + 2] << 16) | - (bytes[pos + 3] << 24); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int BytesToInt(ref byte bytes, int pos) + { + return Unsafe.ReadUnaligned(ref Unsafe.Add(ref bytes, pos)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -476,17 +461,15 @@ public unsafe static int BytesToInt(byte* bytes) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public unsafe static int BytesToIntSafepos(byte[] bytes, int pos) + public static int BytesToIntSafepos(byte[] bytes, int pos) { - if (CanDirectCopyLE) - { - return Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(bytes), pos)); - } + return Unsafe.ReadUnaligned(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(bytes), pos)); + } - return bytes[pos] | - (bytes[pos + 1] << 8) | - (bytes[pos + 2] << 16) | - (bytes[pos + 3] << 24); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int BytesToIntSafepos(ref byte bytes, int pos) + { + return Unsafe.ReadUnaligned(ref Unsafe.Add(ref bytes, pos)); } /// @@ -497,17 +480,15 @@ public unsafe static int BytesToIntSafepos(byte[] bytes, int pos) /// A signed integer, will be zero if the array contains /// less than four bytes [MethodImpl(MethodImplOptions.AggressiveInlining)] - public unsafe static int BytesToInt(byte[] bytes) + public static int BytesToInt(byte[] bytes) { - if (CanDirectCopyLE) - { - return Unsafe.As(ref MemoryMarshal.GetArrayDataReference(bytes)); - } - else - return bytes[0] | - (bytes[1] << 8) | - (bytes[2] << 16) | - (bytes[3] << 24); + return Unsafe.ReadUnaligned(ref MemoryMarshal.GetArrayDataReference(bytes)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int BytesToInt(ref byte bytes) + { + return Unsafe.ReadUnaligned(ref bytes); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -536,22 +517,15 @@ public static int BytesToIntBig(byte[] bytes, int pos) /// A signed long integer, will be zero if the array contains /// less than eight bytes [MethodImpl(MethodImplOptions.AggressiveInlining)] - public unsafe static long BytesToInt64(byte[] bytes) + public static long BytesToInt64(byte[] bytes) { - if (CanDirectCopyLE) - { - return Unsafe.As(ref MemoryMarshal.GetArrayDataReference(bytes)); - } - else - return - bytes[0] | - ((long)bytes[1] << 8) | - ((long)bytes[2] << 16) | - ((long)bytes[3] << 24) | - ((long)bytes[4] << 32) | - ((long)bytes[5] << 40) | - ((long)bytes[6] << 48) | - ((long)bytes[7] << 56); + return Unsafe.ReadUnaligned(ref MemoryMarshal.GetArrayDataReference(bytes)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static long BytesToInt64(ref byte bytes) + { + return Unsafe.ReadUnaligned(ref bytes); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -596,42 +570,28 @@ public unsafe static long BytesToInt64(byte* bytes) /// A signed long integer, will be zero if a long can't be read /// at the given position [MethodImpl(MethodImplOptions.AggressiveInlining)] - public unsafe static long BytesToInt64(byte[] bytes, int pos) + public static long BytesToInt64(byte[] bytes, int pos) { - if (CanDirectCopyLE) - { - if (bytes.Length < pos + 8) return 0; - return Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(bytes), pos)); - } - else - return - (bytes[pos] | - ((long)bytes[pos + 1] << 8)) | - ((long)bytes[pos + 2] << 16) | - ((long)bytes[pos + 3] << 24) | - ((long)bytes[pos + 4] << 32) | - ((long)bytes[pos + 5] << 40) | - ((long)bytes[pos + 6] << 48) | - ((long)bytes[pos + 7] << 56); + if (bytes.Length < pos + 8) return 0; + return Unsafe.ReadUnaligned(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(bytes), pos)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public unsafe static long BytesToInt64Safepos(byte[] bytes, int pos) + public static long BytesToInt64(ref byte bytes, int pos) { - if (CanDirectCopyLE) - { - return Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(bytes), pos)); - } - else - return - (bytes[pos] | - ((long)bytes[pos + 1] << 8)) | - ((long)bytes[pos + 2] << 16) | - ((long)bytes[pos + 3] << 24) | - ((long)bytes[pos + 4] << 32) | - ((long)bytes[pos + 5] << 40) | - ((long)bytes[pos + 6] << 48) | - ((long)bytes[pos + 7] << 56); + return Unsafe.ReadUnaligned(ref Unsafe.Add(ref bytes, pos)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static long BytesToInt64Safepos(byte[] bytes, int pos) + { + return Unsafe.ReadUnaligned(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(bytes), pos)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static long BytesToInt64Safepos(ref byte bytes, int pos) + { + return Unsafe.ReadUnaligned(ref Unsafe.Add(ref bytes, pos)); } /// @@ -643,21 +603,20 @@ public unsafe static long BytesToInt64Safepos(byte[] bytes, int pos) /// An unsigned short, will be zero if a ushort can't be read /// at the given position [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static unsafe ushort BytesToUInt16(byte[] bytes, int pos) + public static ushort BytesToUInt16(byte[] bytes, int pos) { - //if (bytes.Length < pos + 2) return 0; - if (CanDirectCopyLE) - { - return Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(bytes), pos)); - } - else - return (ushort)(bytes[pos] + (bytes[pos + 1] << 8)); + return Unsafe.ReadUnaligned(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(bytes), pos)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ushort BytesToUInt16(ref byte bytes, int pos) + { + return Unsafe.ReadUnaligned(ref Unsafe.Add(ref bytes, pos)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static unsafe ushort BytesToUInt16(byte* bytes) { - //if (bytes.Length < pos + 2) return 0; if (CanDirectCopyLE) return *(ushort*)bytes; else @@ -665,21 +624,22 @@ public static unsafe ushort BytesToUInt16(byte* bytes) } /// - /// Convert two bytes in little endian ordering to an unsigned short + /// Convert two bytes in native endian ordeing to an unsigned short /// /// Byte array containing the ushort /// An unsigned short, will be zero if a ushort can't be /// read [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static unsafe ushort BytesToUInt16(byte[] bytes) + public static ushort BytesToUInt16(byte[] bytes) { //if (bytes.Length < 2) return 0; - if (CanDirectCopyLE) - { - return Unsafe.As(ref MemoryMarshal.GetArrayDataReference(bytes)); - } - else - return (ushort)(bytes[0] + (bytes[1] << 8)); + return Unsafe.ReadUnaligned(ref MemoryMarshal.GetArrayDataReference(bytes)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ushort BytesToUInt16(ref byte bytes) + { + return Unsafe.ReadUnaligned(ref bytes); } /// @@ -691,34 +651,22 @@ public static unsafe ushort BytesToUInt16(byte[] bytes) /// An unsigned integer, will be zero if a uint can't be read /// at the given position [MethodImpl(MethodImplOptions.AggressiveInlining)] - public unsafe static uint BytesToUInt(byte[] bytes, int pos) + public static uint BytesToUInt(byte[] bytes, int pos) { - if (CanDirectCopyLE) - { - if (bytes.Length < pos + 4) return 0; - return Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(bytes), pos)); - } - else - return (uint)( - (bytes[pos]) | - (bytes[pos + 1] << 8) | - (bytes[pos + 2] << 16) | - (bytes[pos + 3] << 24)); + if (bytes.Length < pos + 4) return 0; + return Unsafe.ReadUnaligned(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(bytes), pos)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public unsafe static uint BytesToUIntSafepos(byte[] bytes, int pos) + public static uint BytesToUIntSafepos(byte[] bytes, int pos) { - if (CanDirectCopyLE) - { - return Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(bytes), pos)); - } - else - return (uint)( - (bytes[pos]) | - (bytes[pos + 1] << 8) | - (bytes[pos + 2] << 16) | - (bytes[pos + 3] << 24)); + return Unsafe.ReadUnaligned(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(bytes), pos)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static uint BytesToUIntSafepos(ref byte bytes, int pos) + { + return Unsafe.ReadUnaligned(ref Unsafe.Add(ref bytes, pos)); } /// @@ -729,18 +677,15 @@ public unsafe static uint BytesToUIntSafepos(byte[] bytes, int pos) /// An unsigned integer, will be zero if the array contains /// less than four bytes [MethodImpl(MethodImplOptions.AggressiveInlining)] - public unsafe static uint BytesToUInt(byte[] bytes) + public static uint BytesToUInt(byte[] bytes) { - if (CanDirectCopyLE) - { - return Unsafe.As(ref MemoryMarshal.GetArrayDataReference(bytes)); - } - else - return (uint)( - bytes[0] | - (bytes[1] << 8) | - (bytes[2] << 16) | - (bytes[3] << 24)); + return Unsafe.ReadUnaligned(ref MemoryMarshal.GetArrayDataReference(bytes)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static uint BytesToUInt(ref byte bytes) + { + return Unsafe.ReadUnaligned(ref bytes); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -766,42 +711,28 @@ public unsafe static uint BytesToUInt(byte* bytes) /// An unsigned 64-bit integer, will be zero if the array /// contains less than eight bytes [MethodImpl(MethodImplOptions.AggressiveInlining)] - public unsafe static ulong BytesToUInt64(byte[] bytes, int pos) + public static ulong BytesToUInt64(byte[] bytes, int pos) { if (bytes.Length < pos + 8) return 0; - if (CanDirectCopyLE) - { - return Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(bytes), pos)); - } - else - return (ulong)( - bytes[pos] | - ((long)bytes[pos + 1] << 8) | - ((long)bytes[pos + 2] << 16) | - ((long)bytes[pos + 3] << 24) | - ((long)bytes[pos + 4] << 32) | - ((long)bytes[pos + 5] << 40) | - ((long)bytes[pos + 6] << 48) | - ((long)bytes[pos + 7] << 56)); + return Unsafe.ReadUnaligned(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(bytes), pos)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public unsafe static ulong BytesToUInt64Safepos(byte[] bytes, int pos) + public static ulong BytesToUInt64(ref byte bytes, int pos) { - if (CanDirectCopyLE) - { - return Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(bytes), pos)); - } - else - return (ulong)( - bytes[pos] | - ((long)bytes[pos + 1] << 8) | - ((long)bytes[pos + 2] << 16) | - ((long)bytes[pos + 3] << 24) | - ((long)bytes[pos + 4] << 32) | - ((long)bytes[pos + 5] << 40) | - ((long)bytes[pos + 6] << 48) | - ((long)bytes[pos + 7] << 56)); + return Unsafe.ReadUnaligned(ref Unsafe.Add(ref bytes, pos)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ulong BytesToUInt64Safepos(byte[] bytes, int pos) + { + return Unsafe.ReadUnaligned(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(bytes), pos)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ulong BytesToUInt64Safepos(ref byte bytes, int pos) + { + return Unsafe.ReadUnaligned(ref Unsafe.Add(ref bytes, pos)); } /// @@ -812,22 +743,15 @@ public unsafe static ulong BytesToUInt64Safepos(byte[] bytes, int pos) /// An unsigned 64-bit integer, will be zero if the array /// contains less than eight bytes [MethodImpl(MethodImplOptions.AggressiveInlining)] - public unsafe static ulong BytesToUInt64(byte[] bytes) + public static ulong BytesToUInt64(byte[] bytes) { - if (CanDirectCopyLE) - { - return Unsafe.As(ref MemoryMarshal.GetArrayDataReference(bytes)); - } - else - return (ulong)( - bytes[0] | - ((long)bytes[1] << 8) | - ((long)bytes[2] << 16) | - ((long)bytes[3] << 24) | - ((long)bytes[4] << 32) | - ((long)bytes[5] << 40) | - ((long)bytes[6] << 48) | - ((long)bytes[7] << 56)); + return Unsafe.ReadUnaligned(ref MemoryMarshal.GetArrayDataReference(bytes)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static ulong BytesToUInt64(ref byte bytes) + { + return Unsafe.ReadUnaligned(ref bytes); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -850,7 +774,7 @@ public unsafe static ulong BytesToUInt64(byte* bytes) } /// - /// Convert four bytes in little endian ordering to a floating point + /// Convert four bytes in native endian ordeing to a floating point /// value /// /// Byte array containing a little ending floating @@ -859,9 +783,15 @@ public unsafe static ulong BytesToUInt64(byte* bytes) /// the byte array /// Single precision value [MethodImpl(MethodImplOptions.AggressiveInlining)] - public unsafe static float BytesToFloat(byte[] bytes) + public static float BytesToFloat(byte[] bytes) + { + return Unsafe.ReadUnaligned(ref MemoryMarshal.GetArrayDataReference(bytes)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float BytesToFloat(ref byte bytes) { - return Unsafe.As(ref MemoryMarshal.GetArrayDataReference(bytes)); + return Unsafe.ReadUnaligned(ref bytes); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -872,21 +802,39 @@ public unsafe static float BytesToFloat(byte* bytes) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public unsafe static float BytesToFloat(byte[] bytes, int pos) + public static float BytesToFloat(byte[] bytes, int pos) + { + return Unsafe.ReadUnaligned(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(bytes), pos)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float BytesToFloat(ref byte bytes, int pos) + { + return Unsafe.ReadUnaligned(ref Unsafe.Add(ref bytes, pos)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float BytesToFloatSafepos(byte[] bytes, int pos) { - return Unsafe.As(ref bytes[pos]); + return Unsafe.ReadUnaligned(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(bytes), pos)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public unsafe static float BytesToFloatSafepos(byte[] bytes, int pos) + public static float BytesToFloatSafepos(ref byte bytes, int pos) { - return Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(bytes), pos)); + return Unsafe.ReadUnaligned(ref Unsafe.Add(ref bytes, pos)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public unsafe static double BytesToDouble(byte[] bytes) + public static double BytesToDouble(byte[] bytes) { - return Unsafe.As(ref MemoryMarshal.GetArrayDataReference(bytes)); + return Unsafe.ReadUnaligned(ref MemoryMarshal.GetArrayDataReference(bytes)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static double BytesToDouble(ref byte bytes) + { + return Unsafe.ReadUnaligned(ref bytes); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -904,15 +852,27 @@ public unsafe static double BytesToDouble(byte* bytes) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public unsafe static double BytesToDouble(byte[] bytes, int pos) + public static double BytesToDouble(byte[] bytes, int pos) { - return Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(bytes), pos)); + return Unsafe.ReadUnaligned(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(bytes), pos)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public unsafe static double BytesToDoubleSafepos(byte[] bytes, int pos) + public static double BytesToDouble(ref byte bytes, int pos) { - return Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(bytes), pos)); + return Unsafe.ReadUnaligned(ref Unsafe.Add(ref bytes, pos)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static double BytesToDoubleSafepos(byte[] bytes, int pos) + { + return Unsafe.ReadUnaligned(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(bytes), pos)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static double BytesToDoubleSafepos(ref byte bytes, int pos) + { + return Unsafe.ReadUnaligned(ref Unsafe.Add(ref bytes, pos)); } #endregion BytesTo @@ -937,7 +897,19 @@ public static void Int16ToBytes(Stream ms, short value) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Int16ToBytes(short value, byte[] dest, int pos) { - Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(dest), pos)) = value; + Unsafe.WriteUnaligned(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(dest), pos), value); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void Int16ToBytes(short value, ref byte dest, int pos) + { + Unsafe.WriteUnaligned(ref Unsafe.Add(ref dest, pos), value); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void Int16ToBytes(short value, ref byte dest) + { + Unsafe.WriteUnaligned(ref dest, value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -965,8 +937,19 @@ public static byte[] UInt16ToBytes(ushort value) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void UInt16ToBytes(ushort value, byte[] dest, int pos) { - Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(dest), pos)) = value; + Unsafe.WriteUnaligned(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(dest), pos), value); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void UInt16ToBytes(ushort value, ref byte dest, int pos) + { + Unsafe.WriteUnaligned(ref Unsafe.Add(ref dest, pos), value); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void UInt16ToBytes(ushort value, ref byte dest) + { + Unsafe.WriteUnaligned(ref dest, value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -1017,22 +1000,10 @@ public static void IntToBytes(Stream ms, int value) /// The integer to convert /// A four byte little endian array [MethodImpl(MethodImplOptions.AggressiveInlining)] - public unsafe static byte[] IntToBytes(int value) + public static byte[] IntToBytes(int value) { byte[] bytes = new byte[4]; - if (CanDirectCopyLE) - { - //Unsafe.As(ref bytes[0]) = value; - fixed (byte* p = bytes) - *(int*)p = value; - } - else - { - bytes[0] = (byte)value; - bytes[1] = (byte)(value >> 8); - bytes[2] = (byte)(value >> 16); - bytes[3] = (byte)(value >> 24); - } + Unsafe.As(ref MemoryMarshal.GetArrayDataReference(bytes)) = value; return bytes; } @@ -1040,17 +1011,19 @@ public unsafe static byte[] IntToBytes(int value) public unsafe static void IntToBytes(int value, byte[] dest, int pos) { if (dest.Length < pos + 4) return; - if (CanDirectCopyLE) - { - Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(dest), pos)) = value; - } - else - { - dest[pos] = (byte)(value); - dest[pos + 1] = (byte)((value >> 8)); - dest[pos + 2] = (byte)((value >> 16)); - dest[pos + 3] = (byte)((value >> 24)); - } + Unsafe.WriteUnaligned(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(dest), pos), value); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static void IntToBytes(int value, ref byte dest, int pos) + { + Unsafe.WriteUnaligned(ref Unsafe.Add(ref dest, pos), value); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static void IntToBytes(int value, ref byte dest) + { + Unsafe.WriteUnaligned(ref dest, value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void IntToBytes(int value, byte* dest, int pos) @@ -1087,17 +1060,25 @@ public unsafe static void IntToBytes(int value, byte* dest) [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void IntToBytesSafepos(int value, byte[] dest, int pos) { - if (CanDirectCopyLE) - { - Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(dest), pos)) = value; - } - else - { - dest[pos] = (byte)(value); - dest[pos + 1] = (byte)((value >> 8)); - dest[pos + 2] = (byte)((value >> 16)); - dest[pos + 3] = (byte)((value >> 24)); - } + Unsafe.WriteUnaligned(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(dest), pos), value); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static void IntToBytesSafepos(int value, byte[] dest) + { + Unsafe.WriteUnaligned(ref MemoryMarshal.GetArrayDataReference(dest), value); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static void IntToBytesSafepos(int value, ref byte dest, int pos) + { + Unsafe.WriteUnaligned(ref Unsafe.Add(ref dest, pos), value); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static void IntToBytesSafepos(int value, ref byte dest) + { + Unsafe.WriteUnaligned(ref dest, value); } /// @@ -1161,7 +1142,8 @@ public unsafe static void UIntToBytes(uint value, byte* dest) [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void UIntToBytes(uint value, byte[] dest, int pos) { - IntToBytes((int)value, dest, pos); + if (dest.Length < pos + 4) return; + Unsafe.WriteUnaligned(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(dest), pos), value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -1173,7 +1155,25 @@ public unsafe static void UIntToBytes(uint value, byte* dest, int pos) [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void UIntToBytesSafepos(uint value, byte[] dest, int pos) { - IntToBytesSafepos((int)value, dest, pos); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(dest), pos), value); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static void UIntToBytesSafepos(uint value, byte[] dest) + { + Unsafe.WriteUnaligned(ref MemoryMarshal.GetArrayDataReference(dest), value); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static void UIntToBytesSafepos(uint value, ref byte dest, int pos) + { + Unsafe.WriteUnaligned(ref Unsafe.Add(ref dest, pos), value); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static void UIntToBytesSafepos(uint value, ref byte dest) + { + Unsafe.WriteUnaligned(ref dest, value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -1191,44 +1191,15 @@ public static void UIntToBytesBig(uint value, byte[] dest, int pos) public unsafe static byte[] Int64ToBytes(long value) { byte[] bytes = new byte[8]; - if (CanDirectCopyLE) - { - Unsafe.As(ref MemoryMarshal.GetArrayDataReference(bytes)) = value; - } - else - { - bytes[0] = (byte)value; - bytes[1] = (byte)(value >> 8); - bytes[2] = (byte)(value >> 16); - bytes[3] = (byte)(value >> 24); - bytes[4] = (byte)(value >> 32); - bytes[5] = (byte)(value >> 40); - bytes[6] = (byte)(value >> 48); - bytes[7] = (byte)(value >> 56); - } + Unsafe.As(ref MemoryMarshal.GetArrayDataReference(bytes)) = value; return bytes; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void Int64ToBytes(long value, byte[] dest, int pos) { - if (CanDirectCopyLE) - { - //Unsafe.As(ref dest[pos]) = value; if (dest.Length < pos + 8) return; - Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(dest), pos)) = value; - } - else - { - dest[pos] = (byte)value; - dest[pos + 1] = (byte)(value >> 8); - dest[pos + 2] = (byte)(value >> 16); - dest[pos + 3] = (byte)(value >> 24); - dest[pos + 4] = (byte)(value >> 32); - dest[pos + 5] = (byte)(value >> 40); - dest[pos + 6] = (byte)(value >> 48); - dest[pos + 7] = (byte)(value >> 56); - } + Unsafe.WriteUnaligned(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(dest), pos), value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -1274,21 +1245,25 @@ public unsafe static void Int64ToBytes(long value, byte* dest) [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void Int64ToBytesSafepos(long value, byte[] dest, int pos) { - if (CanDirectCopyLE) - { - Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(dest), pos)) = value; - } - else - { - dest[pos] = (byte)value; - dest[pos + 1] = (byte)(value >> 8); - dest[pos + 2] = (byte)(value >> 16); - dest[pos + 3] = (byte)(value >> 24); - dest[pos + 4] = (byte)(value >> 32); - dest[pos + 5] = (byte)(value >> 40); - dest[pos + 6] = (byte)(value >> 48); - dest[pos + 7] = (byte)(value >> 56); - } + Unsafe.WriteUnaligned(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(dest), pos), value); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static void Int64ToBytesSafepos(long value, byte[] dest) + { + Unsafe.WriteUnaligned(ref MemoryMarshal.GetArrayDataReference(dest), value); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static void Int64ToBytesSafepos(long value, ref byte dest, int pos) + { + Unsafe.WriteUnaligned(ref Unsafe.Add(ref dest, pos), value); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static void Int64ToBytesSafepos(long value, ref byte dest) + { + Unsafe.WriteUnaligned(ref dest, value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -1397,13 +1372,25 @@ public unsafe static void UInt64ToBytes(ulong value, byte* dest, int pos) [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void UInt64ToBytesSafepos(ulong value, byte[] dest, int pos) { - Int64ToBytesSafepos((long)value, dest, pos); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(dest), pos), value); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void UInt64ToBytesSafepos(ulong value, byte[] dest) + { + Unsafe.WriteUnaligned(ref MemoryMarshal.GetArrayDataReference(dest), value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void UInt64ToBytesBig(ulong value, byte[] dest, int pos) + public static void UInt64ToBytesSafepos(ulong value, ref byte dest, int pos) { - Int64ToBytesBig((long) value, dest, pos); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref dest, pos), value); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void UInt64ToBytesSafepos(ulong value, ref byte dest) + { + Unsafe.WriteUnaligned(ref dest, value); } /// @@ -1426,9 +1413,9 @@ public unsafe static void FloatToBytes(Stream ms, float value) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public unsafe static void FloatToBytes(float value, byte[] dest, int pos) + public static void FloatToBytes(float value, byte[] dest, int pos) { - Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(dest), pos)) = value; + Unsafe.WriteUnaligned(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(dest), pos), value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -1445,9 +1432,27 @@ public unsafe static void FloatToBytes(float value, byte* dest) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public unsafe static void FloatToBytesSafepos(float value, byte[] dest, int pos) + public static void FloatToBytesSafepos(float value, byte[] dest, int pos) { - Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(dest), pos)) = value; + Unsafe.WriteUnaligned(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(dest), pos), value); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void FloatToBytesSafepos(float value, ref byte dest, int pos) + { + Unsafe.WriteUnaligned(ref Unsafe.Add(ref dest, pos), value); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void FloatToBytesSafepos(float value, byte[] dest) + { + Unsafe.WriteUnaligned(ref MemoryMarshal.GetArrayDataReference(dest), value); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void FloatToBytesSafepos(float value, ref byte dest) + { + Unsafe.WriteUnaligned(ref dest, value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -1594,9 +1599,9 @@ public static string BytesToHexString(byte[] bytes, int length, string fieldName /// /// The string to convert /// A null-terminated UTF8 byte array - public static byte[] StringToBytes(string str) + public static byte[] StringToBytes(ReadOnlySpan str) { - if (string.IsNullOrEmpty(str)) + if (str.Length == 0) return Array.Empty(); int nbytes = osUTF8GetBytesCount(str, out int sourcelen); @@ -1608,9 +1613,9 @@ public static byte[] StringToBytes(string str) return dstarray; } - public static byte[] StringToBytes(string str, int maxlen) + public static byte[] StringToBytes(ReadOnlySpan str, int maxlen) { - if (string.IsNullOrEmpty(str)) + if (str.Length == 0) return Array.Empty(); int nbytes = osUTF8GetBytesCount(str, maxlen -1, out int sourcelen); @@ -1622,9 +1627,9 @@ public static byte[] StringToBytes(string str, int maxlen) return dstarray; } - public static byte[] StringToBytesNoTerm(string str) + public static byte[] StringToBytesNoTerm(ReadOnlySpan str) { - if (string.IsNullOrEmpty(str)) + if (str.Length == 0) return Array.Empty(); int nbytes = osUTF8GetBytesCount(str, out int sourcelen); @@ -1635,9 +1640,9 @@ public static byte[] StringToBytesNoTerm(string str) return dstarray; } - public static byte[] StringToBytesNoTerm(string str, int maxlen) + public static byte[] StringToBytesNoTerm(ReadOnlySpan str, int maxlen) { - if (string.IsNullOrEmpty(str)) + if (str.Length == 0) return Array.Empty(); int nbytes = osUTF8GetBytesCount(str, maxlen, out int sourcelen); @@ -1648,7 +1653,7 @@ public static byte[] StringToBytesNoTerm(string str, int maxlen) return dstarray; } - public static unsafe int osUTF8Getbytes(string source, int srclenght, byte[] destiny, int maxdstlen) + public static unsafe int osUTF8Getbytes(ReadOnlySpan source, int srclenght, byte[] destiny, int maxdstlen) { int ret = 0; char c; @@ -1723,9 +1728,9 @@ public static unsafe int osUTF8Getbytes(string source, int srclenght, byte[] des return ret; } - public static unsafe bool osUTF8TryGetbytes(string srcstr, ref int srcstart, byte[] dstarray, ref int pos) + public static unsafe bool osUTF8TryGetbytes(ReadOnlySpan srcstr, ref int srcstart, byte[] dstarray, ref int pos) { - if (string.IsNullOrEmpty(srcstr)) + if (srcstr.Length == 0) return true; bool ret = false; @@ -1753,77 +1758,276 @@ public static unsafe bool osUTF8TryGetbytes(string srcstr, ref int srcstart, byt continue; } - if (c < 0x800) - { - free -= 2; - if (free <= 0) - { - --src; - break; - } - *dst++ = (byte)(0xC0 | (c >> 6)); - *dst++ = (byte)(0x80 | (c & 0x3F)); - continue; - } + if (c < 0x800) + { + free -= 2; + if (free <= 0) + { + --src; + break; + } + *dst++ = (byte)(0xC0 | (c >> 6)); + *dst++ = (byte)(0x80 | (c & 0x3F)); + continue; + } + + if (c >= 0xD800 && c < 0xE000) + { + if (c >= 0xDC00) + continue; // ignore invalid + if (src > srcend1) + break; + + int a = c; + c = *src++; + + if (c < 0xDC00 || c > 0xDFFF) + continue; // ignore invalid + + free -= 4; + if (free <= 0) + { + src -= 2; + break; + } + + a = (a << 10) + c - 0x35fdc00; + + *dst++ = (byte)(0xF0 | (a >> 18)); + *dst++ = (byte)(0x80 | ((a >> 12) & 0x3f)); + *dst++ = (byte)(0x80 | ((a >> 6) & 0x3f)); + *dst++ = (byte)(0x80 | (a & 0x3f)); + continue; + } + + free -= 3; + if (free <= 0) + { + --src; + break; + } + + *dst++ = (byte)(0xE0 | (c >> 12)); + *dst++ = (byte)(0x80 | ((c >> 6) & 0x3f)); + *dst++ = (byte)(0x80 | (c & 0x3f)); + } + + pos = (int)(dst - dstbase); + srcstart = (int)(src - srcbase); + if (src == srcend) + ret = true; + } + } + return ret; + } + + public static int SingleCharToUTF8(char c, out byte[] bytes) + { + if (c <= 0x7f) + { + bytes = new byte[1] { (byte)c }; + return 1; + } + + if (c < 0x800) + { + bytes = new byte[2] + { + (byte)(0xC0 | (c >> 6)), + (byte)(0x80 | (c & 0x3F)) + }; + return 2; + } + + if (c >= 0xD800 && c < 0xE000) + { + bytes = Array.Empty(); + if (c >= 0xDC00) + return 0; // ignore invalid + + /* ignore multi char + + int a = c; + c = *src++; + + if (c < 0xDC00 || c > 0xDFFF) + continue; // ignore invalid + + a = (a << 10) + c - 0x35fdc00; + + *dst++ = (byte)(0xF0 | (a >> 18)); + *dst++ = (byte)(0x80 | ((a >> 12) & 0x3f)); + *dst++ = (byte)(0x80 | ((a >> 6) & 0x3f)); + *dst++ = (byte)(0x80 | (a & 0x3f)); + */ + return -1; + } + + bytes = new byte[3] + { + (byte)(0xE0 | (c >> 12)), + (byte)(0x80 | ((c >> 6) & 0x3f)), + (byte)(0x80 | (c & 0x3f)) + }; + return 3; + } + + public static unsafe int SingleCharToUTF8(char c, byte[] dstarray, ref int pos) + { + int free = dstarray.Length - pos; + if (c <= 0x7f) + { + if(free < 1) + return 0; + dstarray[pos++] = (byte)c; + return 1; + } + + if (c < 0x800) + { + if (free < 2) + return 0; + dstarray[pos++] = (byte)(0xC0 | (c >> 6)); + dstarray[pos++] = (byte)(0x80 | (c & 0x3F)); + return 2; + } + + if (c >= 0xD800 && c < 0xE000) + { + if (c >= 0xDC00) + return 0; // ignore invalid + /* + int a = c; + c = *src++; + + if (c < 0xDC00 || c > 0xDFFF) + continue; // ignore invalid + + free -= 4; + if (free <= 0) + { + src -= 2; + break; + } + + a = (a << 10) + c - 0x35fdc00; + + *dst++ = (byte)(0xF0 | (a >> 18)); + *dst++ = (byte)(0x80 | ((a >> 12) & 0x3f)); + *dst++ = (byte)(0x80 | ((a >> 6) & 0x3f)); + *dst++ = (byte)(0x80 | (a & 0x3f)); + continue; + */ + return -1; + } + + if (free < 3) + return 0; + + dstarray[pos++] = (byte)(0xE0 | (c >> 12)); + dstarray[pos++] = (byte)(0x80 | ((c >> 6) & 0x3f)); + dstarray[pos++] = (byte)(0x80 | (c & 0x3f)); + return 3; + } + + public static unsafe int SingleCharToUTF8safepos(char c, byte[] dstarray, ref int pos) + { + if (c <= 0x7f) + { + dstarray[pos++] = (byte)c; + return 1; + } + + if (c < 0x800) + { + dstarray[pos++] = (byte)(0xC0 | (c >> 6)); + dstarray[pos++] = (byte)(0x80 | (c & 0x3F)); + return 2; + } - if (c >= 0xD800 && c < 0xE000) - { - if (c >= 0xDC00) - continue; // ignore invalid - if (src > srcend1) - break; + if (c >= 0xD800 && c < 0xE000) + { + if (c >= 0xDC00) + return 0; // ignore invalid + /* + int a = c; + c = *src++; - int a = c; - c = *src++; + if (c < 0xDC00 || c > 0xDFFF) + continue; // ignore invalid - if (c < 0xDC00 || c > 0xDFFF) - continue; // ignore invalid + free -= 4; + if (free <= 0) + { + src -= 2; + break; + } - free -= 4; - if (free <= 0) - { - src -= 2; - break; - } + a = (a << 10) + c - 0x35fdc00; - a = (a << 10) + c - 0x35fdc00; + *dst++ = (byte)(0xF0 | (a >> 18)); + *dst++ = (byte)(0x80 | ((a >> 12) & 0x3f)); + *dst++ = (byte)(0x80 | ((a >> 6) & 0x3f)); + *dst++ = (byte)(0x80 | (a & 0x3f)); + continue; + */ + return -1; + } - *dst++ = (byte)(0xF0 | (a >> 18)); - *dst++ = (byte)(0x80 | ((a >> 12) & 0x3f)); - *dst++ = (byte)(0x80 | ((a >> 6) & 0x3f)); - *dst++ = (byte)(0x80 | (a & 0x3f)); - continue; - } + dstarray[pos++] = (byte)(0xE0 | (c >> 12)); + dstarray[pos++] = (byte)(0x80 | ((c >> 6) & 0x3f)); + dstarray[pos++] = (byte)(0x80 | (c & 0x3f)); + return 3; + } - free -= 3; - if (free <= 0) - { - --src; - break; - } + public static int osUTF8GetBytesCount(ReadOnlySpan str) + { + char c; + int nbytes = 0; + int i = 0; + while (i < str.Length) + { + c = str[i++]; - *dst++ = (byte)(0xE0 | (c >> 12)); - *dst++ = (byte)(0x80 | ((c >> 6) & 0x3f)); - *dst++ = (byte)(0x80 | (c & 0x3f)); - } + if (c <= 0x7f) + { + ++nbytes; + continue; + } - pos = (int)(dst - dstbase); - srcstart = (int)(src - srcbase); - if (src == srcend) - ret = true; + if (c < 0x800) + { + nbytes += 2; + continue; + } + + if (c >= 0xD800 && c < 0xE000) + { + if (c >= 0xDC00) + continue; + if (i == str.Length) + break; + c = str[i++]; + if (c < 0xDC00 || c > 0xDFFF) + continue; + nbytes += 4; + continue; } + nbytes += 3; } - return ret; + + if (i > 0 && str[i - 1] == 0) + --nbytes; + return nbytes; } - public static int osUTF8GetBytesCount(string sstr, out int maxsource) + public static int osUTF8GetBytesCount(ReadOnlySpan str, out int maxsource) { maxsource = 0; char c; char lastc = (char)0; int nbytes = 0; int i = 0; - var str = sstr.AsSpan(); while (i < str.Length) { c = str[i++]; @@ -1868,7 +2072,7 @@ public static int osUTF8GetBytesCount(string sstr, out int maxsource) return nbytes; } - public static int osUTF8GetBytesCount(string sstr, int maxnbytes, out int maxsourcelen) + public static int osUTF8GetBytesCount(ReadOnlySpan str, int maxnbytes, out int maxsourcelen) { maxsourcelen = 0; int max2 = maxnbytes - 2; @@ -1878,7 +2082,6 @@ public static int osUTF8GetBytesCount(string sstr, int maxnbytes, out int maxsou char c; int nbytes = 0; int i = 0; - var str = sstr.AsSpan(); while(i < str.Length && nbytes < maxnbytes) { c = str[i++]; @@ -2082,13 +2285,13 @@ public static bool TryHexToByte(byte[] data, int pos, out byte res) return true; } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static byte HexToByte(byte[] data, int pos) { return (byte)(HexNibble(data[pos]) << 4 | HexNibble(data[pos + 1])); } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static byte HexToByte(byte* data, int pos) { return (byte)(HexNibble(data[pos]) << 4 | HexNibble(data[pos + 1])); @@ -2683,64 +2886,44 @@ public static IPAddress HostnameToIPv4(string hostname) private const byte ASCIIzero = (byte)'0'; private const byte ASCIIminus = (byte)'-'; - private static unsafe int UintToStrBytes_reversed(uint value, byte* dst) - { - int n = 0; - do - { - byte a = ASCIIzero; - a += (byte)(value % 10); - dst[n] = a; - ++n; - value /= 10; - } - while(value > 0); - return n; - } - - private static unsafe int ULongToStrBytes_reversed(ulong value, byte* dst) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static unsafe void UintToStrBytesFromEnd(uint value, byte* dst) { - int n = 0; - do + if(value >= 10) { - byte a = ASCIIzero; - a += (byte)(value % 10); - dst[n] = a; - ++n; - value /= 10; + while (value >= 100) + { + uint div = value / 100; + dst--; + WriteTwoDecDigits(value - 100 * div, dst); + value = div; + dst--; + } + if (value >= 10) + { + dst--; + WriteTwoDecDigits(value, dst); + return; + } } - while (value > 0); - return n; + *dst = (byte)('0' + value); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static unsafe int UIntToByteString(uint value, byte* dst) { - if (value == 0) - { - *dst = ASCIIzero; - return 1; - } - - byte* tmp = stackalloc byte[16]; - int n = UintToStrBytes_reversed(value, tmp); - for (int i = 0, j = n - 1; i < n; ++i, --j) - dst[i] = tmp[j]; + int n = CountDigits(value); + UintToStrBytesFromEnd(value, dst + n - 1); return n; } - public static unsafe int ULongToByteString(ulong value, byte* dst) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static unsafe int UIntToByteString(uint value, byte[] dst, int pos) { - if (value == 0) + fixed (byte* d = &dst[pos]) { - *dst = ASCIIzero; - return 1; + return UIntToByteString(value, d); } - - byte* tmp = stackalloc byte[32]; - int n = ULongToStrBytes_reversed(value, tmp); - for (int i = 0, j = n - 1; i < n; ++i, --j) - dst[i] = tmp[j]; - return n; } public static unsafe int UIntToByteString(uint value, Stream st) @@ -2751,135 +2934,148 @@ public static unsafe int UIntToByteString(uint value, Stream st) return 1; } + int n = CountDigits(value); byte* tmp = stackalloc byte[32]; - int n = UintToStrBytes_reversed(value, tmp); - for (int j = n - 1; j <= 0; --j) - st.WriteByte(tmp[j]); + UintToStrBytesFromEnd(value, tmp + n - 1); + for (int i = 0; i < n; i++) + st.WriteByte(tmp[i]); return n; } - public static unsafe int ULongToByteString(ulong value, Stream st) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static unsafe int IntToByteString(int value, byte* dst) { - if (value == 0) + int n; + if(value > 0) { - st.WriteByte(ASCIIzero); - return 1; + n = CountDigits((uint)value); + UintToStrBytesFromEnd((uint)value, dst + n - 1); + return n; } - - byte* tmp = stackalloc byte[32]; - int n = ULongToStrBytes_reversed(value, tmp); - for (int j = n - 1; j <= 0; --j) - st.WriteByte(tmp[j]); - return n; - } - - public static unsafe int UIntToByteString(uint value, byte[] dst, int pos) - { if (value == 0) { - dst[pos] = ASCIIzero; + *dst = ASCIIzero; return 1; } - fixed (byte* d = &dst[pos]) - { - return UIntToByteString(value, d); - } + *dst = ASCIIminus; + value = -value; + n = CountDigits((uint)value); + UintToStrBytesFromEnd((uint)value, dst + n); + return n + 1; } - public static unsafe int ULongToByteString(ulong value, byte[] dst, int pos) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static unsafe int IntToByteString(int value, byte[] dst, int pos) { - if (value == 0) - { - dst[pos] = ASCIIzero; - return 1; - } - fixed (byte* d = &dst[pos]) { - return ULongToByteString(value, d); + return IntToByteString(value, d); } } - public static unsafe int IntToByteString(int value, byte* dst) + public static unsafe int IntToByteString(int value, Stream st) { if (value == 0) { - *dst = ASCIIzero; + st.WriteByte(ASCIIzero); return 1; } - byte* tmp = stackalloc byte[16]; + byte* tmp = stackalloc byte[32]; int n; if (value > 0) { - n = UintToStrBytes_reversed((uint)value, tmp); - for (int i = 0, j = n - 1; i < n; ++i, --j) - dst[i] = tmp[j]; + n = CountDigits((uint)value); + UintToStrBytesFromEnd((uint)value, tmp + n - 1); + for (int j = 0; j < n; j++) + st.WriteByte(tmp[j]); + return n; } - else + + st.WriteByte(ASCIIminus); + value = -value; + n = CountDigits((uint)value); + UintToStrBytesFromEnd((uint)value, tmp + n - 1); + for (int j = 0; j < n; j++) + st.WriteByte(tmp[j]); + return n + 1; + } + + public static unsafe void ULongToStrBytesFromEnd(ulong value, byte* dst) + { + if (value >= 10) { - dst[0] = ASCIIminus; - n = UintToStrBytes_reversed((uint)(-value), tmp); - for (int i = 1, j = n - 1; i < n + 1; ++i, --j) - dst[i] = tmp[j]; - ++n; + while (value >= 100) + { + ulong div = value / 100; + dst--; + WriteTwoDecDigits((uint)(value - 100 * div), dst); + value = div; + dst--; + } + if (value >= 10) + { + dst--; + WriteTwoDecDigits((uint)value, dst); + return; + } } + *dst = (byte)('0' + value); + } + + public static unsafe int ULongToByteString(ulong value, byte* dst) + { + int n = CountDigits(value); + ULongToStrBytesFromEnd(value, dst + n - 1); return n; } - public static unsafe int LongToByteString(long value, byte* dst) + public static unsafe int ULongToByteString(ulong value, Stream st) { if (value == 0) { - *dst = ASCIIzero; + st.WriteByte(ASCIIzero); return 1; } + int n = CountDigits(value); byte* tmp = stackalloc byte[32]; - int n; - if (value > 0) - { - n = ULongToStrBytes_reversed((ulong)value, tmp); - for (int i = 0, j = n - 1; i < n; ++i, --j) - dst[i] = tmp[j]; - } - else - { - dst[0] = ASCIIminus; - n = ULongToStrBytes_reversed((ulong)(-value), tmp); - for (int i = 1, j = n - 1; i < n + 1; ++i, --j) - dst[i] = tmp[j]; - ++n; - } + ULongToStrBytesFromEnd(value, tmp + n - 1); + for (int i = 0; i < n; i++) + st.WriteByte(tmp[i]); return n; } - public static unsafe int IntToByteString(int value, Stream st) + public static unsafe int ULongToByteString(ulong value, byte[] dst, int pos) { - if (value == 0) + fixed (byte* d = &dst[pos]) { - st.WriteByte(ASCIIzero); - return 1; + return ULongToByteString(value, d); } + } - byte* tmp = stackalloc byte[32]; + public static unsafe int LongToByteString(long value, byte* dst) + { int n; if (value > 0) { - n = UintToStrBytes_reversed((uint)value, tmp); - for (int j = n - 1; j >= 0; --j) - st.WriteByte(tmp[j]); + n = CountDigits((ulong)value); + UintToStrBytesFromEnd((uint)value, dst + n - 1); + return n; } - else + + if (value == 0) { - st.WriteByte(ASCIIminus); - n = UintToStrBytes_reversed((uint)(-value), tmp); - for (int j = n - 1; j >= 0; --j) - st.WriteByte(tmp[j]); - ++n; + *dst = ASCIIzero; + return 1; } - return n; + + *dst = ASCIIminus; + value = -value; + n = CountDigits((ulong)value); + UintToStrBytesFromEnd((uint)value, dst + n); + return n + 1; } public static unsafe int LongToByteString(long value, Stream st) @@ -2894,45 +3090,25 @@ public static unsafe int LongToByteString(long value, Stream st) int n; if (value > 0) { - n = ULongToStrBytes_reversed((ulong)value, tmp); - for (int j = n - 1; j >= 0; --j) - st.WriteByte(tmp[j]); - } - else - { - st.WriteByte(ASCIIminus); - n = ULongToStrBytes_reversed((ulong)(-value), tmp); - for (int j = n - 1; j >= 0; --j) + n = CountDigits((ulong)value); + ULongToStrBytesFromEnd((ulong)value, tmp + n - 1); + for (int j = 0; j < n; j++) st.WriteByte(tmp[j]); - ++n; - } - return n; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static unsafe int IntToByteString(int value, byte[] dst, int pos) - { - if (value == 0) - { - dst[pos] = ASCIIzero; - return 1; + return n; } - fixed (byte* d = &dst[pos]) - { - return IntToByteString(value, d); - } + st.WriteByte(ASCIIminus); + value = -value; + n = CountDigits((ulong)value); + ULongToStrBytesFromEnd((ulong)value, tmp + n - 1); + for (int j = 0; j < n; j++) + st.WriteByte(tmp[j]); + return n + 1; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static unsafe int LongToByteString(long value, byte[] dst, int pos) { - if (value == 0) - { - dst[pos] = ASCIIzero; - return 1; - } - fixed (byte* d = &dst[pos]) { return LongToByteString(value, d); @@ -3339,6 +3515,111 @@ public static string UUIDToDashString(UUID u) dst[35] = charLowNibbleToHexChar(b); }); } + + //from .net8 for integer to utf8 + + // Map the log2(value) to a power of 10. + public static readonly byte[] log2ToPow10 = new byte[] + { + 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, + 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10, + 10, 11, 11, 11, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 15, 15, + 15, 16, 16, 16, 16, 17, 17, 17, 18, 18, 18, 19, 19, 19, 19, 20 + }; + + public static readonly ulong[] powersOf10 = new ulong[] + { + 0, // unused entry to avoid needing to subtract + 0, + 10, + 100, + 1000, + 10000, + 100000, + 1000000, + 10000000, + 100000000, + 1000000000, + 10000000000, + 100000000000, + 1000000000000, + 10000000000000, + 100000000000000, + 1000000000000000, + 10000000000000000, + 100000000000000000, + 1000000000000000000, + 10000000000000000000 + }; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int CountDigits(ulong value) + { + uint index = Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(log2ToPow10), System.Numerics.BitOperations.Log2(value)); + bool lessThan = value < Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(powersOf10), index); ; + return (int)(index - Unsafe.As(ref lessThan)); + } + + public static readonly long[] CountDigitlongtable = new long[] + { + 4294967296, + 8589934582, + 8589934582, + 8589934582, + 12884901788, + 12884901788, + 12884901788, + 17179868184, + 17179868184, + 17179868184, + 21474826480, + 21474826480, + 21474826480, + 21474826480, + 25769703776, + 25769703776, + 25769703776, + 30063771072, + 30063771072, + 30063771072, + 34349738368, + 34349738368, + 34349738368, + 34349738368, + 38554705664, + 38554705664, + 38554705664, + 41949672960, + 41949672960, + 41949672960, + 42949672960, + 42949672960, + }; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int CountDigits(uint value) + { + long tableValue = Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(CountDigitlongtable), System.Numerics.BitOperations.Log2(value)); + return (int)((value + tableValue) >> 32); + } + + public static readonly byte[] twodigitbytes = StringToBytesNoTerm( + "00010203040506070809" + + "10111213141516171819" + + "20212223242526272829" + + "30313233343536373839" + + "40414243444546474849" + + "50515253545556575859" + + "60616263646566676869" + + "70717273747576777879" + + "80818283848586878889" + + "90919293949596979899"); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static unsafe void WriteTwoDecDigits(uint value, byte* dest) + { + *(ushort*)dest = Unsafe.ReadUnaligned(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(twodigitbytes), 2 * value)); + } #endregion Miscellaneous } } diff --git a/OpenMetaverseTypes/Vector3.cs b/OpenMetaverseTypes/Vector3.cs index 9a82a151..766abfde 100644 --- a/OpenMetaverseTypes/Vector3.cs +++ b/OpenMetaverseTypes/Vector3.cs @@ -1035,14 +1035,10 @@ public static Vector3 Rotate(Vector3 vec, Quaternion rot) float yz2 = rot.Y * z2; float zz2 = rot.Z * z2; - x2 = vec.X; - y2 = vec.Y; - z2 = vec.Z; - return new Vector3( - x2 * (1.0f - yy2 - zz2) + y2 * (xy2 - wz2) + z2 * (xz2 + wy2), - x2 * (xy2 + wz2) + y2 * (1.0f - xx2 - zz2) + z2 * (yz2 - wx2), - x2 * (xz2 - wy2) + y2 * (yz2 + wx2) + z2 * (1.0f - xx2 - yy2)); + vec.X * (1.0f - yy2 - zz2) + vec.Y * (xy2 - wz2) + vec.Z * (xz2 + wy2), + vec.X * (xy2 + wz2) + vec.Y * (1.0f - xx2 - zz2) + vec.Z * (yz2 - wx2), + vec.X * (xz2 - wy2) + vec.Y * (yz2 + wx2) + vec.Z * (1.0f - xx2 - yy2)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -1062,14 +1058,10 @@ public static Vector3 InverseRotate(Vector3 vec, Quaternion rot) float yz2 = rot.Y * z2; float zz2 = rot.Z * z2; - x2 = vec.X; - y2 = vec.Y; - z2 = vec.Z; - return new Vector3( - x2 * (1.0f - yy2 - zz2) + y2 * (xy2 + wz2) + z2 * (xz2 - wy2), - x2 * (xy2 - wz2) + y2 * (1.0f - xx2 - zz2) + z2 * (yz2 + wx2), - x2 * (xz2 + wy2) + y2 * (yz2 - wx2) + z2 * (1.0f - xx2 - yy2)); + vec.X * (1.0f - yy2 - zz2) + vec.Y * (xy2 + wz2) + vec.Z * (xz2 - wy2), + vec.X * (xy2 - wz2) + vec.Y * (1.0f - xx2 - zz2) + vec.Z * (yz2 + wx2), + vec.X * (xz2 + wy2) + vec.Y * (yz2 - wx2) + vec.Z * (1.0f - xx2 - yy2)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -1133,7 +1125,7 @@ public static Vector3 RotateByQZ(Vector3 vec, Quaternion rot) return new Vector3( vec.X * zz2 - vec.Y * wz2, vec.X * wz2 + vec.Y * zz2, - vec.Z);; + vec.Z); } //quaternion must be normalized <0,0,z,w> diff --git a/Programs/examples/GridAccountant/frmGridAccountant.cs b/Programs/examples/GridAccountant/frmGridAccountant.cs index 3581c872..8092d940 100644 --- a/Programs/examples/GridAccountant/frmGridAccountant.cs +++ b/Programs/examples/GridAccountant/frmGridAccountant.cs @@ -488,7 +488,7 @@ private void cmdFind_Click(object sender, System.EventArgs e) query.QueryData.QueryFlags = 1; query.QueryData.QueryID = UUID.Random(); query.QueryData.QueryStart = 0; - query.QueryData.QueryText = Utils.StringToBytes(txtFind.Text); + query.QueryData.QueryText = Utils.StringToBytes(ref txtFind.Text); query.Header.Reliable = true; Client.Network.SendPacket(query); diff --git a/data/message_template.msg b/data/message_template.msg index 07a08658..23d595fc 100755 --- a/data/message_template.msg +++ b/data/message_template.msg @@ -5780,6 +5780,24 @@ version 2.0 } } +// GenericStreamingMessage +// Optimized generic message for streaming arbitrary data to viewer +// Avoid payloads over 7KB (8KB ceiling) +// Method -- magic number indicating method to use to decode payload: +// 0x4175 - GLTF material override data +// Payload -- data to be decoded +{ + GenericStreamingMessage High 31 Trusted Unencoded + { + MethodData Single + { Method U16 } + } + + { + DataBlock Single + { Data Variable 2 } + } +} // LargeGenericMessage // Similar to the above messages, but can handle larger payloads and serialized // LLSD. Uses HTTP transport diff --git a/mapgen.bat b/mapgen.bat index ab69895a..2cc00d62 100644 --- a/mapgen.bat +++ b/mapgen.bat @@ -1 +1,2 @@ -"bin/mapgenerator.exe" data/message_template.msg Programs/mapgenerator/template.cs Programs/mapgenerator/unusedpackets.txt OpenMetaverse/_Packets_.cs \ No newline at end of file +rem "bin/mapgenerator.exe" data/message_template.msg Programs/mapgenerator/template.cs Programs/mapgenerator/unusedpackets.txt OpenMetaverse/_Packets_.cs +"bin/mapgenerator.exe" data/message_template.msg Programs/mapgenerator/template.cs Programs/mapgenerator/unusedpackets.txt _Packets_.cs \ No newline at end of file From abe4474c4c5fa2aa505ebf5b28c0764297855986 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Fri, 23 Feb 2024 22:23:31 +0000 Subject: [PATCH 106/149] several changes --- CSJ2K/j2k/util/ArrayUtil.cs | 135 +------ CSJ2K/j2k/util/MathUtil.cs | 33 +- OpenMetaverse.StructuredData/LLSD/XmlLLSD.cs | 52 +-- OpenMetaverse/AgentThrottle.cs | 32 +- OpenMetaverse/Imaging/ManagedImage.cs | 28 +- OpenMetaverse/Primitives/Primitive.cs | 2 +- OpenMetaverse/ProtocolManager.cs | 2 +- OpenMetaverseTypes/Matrix3x3.cs | 50 +-- OpenMetaverseTypes/Matrix4.cs | 43 +- OpenMetaverseTypes/OSUTF8.cs | 29 ++ OpenMetaverseTypes/UtilsConversions.cs | 399 ++++++++++++++++++- OpenMetaverseTypes/Vector3.cs | 22 + 12 files changed, 563 insertions(+), 264 deletions(-) diff --git a/CSJ2K/j2k/util/ArrayUtil.cs b/CSJ2K/j2k/util/ArrayUtil.cs index 2bbe89ab..f8f024dc 100644 --- a/CSJ2K/j2k/util/ArrayUtil.cs +++ b/CSJ2K/j2k/util/ArrayUtil.cs @@ -44,125 +44,22 @@ * */ using System; +using System.Runtime.CompilerServices; + namespace CSJ2K.j2k.util { - - /// This class contains a colleaction of utility static methods for arrays. - /// - /// - public class ArrayUtil - { - - /// The maximum array size to do element by element copying, larger - /// arrays are copyied in a n optimized way. - /// - public const int MAX_EL_COPYING = 8; - - /// The number of elements to copy initially in an optimized array copy - public const int INIT_EL_COPYING = 4; - - /// Reinitializes an int array to the given value in an optimized way. If - /// the length of the array is less than MAX_EL_COPYING, then the array - /// is set element by element in the normal way, otherwise the first - /// INIT_EL_COPYING elements are set element by element and then - /// System.arraycopy is used to set the other parts of the array. - /// - /// - /// The array to set. - /// - /// - /// The value to set the array to. - /// - /// - /// - /// - public static void intArraySet(int[] arr, int val) - { - int i, len, len2; - - len = arr.Length; - // Set array to 'val' in an optimized way - if (len < MAX_EL_COPYING) - { - // Not worth doing optimized way - for (i = len - 1; i >= 0; i--) - { - // Set elements - arr[i] = val; - } - } - else - { - // Do in optimized way - len2 = len >> 1; - for (i = 0; i < INIT_EL_COPYING; i++) - { - // Set first elements - arr[i] = val; - } - for (; i <= len2; i <<= 1) - { - // Copy values doubling size each time - Array.Copy(arr, 0, arr, i, i); - } - if (i < len) - { - // Copy values to end - Array.Copy(arr, 0, arr, i, len - i); - } - } - } - - /// Reinitializes a byte array to the given value in an optimized way. If - /// the length of the array is less than MAX_EL_COPYING, then the array - /// is set element by element in the normal way, otherwise the first - /// INIT_EL_COPYING elements are set element by element and then - /// System.arraycopy is used to set the other parts of the array. - /// - /// - /// The array to set. - /// - /// - /// The value to set the array to. - /// - /// - /// - /// - public static void byteArraySet(byte[] arr, byte val) - { - int i, len, len2; - - len = arr.Length; - // Set array to 'val' in an optimized way - if (len < MAX_EL_COPYING) - { - // Not worth doing optimized way - for (i = len - 1; i >= 0; i--) - { - // Set elements - arr[i] = val; - } - } - else - { - // Do in optimized way - len2 = len >> 1; - for (i = 0; i < INIT_EL_COPYING; i++) - { - // Set first elements - arr[i] = val; - } - for (; i <= len2; i <<= 1) - { - // Copy values doubling size each time - Array.Copy(arr, 0, arr, i, i); - } - if (i < len) - { - // Copy values to end - Array.Copy(arr, 0, arr, i, len - i); - } - } - } - } + public class ArrayUtil + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void intArraySet(int[] arr, int val) + { + Array.Fill(arr, val); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void byteArraySet(byte[] arr, byte val) + { + Array.Fill(arr, val); + } + } } \ No newline at end of file diff --git a/CSJ2K/j2k/util/MathUtil.cs b/CSJ2K/j2k/util/MathUtil.cs index b945d981..8fdcdc0b 100644 --- a/CSJ2K/j2k/util/MathUtil.cs +++ b/CSJ2K/j2k/util/MathUtil.cs @@ -41,6 +41,7 @@ * Copyright (c) 1999/2000 JJ2000 Partners. * */ using System; +using System.Runtime.CompilerServices; namespace CSJ2K.j2k.util { @@ -50,34 +51,12 @@ namespace CSJ2K.j2k.util /// public class MathUtil { - - /// Method that calculates the floor of the log, base 2, of 'x'. The - /// calculation is performed in integer arithmetic, therefore, it is exact. - /// - /// - /// The value to calculate log2 on. - /// - /// - /// floor(log(x)/log(2)), calculated in an exact way. - /// - /// - public static int log2(int x) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int log2(int x) { - int y, v; - // No log of 0 or negative - if (x <= 0) - { - throw new System.ArgumentException("" + x + " <= 0"); - } - // Calculate log2 (it's actually floor log2) - v = x; - y = - 1; - while (v > 0) - { - v >>= 1; - y++; - } - return y; + if (x <= 0) + throw new System.ArgumentException("" + x + " <= 0"); + return System.Numerics.BitOperations.Log2((uint)x); } /// Method that calculates the Least Common Multiple (LCM) of two strictly diff --git a/OpenMetaverse.StructuredData/LLSD/XmlLLSD.cs b/OpenMetaverse.StructuredData/LLSD/XmlLLSD.cs index 23fcbe4b..83ca9a12 100644 --- a/OpenMetaverse.StructuredData/LLSD/XmlLLSD.cs +++ b/OpenMetaverse.StructuredData/LLSD/XmlLLSD.cs @@ -450,17 +450,17 @@ public static unsafe void base64Encode(byte[] data, osUTF8 mb) int lenMod3 = data.Length % 3; int len = data.Length - lenMod3; - mb.CheckCapacity(4 * data.Length / 3); + mb.CheckCapacity(((data.Length + 2) / 3) * 4); fixed (byte* d = data, b64 = osUTF8Const.base64Bytes) { int i = 0; while (i < len) { - mb.Append(b64[d[i] >> 2]); - mb.Append(b64[((d[i] & 0x03) << 4) | ((d[i + 1] & 0xf0) >> 4)]); - mb.Append(b64[((d[i + 1] & 0x0f) << 2) | ((d[i + 2] & 0xc0) >> 6)]); - mb.Append(b64[d[i + 2] & 0x3f]); + mb.AppendSafe(b64[d[i] >> 2]); + mb.AppendSafe(b64[((d[i] & 0x03) << 4) | ((d[i + 1] & 0xf0) >> 4)]); + mb.AppendSafe(b64[((d[i + 1] & 0x0f) << 2) | ((d[i + 2] & 0xc0) >> 6)]); + mb.AppendSafe(b64[d[i + 2] & 0x3f]); i += 3; } @@ -469,19 +469,19 @@ public static unsafe void base64Encode(byte[] data, osUTF8 mb) case 2: { i = len; - mb.Append(b64[d[i] >> 2]); - mb.Append(b64[((d[i] & 0x03) << 4) | ((d[i + 1] & 0xf0) >> 4)]); - mb.Append(b64[((d[i + 1] & 0x0f) << 2)]); - mb.Append((byte)'='); + mb.AppendSafe(b64[d[i] >> 2]); + mb.AppendSafe(b64[((d[i] & 0x03) << 4) | ((d[i + 1] & 0xf0) >> 4)]); + mb.AppendSafe(b64[((d[i + 1] & 0x0f) << 2)]); + mb.AppendSafe((byte)'='); break; } case 1: { i = len; - mb.Append(b64[d[i] >> 2]); - mb.Append(b64[(d[i] & 0x03) << 4]); - mb.Append((byte)'='); - mb.Append((byte)'='); + mb.AppendSafe(b64[d[i] >> 2]); + mb.AppendSafe(b64[(d[i] & 0x03) << 4]); + mb.AppendSafe((byte)'='); + mb.AppendSafe((byte)'='); break; } } @@ -493,15 +493,16 @@ public static unsafe void base64Encode(byte[] data, int start, int lenght, osUTF int lenMod3 = lenght % 3; int len = lenght - lenMod3; + mb.CheckCapacity(((lenght + 2) / 3) * 4); fixed (byte* d = &data[start], b64 = osUTF8Const.base64Bytes) { int i = 0; while (i < len) { - mb.Append(b64[d[i] >> 2]); - mb.Append(b64[((d[i] & 0x03) << 4) | ((d[i + 1] & 0xf0) >> 4)]); - mb.Append(b64[((d[i + 1] & 0x0f) << 2) | ((d[i + 2] & 0xc0) >> 6)]); - mb.Append(b64[d[i + 2] & 0x3f]); + mb.AppendSafe(b64[d[i] >> 2]); + mb.AppendSafe(b64[((d[i] & 0x03) << 4) | ((d[i + 1] & 0xf0) >> 4)]); + mb.AppendSafe(b64[((d[i + 1] & 0x0f) << 2) | ((d[i + 2] & 0xc0) >> 6)]); + mb.AppendSafe(b64[d[i + 2] & 0x3f]); i += 3; } @@ -510,19 +511,19 @@ public static unsafe void base64Encode(byte[] data, int start, int lenght, osUTF case 2: { i = len; - mb.Append(b64[d[i] >> 2]); - mb.Append(b64[((d[i] & 0x03) << 4) | ((d[i + 1] & 0xf0) >> 4)]); - mb.Append(b64[((d[i + 1] & 0x0f) << 2)]); - mb.Append((byte)'='); + mb.AppendSafe(b64[d[i] >> 2]); + mb.AppendSafe(b64[((d[i] & 0x03) << 4) | ((d[i + 1] & 0xf0) >> 4)]); + mb.AppendSafe(b64[((d[i + 1] & 0x0f) << 2)]); + mb.AppendSafe((byte)'='); break; } case 1: { i = len; - mb.Append(b64[d[i] >> 2]); - mb.Append(b64[(d[i] & 0x03) << 4]); - mb.Append((byte)'='); - mb.Append((byte)'='); + mb.AppendSafe(b64[d[i] >> 2]); + mb.AppendSafe(b64[(d[i] & 0x03) << 4]); + mb.AppendSafe((byte)'='); + mb.AppendSafe((byte)'='); break; } } @@ -540,6 +541,7 @@ public static unsafe void base64Encode(byte[] data, StringBuilder sb) int lenMod3 = data.Length % 3; int len = data.Length - lenMod3; + sb.EnsureCapacity(((data.Length + 2) / 3) * 4); fixed (byte* d = data) { fixed (char* b64 = base64Chars) diff --git a/OpenMetaverse/AgentThrottle.cs b/OpenMetaverse/AgentThrottle.cs index f5703ded..ac79dcc5 100644 --- a/OpenMetaverse/AgentThrottle.cs +++ b/OpenMetaverse/AgentThrottle.cs @@ -178,13 +178,14 @@ public AgentThrottle(byte[] data, int pos) adjData = data; } - Resend = BitConverter.ToSingle(adjData, pos); pos += 4; - Land = BitConverter.ToSingle(adjData, pos); pos += 4; - Wind = BitConverter.ToSingle(adjData, pos); pos += 4; - Cloud = BitConverter.ToSingle(adjData, pos); pos += 4; - Task = BitConverter.ToSingle(adjData, pos); pos += 4; - Texture = BitConverter.ToSingle(adjData, pos); pos += 4; - Asset = BitConverter.ToSingle(adjData, pos); + Resend = Utils.BytesToFloat(adjData, 0); + Land = Utils.BytesToFloat(adjData, 4); + Wind = Utils.BytesToFloat(adjData, 8); + Cloud = Utils.BytesToFloat(adjData, 12); + Task = Utils.BytesToFloat(adjData, 16); + Texture = Utils.BytesToFloat(adjData, 20); + Asset = Utils.BytesToFloat(adjData, 24); + pos += 28; } /// @@ -220,15 +221,14 @@ public void Set(Simulator simulator) public byte[] ToBytes() { byte[] data = new byte[7 * 4]; - int i = 0; - - Buffer.BlockCopy(Utils.FloatToBytes(Resend), 0, data, i, 4); i += 4; - Buffer.BlockCopy(Utils.FloatToBytes(Land), 0, data, i, 4); i += 4; - Buffer.BlockCopy(Utils.FloatToBytes(Wind), 0, data, i, 4); i += 4; - Buffer.BlockCopy(Utils.FloatToBytes(Cloud), 0, data, i, 4); i += 4; - Buffer.BlockCopy(Utils.FloatToBytes(Task), 0, data, i, 4); i += 4; - Buffer.BlockCopy(Utils.FloatToBytes(Texture), 0, data, i, 4); i += 4; - Buffer.BlockCopy(Utils.FloatToBytes(Asset), 0, data, i, 4); i += 4; + + Utils.FloatToBytes(Resend, data, 0); + Utils.FloatToBytes(Land, data, 4); + Utils.FloatToBytes(Wind, data, 8); + Utils.FloatToBytes(Cloud, data, 12); + Utils.FloatToBytes(Task, data, 16); + Utils.FloatToBytes(Texture, data, 20); + Utils.FloatToBytes(Asset, data, 24); return data; } diff --git a/OpenMetaverse/Imaging/ManagedImage.cs b/OpenMetaverse/Imaging/ManagedImage.cs index 7a024609..adc12f82 100644 --- a/OpenMetaverse/Imaging/ManagedImage.cs +++ b/OpenMetaverse/Imaging/ManagedImage.cs @@ -131,10 +131,10 @@ public ManagedImage(System.Drawing.Bitmap bitmap) if (bitmap.PixelFormat == System.Drawing.Imaging.PixelFormat.Format32bppArgb) { Channels = ImageChannels.Alpha | ImageChannels.Color; - Red = new byte[pixelCount]; - Green = new byte[pixelCount]; - Blue = new byte[pixelCount]; - Alpha = new byte[pixelCount]; + Red = GC.AllocateUninitializedArray(pixelCount); + Green = GC.AllocateUninitializedArray(pixelCount); + Blue = GC.AllocateUninitializedArray(pixelCount); + Alpha = GC.AllocateUninitializedArray(pixelCount); System.Drawing.Imaging.BitmapData bd = bitmap.LockBits(new System.Drawing.Rectangle(0, 0, Width, Height), System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); @@ -158,16 +158,16 @@ public ManagedImage(System.Drawing.Bitmap bitmap) else if (bitmap.PixelFormat == System.Drawing.Imaging.PixelFormat.Format16bppGrayScale) { Channels = ImageChannels.Gray; - Red = new byte[pixelCount]; + Red = GC.AllocateUninitializedArray(pixelCount); throw new NotImplementedException("16bpp grayscale image support is incomplete"); } else if (bitmap.PixelFormat == System.Drawing.Imaging.PixelFormat.Format24bppRgb) { Channels = ImageChannels.Color; - Red = new byte[pixelCount]; - Green = new byte[pixelCount]; - Blue = new byte[pixelCount]; + Red = GC.AllocateUninitializedArray(pixelCount); + Green = GC.AllocateUninitializedArray(pixelCount); + Blue = GC.AllocateUninitializedArray(pixelCount); System.Drawing.Imaging.BitmapData bd = bitmap.LockBits(new System.Drawing.Rectangle(0, 0, Width, Height), System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format24bppRgb); @@ -190,9 +190,9 @@ public ManagedImage(System.Drawing.Bitmap bitmap) else if (bitmap.PixelFormat == System.Drawing.Imaging.PixelFormat.Format32bppRgb) { Channels = ImageChannels.Color; - Red = new byte[pixelCount]; - Green = new byte[pixelCount]; - Blue = new byte[pixelCount]; + Red = GC.AllocateUninitializedArray(pixelCount); + Green = GC.AllocateUninitializedArray(pixelCount); + Blue = GC.AllocateUninitializedArray(pixelCount); System.Drawing.Imaging.BitmapData bd = bitmap.LockBits(new System.Drawing.Rectangle(0, 0, Width, Height), System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppRgb); @@ -235,9 +235,9 @@ public void ConvertChannels(ImageChannels channels) if ((add & ImageChannels.Color) != 0) { - Red = new byte[n]; - Green = new byte[n]; - Blue = new byte[n]; + Red = GC.AllocateUninitializedArray(n); + Green = GC.AllocateUninitializedArray(n); + Blue = GC.AllocateUninitializedArray(n); } else if ((del & ImageChannels.Color) != 0) { diff --git a/OpenMetaverse/Primitives/Primitive.cs b/OpenMetaverse/Primitives/Primitive.cs index aba38b5c..f968daf8 100644 --- a/OpenMetaverse/Primitives/Primitive.cs +++ b/OpenMetaverse/Primitives/Primitive.cs @@ -36,7 +36,7 @@ public partial class Primitive : IEquatable protected const float CUT_QUANTA = 0.00002f; protected const float CUT_QUANTAINV = 1.0f / CUT_QUANTA; protected const float SCALE_QUANTA = 0.01f; - protected const float SCALE_QUANTAINV = 1-0f/ SCALE_QUANTA; + protected const float SCALE_QUANTAINV = 1.0f/ SCALE_QUANTA; protected const float SHEAR_QUANTA = 0.01f; protected const float SHEAR_QUANTAINV = 1.0f / SHEAR_QUANTA; protected const float TAPER_QUANTA = 0.01f; diff --git a/OpenMetaverse/ProtocolManager.cs b/OpenMetaverse/ProtocolManager.cs index cd761d32..697cbae8 100644 --- a/OpenMetaverse/ProtocolManager.cs +++ b/OpenMetaverse/ProtocolManager.cs @@ -395,7 +395,7 @@ private void PrintOneMap(MapPacket[] map, string frequency) { public static void DecodeMapFile(string mapFile, string outputFile) { byte magicKey = 0; - byte[] buffer = new byte[2048]; + byte[] buffer = GC.AllocateUninitializedArray(2048); int nread; try diff --git a/OpenMetaverseTypes/Matrix3x3.cs b/OpenMetaverseTypes/Matrix3x3.cs index 7d06ddc1..8f96c0b6 100644 --- a/OpenMetaverseTypes/Matrix3x3.cs +++ b/OpenMetaverseTypes/Matrix3x3.cs @@ -372,17 +372,32 @@ public static Matrix3x3 CreateFromQuaternion(Quaternion rot) float zz2 = rot.Z * z2; return new Matrix3x3( - 1.0f - yy2 - zz2, - xy2 - wz2, - xz2 + wy2, + 1.0f - yy2 - zz2, xy2 + wz2, xz2 - wy2, + xy2 - wz2, 1.0f - xx2 - zz2, yz2 + wx2, + xz2 + wy2, yz2 - wx2, 1.0f - xx2 - yy2 + ); + } - xy2 + wz2, - 1.0f - xx2 - zz2, - yz2 - wx2, + public static Matrix3x3 CreateFromInverseQuaternion(Quaternion rot) + { + float x2 = rot.X + rot.X; + float y2 = rot.Y + rot.Y; + float z2 = rot.Z + rot.Z; - xz2 - wy2, - yz2 + wx2, - 1.0f - xx2 - yy2 + float wx2 = rot.W * x2; + float wy2 = rot.W * y2; + float wz2 = rot.W * z2; + float xx2 = rot.X * x2; + float xy2 = rot.X * y2; + float xz2 = rot.X * z2; + float yy2 = rot.Y * y2; + float yz2 = rot.Y * z2; + float zz2 = rot.Z * z2; + + return new Matrix3x3( + 1.0f - yy2 - zz2, xy2 - wz2, xz2 + wy2, + xy2 + wz2, 1.0f - xx2 - zz2, yz2 - wx2, + xz2 - wy2, yz2 + wx2, 1.0f - xx2 - yy2 ); } @@ -595,20 +610,7 @@ public static Matrix3x3 Inverse3x3(Matrix3x3 matrix) if (matrix.Determinant3x3() == 0f) throw new ArgumentException("Singular matrix inverse not possible"); - return (Adjoint3x3(matrix) / matrix.Determinant3x3()); - } - - public static Matrix3x3 Adjoint3x3(Matrix3x3 matrix) - { - Matrix3x3 adjointMatrix = new Matrix3x3(); - for (int i = 0; i < 4; i++) - { - for (int j = 0; j < 4; j++) - adjointMatrix[i,j] = MathF.Pow(-1, i + j) * (Minor(matrix, i, j).Determinant3x3()); - } - - adjointMatrix = Transpose(adjointMatrix); - return adjointMatrix; + return (Adjoint(matrix) / matrix.Determinant3x3()); } public static Matrix3x3 Inverse(Matrix3x3 matrix) @@ -616,7 +618,7 @@ public static Matrix3x3 Inverse(Matrix3x3 matrix) if (matrix.Determinant() == 0f) throw new ArgumentException("Singular matrix inverse not possible"); - return (Adjoint(matrix) / matrix.Determinant()); + return Adjoint(matrix) / matrix.Determinant(); } public static Matrix3x3 Adjoint(Matrix3x3 matrix) diff --git a/OpenMetaverseTypes/Matrix4.cs b/OpenMetaverseTypes/Matrix4.cs index 18d2efe1..097f5e10 100644 --- a/OpenMetaverseTypes/Matrix4.cs +++ b/OpenMetaverseTypes/Matrix4.cs @@ -419,8 +419,6 @@ public static Matrix4 CreateFromEulers(float roll, float pitch, float yaw) public static Matrix4 CreateFromQuaternion(Quaternion rot) { - Matrix4 matrix; - float x2 = rot.X + rot.X; float y2 = rot.Y + rot.Y; float z2 = rot.Z + rot.Z; @@ -435,25 +433,34 @@ public static Matrix4 CreateFromQuaternion(Quaternion rot) float yz2 = rot.Y * z2; float zz2 = rot.Z * z2; - matrix.M11 = 1.0f - yy2 - zz2; - matrix.M12 = xy2 - wz2; - matrix.M13 = xz2 + wy2; - matrix.M14 = 0f; - - matrix.M21 = xy2 + wz2; - matrix.M22 = 1.0f - xx2 - zz2; - matrix.M23 = yz2 - wx2; - matrix.M24 = 0f; + return new Matrix4( + 1.0f - yy2 - zz2, xy2 + wz2, xz2 - wy2, 0, + xy2 - wz2, 1.0f - xx2 - zz2, yz2 + wx2, 0, + xz2 + wy2, yz2 - wx2, 1.0f - xx2 - yy2, 0, + 0, 0, 0, 1.0f); + } - matrix.M31 = xz2 - wy2; - matrix.M32 = yz2 + wx2; - matrix.M33 = 1.0f - xx2 - yy2; - matrix.M34 = 0f; + public static Matrix4 CreateFromInverseQuaternion(Quaternion rot) + { + float x2 = rot.X + rot.X; + float y2 = rot.Y + rot.Y; + float z2 = rot.Z + rot.Z; - matrix.M43 = matrix.M42 = matrix.M41 = 0f; - matrix.M44 = 1f; + float wx2 = rot.W * x2; + float wy2 = rot.W * y2; + float wz2 = rot.W * z2; + float xx2 = rot.X * x2; + float xy2 = rot.X * y2; + float xz2 = rot.X * z2; + float yy2 = rot.Y * y2; + float yz2 = rot.Y * z2; + float zz2 = rot.Z * z2; - return matrix; + return new Matrix4( + 1.0f - yy2 - zz2, xy2 - wz2, xz2 + wy2, 0, + xy2 + wz2, 1.0f - xx2 - zz2, yz2 - wx2, 0, + xz2 - wy2, yz2 + wx2, 1.0f - xx2 - yy2, 0, + 0, 0, 0, 1.0f); } public static Matrix4 CreateLookAt(Vector3 cameraPosition, Vector3 cameraTarget, Vector3 cameraUpVector) diff --git a/OpenMetaverseTypes/OSUTF8.cs b/OpenMetaverseTypes/OSUTF8.cs index 67b7f29a..6f9d4301 100644 --- a/OpenMetaverseTypes/OSUTF8.cs +++ b/OpenMetaverseTypes/OSUTF8.cs @@ -41,6 +41,7 @@ Ubit Umarov (Leal Duarte) 2020 using System.Runtime.InteropServices; using System.Runtime.Intrinsics.X86; using System.Runtime.Intrinsics; +using System.IO; namespace OpenMetaverse { @@ -475,6 +476,13 @@ public void Append(byte c) ++m_len; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendSafe(byte c) + { + Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(m_data), m_len)) = c; + ++m_len; + } + public unsafe void AppendASCII(string asciiString) { int nbytes = asciiString.Length; @@ -1285,5 +1293,26 @@ public osUTF8 RemoveBytes(int start, int len) o.m_len = m_len - len; return o; } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToVarBin(Stream ms) + { + Utils.UIntToVarBytes(ms, (uint)m_len); + if (m_len > 0) + ms.Write(m_data, 0, m_len); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static osUTF8 FromVarBin(Stream ms) + { + int len = (int)Utils.VarBytestoUlong(ms); + if(len > 0) + { + byte[] data = new byte[len]; + ms.Read(data,0, len); + return new osUTF8(data); + } + return new osUTF8(); + } } } diff --git a/OpenMetaverseTypes/UtilsConversions.cs b/OpenMetaverseTypes/UtilsConversions.cs index b1f0d423..c220ae74 100644 --- a/OpenMetaverseTypes/UtilsConversions.cs +++ b/OpenMetaverseTypes/UtilsConversions.cs @@ -773,6 +773,283 @@ public unsafe static ulong BytesToUInt64(byte* bytes) ((long)bytes[7] << 56)); } + public static ulong VarBytestoUlong(byte[] bytes, int pos) + { + ref byte dataref = ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(bytes), pos); + + ulong value = Unsafe.ReadUnaligned(ref dataref); + if ((value & 0x80) == 0) + return value; + value &= 0x7F; + + ulong next = Unsafe.ReadUnaligned(ref Unsafe.Add(ref dataref, 1)); + if ((next & 0x80) == 0) + return value | (next << 7); + value |= (next & 0x7F) << 7; + + next = Unsafe.ReadUnaligned(ref Unsafe.Add(ref dataref, 2)); + if ((next & 0x80) == 0) + return value | (next << 14); + value |= (next & 0x7F) << 14; + + next = Unsafe.ReadUnaligned(ref Unsafe.Add(ref dataref, 3)); + if ((next & 0x80) == 0) + return value | (next << 21); + value |= (next & 0x7F) << 21; + + next = Unsafe.ReadUnaligned(ref Unsafe.Add(ref dataref, 4)); + if ((next & 0x80) == 0) + return value | (next << 28); + value |= (next & 0x7F) << 28; + + next = Unsafe.ReadUnaligned(ref Unsafe.Add(ref dataref, 5)); + if ((next & 0x80) == 0) + return value | (next << 35); + value |= (next & 0x7F) << 35; + + next = Unsafe.ReadUnaligned(ref Unsafe.Add(ref dataref, 6)); + if ((next & 0x80) == 0) + return value | (next << 42); + value |= (next & 0x7F) << 42; + + next = Unsafe.ReadUnaligned(ref Unsafe.Add(ref dataref, 7)); + if ((next & 0x80) == 0) + return value | (next << 49); + value |= (next & 0x7F) << 49; + + next = Unsafe.ReadUnaligned(ref Unsafe.Add(ref dataref, 8)); + if ((next & 0x80) == 0) + return value | (next << 56); + value |= (next & 0x7F) << 56; + + next = Unsafe.ReadUnaligned(ref Unsafe.Add(ref dataref, 9)); + return value | (next << 63); + } + + public static bool TryVarBytestoUlong(byte[] bytes, ref int pos, out ulong value) + { + int st = pos; + try + { + value = bytes[pos++]; + if ((value & 0x80) == 0) + return true; + value &= 0x7F; + + ulong next = bytes[pos++]; + if ((next & 0x80) == 0) + { + value |= (next << 7); + return true; + } + value |= (next & 0x7F) << 7; + + next = bytes[pos++]; + if ((next & 0x80) == 0) + { + value |= (next << 14); + return true; + } + value |= (next & 0x7F) << 14; + + pos++; + next = bytes[pos++]; + if ((next & 0x80) == 0) + { + value |= (next << 21); + return true; + } + value |= (next & 0x7F) << 21; + + next = bytes[pos++]; + if ((next & 0x80) == 0) + { + value |= (next << 28); + return true; + } + value |= (next & 0x7F) << 28; + + next = bytes[pos++]; + if ((next & 0x80) == 0) + { + value |= (next << 35); + return true; + } + value |= (next & 0x7F) << 35; + + next = bytes[pos++]; + if ((next & 0x80) == 0) + { + value |= (next << 42); + return true; + } + value |= (next & 0x7F) << 42; + + next = bytes[pos++]; + if ((next & 0x80) == 0) + { + value |= (next << 49); + return true; + } + value |= (next & 0x7F) << 49; + + next = bytes[pos++]; + if ((next & 0x80) == 0) + { + value |= (next << 56); + return true; + } + value |= (next & 0x7F) << 56; + + next = bytes[pos++]; + value |= (next << 63); + if( next < 2) + return true; + } + catch {} + + value = 0; + pos = st; + return false; + } + + public static ulong VarBytestoUlong(Stream ms) + { + ulong value = (ulong)ms.ReadByte(); + if ((value & 0x80) == 0) + return value; + value &= 0x7F; + + ulong next = (ulong)ms.ReadByte(); + if ((next & 0x80) == 0) + return value | (next << 7); + value |= (next & 0x7F) << 7; + + next = (ulong)ms.ReadByte(); + if ((next & 0x80) == 0) + return value | (next << 14); + value |= (next & 0x7F) << 14; + + next = (ulong)ms.ReadByte(); + if ((next & 0x80) == 0) + return value | (next << 21); + value |= (next & 0x7F) << 21; + + next = (ulong)ms.ReadByte(); + if ((next & 0x80) == 0) + return value | (next << 28); + value |= (next & 0x7F) << 28; + + next = (ulong)ms.ReadByte(); + if ((next & 0x80) == 0) + return value | (next << 35); + value |= (next & 0x7F) << 35; + + next = (ulong)ms.ReadByte(); + if ((next & 0x80) == 0) + return value | (next << 42); + value |= (next & 0x7F) << 42; + + next = (ulong)ms.ReadByte(); + if ((next & 0x80) == 0) + return value | (next << 49); + value |= (next & 0x7F) << 49; + + next = (ulong)ms.ReadByte(); + if ((next & 0x80) == 0) + return value | (next << 56); + value |= (next & 0x7F) << 56; + + next = (ulong)ms.ReadByte(); + return value | (next << 63); + } + + public static bool TryVarBytestoUlong(Stream ms, out ulong value) + { + long st = ms.Position; + try + { + value = (ulong)ms.ReadByte(); + if ((value & 0x80) == 0) + return true; + value &= 0x7F; + + ulong next = (ulong)ms.ReadByte(); + if ((next & 0x80) == 0) + { + value |= (next << 7); + return true; + } + value |= (next & 0x7F) << 7; + + next = (ulong)ms.ReadByte(); + if ((next & 0x80) == 0) + { + value |= (next << 14); + return true; + } + value |= (next & 0x7F) << 14; + + next = (ulong)ms.ReadByte(); + if ((next & 0x80) == 0) + { + value |= (next << 21); + return true; + } + value |= (next & 0x7F) << 21; + + next = (ulong)ms.ReadByte(); + if ((next & 0x80) == 0) + { + value |= (next << 28); + return true; + } + value |= (next & 0x7F) << 28; + + next = (ulong)ms.ReadByte(); + if ((next & 0x80) == 0) + { + value |= (next << 35); + return true; + } + value |= (next & 0x7F) << 35; + + next = (ulong)ms.ReadByte(); + if ((next & 0x80) == 0) + { + value |= (next << 42); + return true; + } + value |= (next & 0x7F) << 42; + + next = (ulong)ms.ReadByte(); + if ((next & 0x80) == 0) + { + value |= (next << 49); + return true; + } + value |= (next & 0x7F) << 49; + + next = (ulong)ms.ReadByte(); + if ((next & 0x80) == 0) + { + value |= (next << 56); + return true; + } + value |= (next & 0x7F) << 56; + + next = (ulong)ms.ReadByte(); + value |= (next << 63); + if(next < 2) + return true; + } + catch { } + + value = 0; + ms.Position = st; + return false; + } + /// /// Convert four bytes in native endian ordeing to a floating point /// value @@ -881,10 +1158,7 @@ public static double BytesToDoubleSafepos(ref byte bytes, int pos) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static byte[] Int16ToBytes(short value) { - byte[] bytes = new byte[2]; - bytes[0] = (byte)value; - bytes[1] = (byte)(value >> 8); - return bytes; + return new byte[] {(byte)value, (byte)(value >> 8)}; } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -928,10 +1202,7 @@ public static unsafe void Int16ToBytes(short value, byte* dest, int pos) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static byte[] UInt16ToBytes(ushort value) { - byte[] bytes = new byte[2]; - bytes[0] = (byte)value; - bytes[1] = (byte)(value >> 8); - return bytes; + return new byte[] { (byte)value, (byte)(value >> 8) }; } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -1089,14 +1360,13 @@ public unsafe static void IntToBytesSafepos(int value, ref byte dest) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static byte[] IntToBytesBig(int value) { - byte[] bytes = new byte[4]; - - bytes[0] = (byte)(value >> 24); - bytes[1] = (byte)(value >> 16); - bytes[2] = (byte)(value >> 8); - bytes[3] = (byte)value; - - return bytes; + return new byte[] + { + (byte)(value >> 24), + (byte)(value >> 16), + (byte)(value >> 8), + (byte)value + }; } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -1182,6 +1452,16 @@ public static void UIntToBytesBig(uint value, byte[] dest, int pos) IntToBytesBig((int)value, dest, pos); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void UIntToVarBytes(Stream ms, uint value) + { + while (value > 127) + { + ms.WriteByte((byte)(value | 0x80)); + value >>= 7; + } + ms.WriteByte((byte)value); + } /// /// Convert a 64-bit integer to a byte array in little endian format /// @@ -1393,6 +1673,68 @@ public static void UInt64ToBytesSafepos(ulong value, ref byte dest) Unsafe.WriteUnaligned(ref dest, value); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int UInt64ToVarBytes(byte[] bytes, int pos, ulong value) + { + ref byte bytesref = ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(bytes), pos); + ref byte bytesrefbase = ref bytesref; + while (value > 127UL) + { + Unsafe.WriteUnaligned(ref bytesref, (byte)(value | 0x80)); + bytesref = ref Unsafe.Add(ref bytesref, 1); + value >>= 7; + } + Unsafe.WriteUnaligned(ref bytesref, (byte)value); + return (int)Unsafe.ByteOffset(ref bytesrefbase, ref bytesref) + 1; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int TryUInt64ToVarBytes(byte[] bytes, int pos, ulong value) + { + int st = pos; + try + { + while (value > 127UL) + { + bytes[pos] = (byte)(value | 0x80); + pos++; + value >>= 7; + } + bytes[pos] = (byte)value; + return pos - st + 1; + } + catch { } + return -1; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void UInt64ToVarBytes(Stream ms, ulong value) + { + while (value > 127UL) + { + ms.WriteByte((byte)(value | 0x80)); + value >>= 7; + } + ms.WriteByte((byte)value); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool TryUInt64ToVarBytes(Stream ms, ulong value) + { + try + { + while (value > 127UL) + { + ms.WriteByte((byte)(value | 0x80)); + value >>= 7; + } + ms.WriteByte((byte)value); + return true; + } + catch { } + return false; + } + /// /// Convert a floating point value to four bytes in little endian /// ordering @@ -2267,7 +2609,7 @@ public static bool TryHexToInt(byte[] data, int start, int len, out int res) return true; } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool TryHexToByte(byte[] data, int pos, out byte res) { int a,b; @@ -2325,11 +2667,13 @@ public unsafe static byte[] HexStringToBytes(string hexString, bool handleDirty) } hexString = stripped.ToString(); + /* // if odd number of characters, discard last character if (hexString.Length % 2 != 0) { - hexString = hexString.Substring(0, hexString.Length - 1); + hexString = hexString[..^1]; } + */ } int byteLength = hexString.Length / 2; @@ -2712,7 +3056,7 @@ public static byte[] CopyBytes(byte[] bytes) if (bytes == null) return null; - byte[] newBytes = new byte[bytes.Length]; + byte[] newBytes = GC.AllocateUninitializedArray(bytes.Length); Array.Copy(bytes, newBytes, bytes.Length); return newBytes; } @@ -3620,6 +3964,23 @@ public static unsafe void WriteTwoDecDigits(uint value, byte* dest) { *(ushort*)dest = Unsafe.ReadUnaligned(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(twodigitbytes), 2 * value)); } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void StringToUFT8VarBin(Stream ms, ReadOnlySpan s) + { + ReadOnlySpan sp = StringToBytesNoTerm(s); + UIntToVarBytes(ms, (uint)sp.Length); + if (sp.Length > 0) + ms.Write(sp); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void Utf8ToVarBin(Stream ms, ReadOnlySpan sp) + { + UIntToVarBytes(ms, (uint)sp.Length); + if (sp.Length > 0) + ms.Write(sp); + } #endregion Miscellaneous } } diff --git a/OpenMetaverseTypes/Vector3.cs b/OpenMetaverseTypes/Vector3.cs index 766abfde..1b4a1784 100644 --- a/OpenMetaverseTypes/Vector3.cs +++ b/OpenMetaverseTypes/Vector3.cs @@ -520,6 +520,7 @@ public void Rotate(Quaternion rot) Z = x2 * (xz2 - wy2) + y2 * (yz2 + wx2) + z2 * (1.0f - xx2 - yy2); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void InverseRotate(Quaternion rot) { float x2 = rot.X + rot.X; @@ -996,6 +997,26 @@ public static Vector3 AddS(Vector3 value1, Vector3 value2) return Subtract(value1, value2); } */ + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector3 Transform(Vector3 position, Matrix3x3 matrix) + { + return new Vector3( + (position.X * matrix.M11) + (position.Y * matrix.M21) + (position.Z * matrix.M31), + (position.X * matrix.M12) + (position.Y * matrix.M22) + (position.Z * matrix.M32), + (position.X * matrix.M13) + (position.Y * matrix.M23) + (position.Z * matrix.M33)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector3 TransformByTransposed(Vector3 position, Matrix3x3 matrix) + { + return new Vector3( + (position.X * matrix.M11) + (position.Y * matrix.M12) + (position.Z * matrix.M13), + (position.X * matrix.M21) + (position.Y * matrix.M22) + (position.Z * matrix.M23), + (position.X * matrix.M31) + (position.Y * matrix.M32) + (position.Z * matrix.M33)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 Transform(Vector3 position, Matrix4 matrix) { return new Vector3( @@ -1004,6 +1025,7 @@ public static Vector3 Transform(Vector3 position, Matrix4 matrix) (position.X * matrix.M13) + (position.Y * matrix.M23) + (position.Z * matrix.M33) + matrix.M43); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 TransformNormal(Vector3 position, Matrix4 matrix) { return new Vector3( From d94f29d086f8686d865c38e034e32e77db64cfbe Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Mon, 8 Apr 2024 22:32:46 +0100 Subject: [PATCH 107/149] missing file --- .../JSON/JsonOSUTF8Writer.cs | 440 ++++++++++++++++++ 1 file changed, 440 insertions(+) create mode 100644 OpenMetaverse.StructuredData/JSON/JsonOSUTF8Writer.cs diff --git a/OpenMetaverse.StructuredData/JSON/JsonOSUTF8Writer.cs b/OpenMetaverse.StructuredData/JSON/JsonOSUTF8Writer.cs new file mode 100644 index 00000000..d5359524 --- /dev/null +++ b/OpenMetaverse.StructuredData/JSON/JsonOSUTF8Writer.cs @@ -0,0 +1,440 @@ + +using System; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Text; +using OpenMetaverse; + +namespace LitJson +{ + public class JsonOSUTF8Writer + { + #region Fields + private static NumberFormatInfo number_format; + + private WriterContext context; + private Stack ctx_stack; + private bool has_reached_end; + private byte[] hex_seq; + private int indentation; + private int indent_value; + private osUTF8 sb; + private bool ownsb; + private bool pretty_print; + private bool validate; + + #endregion + + #region Properties + public int IndentValue + { + get { return indent_value; } + set + { + indentation = (indentation / indent_value) * value; + indent_value = value; + } + } + + public bool PrettyPrint + { + get { return pretty_print; } + set { pretty_print = value; } + } + + public bool Validate + { + get { return validate; } + set { validate = value; } + } + #endregion + + #region Constructors + static JsonOSUTF8Writer() + { + number_format = NumberFormatInfo.InvariantInfo; + } + + public JsonOSUTF8Writer() + { + sb = OSUTF8Cached.Acquire(); + ownsb = true; + Init(); + } + + public JsonOSUTF8Writer(osUTF8 sb) + { + this.sb = sb; + ownsb = false; + Init(); + } + #endregion + + + #region Private Methods + private void DoValidation(Condition cond) + { + if (!context.ExpectingValue) + context.Count++; + + if (!validate) + return; + + if (has_reached_end) + throw new JsonException( + "A complete JSON symbol has already been written"); + + switch (cond) + { + case Condition.InArray: + if (!context.InArray) + throw new JsonException( + "Can't close an array here"); + break; + + case Condition.InObject: + if (!context.InObject || context.ExpectingValue) + throw new JsonException( + "Can't close an object here"); + break; + + case Condition.NotAProperty: + if (context.InObject && !context.ExpectingValue) + throw new JsonException( + "Expected a property"); + break; + + case Condition.Property: + if (!context.InObject || context.ExpectingValue) + throw new JsonException( + "Can't add a property here"); + break; + + case Condition.Value: + if (!context.InArray && + (!context.InObject || !context.ExpectingValue)) + throw new JsonException( + "Can't add a value here"); + + break; + } + } + + private void Init() + { + has_reached_end = false; + hex_seq = new byte[4]; + indentation = 0; + indent_value = 4; + pretty_print = false; + validate = true; + + ctx_stack = new Stack(); + context = new WriterContext(); + ctx_stack.Push(context); + } + + private void Indent() + { + if (pretty_print) + indentation += indent_value; + } + + + private void Put(string str) + { + if (pretty_print && !context.ExpectingValue) + for (int i = 0; i < indentation; i++) + sb.AppendASCII(' '); + + sb.AppendASCII(str); + } + + private void Put(char c) + { + if (pretty_print && !context.ExpectingValue) + for (int i = 0; i < indentation; i++) + sb.AppendASCII(' '); + + sb.AppendASCII(c); + } + + private void PutNewline() + { + PutNewline(true); + } + + private void PutNewline(bool add_comma) + { + if (add_comma && !context.ExpectingValue && + context.Count > 1) + sb.AppendASCII(','); + + if (pretty_print && !context.ExpectingValue) + sb.AppendASCII('\n'); + } + + private void PutString(string str) + { + if (pretty_print && !context.ExpectingValue) + for (int i = 0; i < indentation; i++) + sb.AppendASCII(' '); + + sb.AppendASCII('"'); + for (int i = 0; i < str.Length; i++) + { + char c = str[i]; + switch (c) + { + case '\n': + sb.AppendASCII("\\n"); + break; + + case '\r': + sb.AppendASCII("\\r"); + break; + + case '\t': + sb.AppendASCII("\\t"); + break; + + case '"': + case '\\': + sb.AppendASCII('\\'); + sb.AppendASCII(c); + break; + + case '\f': + sb.AppendASCII("\\f"); + break; + + case '\b': + sb.AppendASCII("\\b"); + break; + + default: + // Default, turn into a \uXXXX sequence + if (c >= 32 && c <= 126) + sb.AppendASCII(c); + else + { + sb.AppendASCII("\\u"); + sb.Append(Utils.NibbleToHexUpper((byte)(c >> 12))); + sb.Append(Utils.NibbleToHexUpper((byte)(c >> 8))); + sb.Append(Utils.NibbleToHexUpper((byte)(c >> 4))); + sb.Append(Utils.NibbleToHexUpper((byte)c)); + } + break; + } + } + sb.AppendASCII('"'); + } + + private void Unindent() + { + if (pretty_print) + indentation -= indent_value; + } + #endregion + + public override string ToString() + { + if (sb == null) + return String.Empty; + if (ownsb) + { + string ret = sb.ToString(); + OSUTF8Cached.Release(sb); + return ret; + } + return sb.ToString(); + } + + public byte[] ToBytes() + { + if (sb == null) + return new byte[0]; + if (ownsb) + return OSUTF8Cached.GetArrayAndRelease(sb); + return sb.ToArray(); + } + + public void Reset() + { + has_reached_end = false; + + ctx_stack.Clear(); + context = new WriterContext(); + ctx_stack.Push(context); + + if (sb != null) + sb.Clear(); + } + + public void Write(bool boolean) + { + DoValidation(Condition.Value); + PutNewline(); + + Put(boolean ? "true" : "false"); + + context.ExpectingValue = false; + } + + public void Write(decimal number) + { + DoValidation(Condition.Value); + PutNewline(); + + Put(Convert.ToString(number, number_format)); + + context.ExpectingValue = false; + } + + public void Write(double number) + { + DoValidation(Condition.Value); + PutNewline(); + + string str = Convert.ToString(number, number_format); + Put(str); + + if (str.IndexOfAny(new char[] { '.', 'E' }) == -1) + sb.AppendASCII(".0"); + + context.ExpectingValue = false; + } + + public void Write(int number) + { + DoValidation(Condition.Value); + PutNewline(); + + Put(Convert.ToString(number, number_format)); + + context.ExpectingValue = false; + } + + public void Write(long number) + { + DoValidation(Condition.Value); + PutNewline(); + + Put(Convert.ToString(number, number_format)); + + context.ExpectingValue = false; + } + + public void Write(string str) + { + DoValidation(Condition.Value); + PutNewline(); + + if (str == null) + Put("null"); + else + PutString(str); + + context.ExpectingValue = false; + } + + public void Write(ulong number) + { + DoValidation(Condition.Value); + PutNewline(); + + Put(Convert.ToString(number, number_format)); + + context.ExpectingValue = false; + } + + public void WriteArrayEnd() + { + DoValidation(Condition.InArray); + PutNewline(false); + + ctx_stack.Pop(); + if (ctx_stack.Count == 1) + has_reached_end = true; + else + { + context = ctx_stack.Peek(); + context.ExpectingValue = false; + } + + Unindent(); + Put(']'); + } + + public void WriteArrayStart() + { + DoValidation(Condition.NotAProperty); + PutNewline(); + + Put('['); + + context = new WriterContext(); + context.InArray = true; + ctx_stack.Push(context); + + Indent(); + } + + public void WriteObjectEnd() + { + DoValidation(Condition.InObject); + PutNewline(false); + + ctx_stack.Pop(); + if (ctx_stack.Count == 1) + has_reached_end = true; + else + { + context = ctx_stack.Peek(); + context.ExpectingValue = false; + } + + Unindent(); + Put('}'); + } + + public void WriteObjectStart() + { + DoValidation(Condition.NotAProperty); + PutNewline(); + + Put('{'); + + context = new WriterContext(); + context.InObject = true; + ctx_stack.Push(context); + + Indent(); + } + + public void WritePropertyName(string property_name) + { + DoValidation(Condition.Property); + PutNewline(); + + PutString(property_name); + + if (pretty_print) + { + if (property_name.Length > context.Padding) + context.Padding = property_name.Length; + + for (int i = context.Padding - property_name.Length; + i >= 0; i--) + sb.AppendASCII(' '); + + sb.AppendASCII(": "); + } + else + sb.AppendASCII(':'); + + context.ExpectingValue = true; + } + } +} From 1b4846b36471922f7263af10a4764e413e1725d4 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Mon, 8 Apr 2024 23:00:34 +0100 Subject: [PATCH 108/149] update readme --- README.md | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ README.txt | 55 --------------------------------------------- 2 files changed, 65 insertions(+), 55 deletions(-) create mode 100644 README.md delete mode 100644 README.txt diff --git a/README.md b/README.md new file mode 100644 index 00000000..3f1a5bec --- /dev/null +++ b/README.md @@ -0,0 +1,65 @@ +libOpenMetaverse Library Fork for OpenSimulator (version >= 0.9.3.0) + +for older Opensimulator versions >= 0.9.1.0 use branch Mono-Net4x + +# git clone + +get or update source from git + + `git clone https://bitbucket.org/opensimulator/libopenmetaverse.git` +or + `git clone https://github.com/UbitUmarov/libopenmetaverse.git´ + + +# Building on Windows + +## Requirements + To building under Windows, the following is required: + + * [dotnet 6.0 SDK, Runtime and Desktop Runtime](https://dotnet.microsoft.com/en-us/download/dotnet/6.0) + +optionally also + + * [Visual Studio .NET](https://visualstudio.microsoft.com/vs/features/net-development/), version 2022 or later + + +### Building + To create the project files, run + + `runprebuild.bat` + +run + `compile.bat` + +Or load the generated OpenSim.sln into Visual Studio and build the solution. + +Configure, see below + +Now just run `OpenSim.exe` from the `bin` folder, and set up the region. + +# Building on Linux / Mac + +## Requirements + + * [dotnet 6.0 SDK and Runtime](https://dotnet.microsoft.com/en-us/download/dotnet/6.0) + * libgdiplus + + if you have mono 6.x complete, you already have libgdiplus, otherwise you need to install it + using a package manager for your operating system, like apt, brew, macports, etc + for example on debian: + + `apt-get update && apt-get install -y apt-utils libgdiplus libc6-dev` + +### Building + To create the project files, run: + + `./runprebuild.sh` + + then run + + `compile.bat`` + + +### Current building problems +several projest will only compile and run on windows +many of those project also need fixes on their project files to set the framework to netxxx-windows and allow windows forms diff --git a/README.txt b/README.txt deleted file mode 100644 index de4135af..00000000 --- a/README.txt +++ /dev/null @@ -1,55 +0,0 @@ -libOpenMetaverse Library Fork for OpenSimulator (version >= 0.9.1.0) - - -Finding Help ------------- - -If you need any help we have a couple of resources, the primary one being -the #opensim-dev IRC channel on Freenode. - - -Getting started on Windows -==================================================================================== - - -Prerequisites (all Freely Available) --------------------------------------- - -Microsoft .NET Framework 4.6 -Visual Visual Studio (community) 2017 - -Compiling ---------- -1. Open Explorer and browse to the directory you extracted the source distribution to -2. Double click the runprebuild.bat file, this will create the necessary solution and project files -3. open the solution OpenMetaverse.sln from within Visual Studio -4. From the Build Menu choose Build Solution (or press the F6 Key) - -The library, example applications and tools will be in the bin directory - - -Getting started on Linux -==================================================================================== - -Prerequisites Needed --------------------- - -mono 5.x - https://www.mono-project.com/download/stable/#download-lin -(install mono.complete) - -Compiling ---------- -1. Change to the directory you extracted the source distribution to -2. run the prebuild file: % sh runprebuild.sh - This will generate the solution files for xbuild - -using xbuild -3. Compile the solution with the command: % xbuild OpenMetaverse.sln -using msbuild -3. Compile the solution with the command: % msbuild OpenMetaverse.sln - -The library, example applications and tools will be in the bin directory - - -Happy fiddling, --- OpenMetaverse Ninjas - From d0f2621d25ef07c9e5a09ebf272fdb30b0e9437a Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Mon, 8 Apr 2024 23:06:48 +0100 Subject: [PATCH 109/149] update runprebuild. bat/sh --- runprebuild.bat | 1 + runprebuild.sh | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/runprebuild.bat b/runprebuild.bat index af3d48e7..58f6e4c7 100644 --- a/runprebuild.bat +++ b/runprebuild.bat @@ -1,5 +1,6 @@ @echo OFF +copy bin\System.Drawing.Common.dll.win bin\System.Drawing.Common.dll dotnet bin\prebuild.dll /target vs2022 /targetframework net6_0 /excludedir = "obj | bin" /file prebuild.xml @echo Creating compile.bat diff --git a/runprebuild.sh b/runprebuild.sh index cc5561b3..a1999427 100755 --- a/runprebuild.sh +++ b/runprebuild.sh @@ -18,10 +18,10 @@ case "$1" in *) + cp bin/System.Drawing.Common.dll.linux bin/System.Drawing.Common.dll dotnet bin/prebuild.dll /target vs2022 /targetframework net6_0 /excludedir = "obj | bin" /file prebuild.xml echo "dotnet build -c Release OpenMetaverse.sln" > compile.sh chmod +x compile.sh - cp bin/System.Drawing.Common.dll.linux bin/System.Drawing.Common.dll ;; From 56220ac592a29aaee0fa461da143f991b6f0f826 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Mon, 8 Apr 2024 23:15:15 +0100 Subject: [PATCH 110/149] update github workflow --- .github/workflows/dotnet.yml | 10 +++++----- README.md | 7 +++++-- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index df48378a..18261fa3 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -1,4 +1,4 @@ -name: msbuild48 +name: msbuild on: push: @@ -18,10 +18,10 @@ jobs: id: vars run: echo "::set-output name=sha_short::$(git rev-parse --short HEAD)" - name: preBuild - run: bash ${GITHUB_WORKSPACE}/runprebuild48.sh + run: bash ${GITHUB_WORKSPACE}/runprebuild.sh - name: Build id: build - run: msbuild /p:Configuration=Release OpenMetaverse.sln + run: dotnet build --configuration Releas OpenMetaverse.sln - name: release if: success() run: zip -r LastBuild.zip bin LICENSE.txt @@ -37,7 +37,7 @@ jobs: with: channel: "#opensim-dev" server: "irc.libera.chat" - nickname: osgithub + nickname: osgithubomv message: | ${{ github.actor }} pushed to ${{ github.repository }} ${{ join(github.event.commits.*.message, '\n') }} @@ -51,4 +51,4 @@ jobs: nickname: osgithub message: | ${{ github.repository }} - mono compile: ${{ steps.build.conclusion }} + dotnet compile: ${{ steps.build.conclusion }} diff --git a/README.md b/README.md index 3f1a5bec..c30c442f 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,9 @@ for older Opensimulator versions >= 0.9.1.0 use branch Mono-Net4x get or update source from git `git clone https://bitbucket.org/opensimulator/libopenmetaverse.git` + or + `git clone https://github.com/UbitUmarov/libopenmetaverse.git´ @@ -28,7 +30,8 @@ optionally also `runprebuild.bat` -run +run + `compile.bat` Or load the generated OpenSim.sln into Visual Studio and build the solution. @@ -61,5 +64,5 @@ Now just run `OpenSim.exe` from the `bin` folder, and set up the region. ### Current building problems -several projest will only compile and run on windows +several projects will only compile and run on windows many of those project also need fixes on their project files to set the framework to netxxx-windows and allow windows forms From 4ab7b2d437ecb10747a2dbfe9ca8db1ae07b2220 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Mon, 8 Apr 2024 23:42:41 +0100 Subject: [PATCH 111/149] update several files --- .github/workflows/dotnet.yml | 2 +- OpenMetaverseTypes/Matrix3x3.cs | 111 ++++++++++++++------ OpenMetaverseTypes/Matrix4.cs | 47 +++++++++ OpenMetaverseTypes/OSUTF8.cs | 25 +++++ OpenMetaverseTypes/UUID.cs | 36 +++---- OpenMetaverseTypes/Vector3.cs | 175 +++++++++++++++++++++++++++++--- README.md | 4 +- prebuild.xml | 2 +- 8 files changed, 331 insertions(+), 71 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 18261fa3..b1bc9015 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -21,7 +21,7 @@ jobs: run: bash ${GITHUB_WORKSPACE}/runprebuild.sh - name: Build id: build - run: dotnet build --configuration Releas OpenMetaverse.sln + run: dotnet build --configuration Release OpenMetaverse.sln - name: release if: success() run: zip -r LastBuild.zip bin LICENSE.txt diff --git a/OpenMetaverseTypes/Matrix3x3.cs b/OpenMetaverseTypes/Matrix3x3.cs index 8f96c0b6..8ff3c797 100644 --- a/OpenMetaverseTypes/Matrix3x3.cs +++ b/OpenMetaverseTypes/Matrix3x3.cs @@ -25,7 +25,11 @@ */ using System; +using System.Runtime.CompilerServices; using System.Runtime.InteropServices; +using System.Runtime.Intrinsics.X86; +using System.Runtime.Intrinsics; +using System.IO; namespace OpenMetaverse { @@ -105,22 +109,31 @@ public Matrix3x3( public Matrix3x3(float roll, float pitch, float yaw) { - this = CreateFromEulers(roll, pitch, yaw); - } + float a = MathF.Cos(roll); + float b = MathF.Sin(roll); + float c = MathF.Cos(pitch); + float d = MathF.Sin(pitch); + float e = MathF.Cos(yaw); + float f = MathF.Sin(yaw); - public Matrix3x3(Matrix3x3 m) - { - M11 = m.M11; - M12 = m.M12; - M13 = m.M13; + float ad = a * d; + float bd = b * d; + M11 = c * e; + M12 = -c * f; + M13 = d; - M21 = m.M21; - M22 = m.M22; - M23 = m.M23; + M21 = bd * e + a * f; + M22 = -bd * f + a * e; + M23 = -b * c; + + M31 = -ad * e + b * f; + M32 = ad * f + b * e; + M33 = a * c; + } - M31 = m.M31; - M32 = m.M32; - M33 = m.M33; + public Matrix3x3(Matrix3x3 m) + { + this = m; } #endregion Constructors @@ -202,12 +215,13 @@ public void GetEulerAngles(out float roll, out float pitch, out float yaw) /// Convert this matrix to a quaternion rotation /// /// A quaternion representation of this rotation matrix + [MethodImpl(MethodImplOptions.AggressiveInlining)] public Quaternion GetQuaternion() { Quaternion quat = new Quaternion(); float trace = Trace() + 1f; - if (trace > Single.Epsilon) + if (trace > float.Epsilon) { float s = 0.5f / MathF.Sqrt(trace); @@ -270,13 +284,14 @@ public bool Decompose(out Vector3 scale, out Quaternion rotation) rotation = Quaternion.CreateFromRotationMatrix(m1); return true; - } + } #endregion Public Methods #region Static Methods - public static Matrix3x3 Add(Matrix3x3 matrix1, in Matrix3x3 matrix2) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Matrix3x3 Add(Matrix3x3 matrix1, in Matrix3x3 matrix2) { return new Matrix3x3( matrix1.M11 + matrix2.M11, @@ -355,7 +370,8 @@ public static Matrix3x3 CreateFromEulers(float roll, float pitch, float yaw) ); } - public static Matrix3x3 CreateFromQuaternion(Quaternion rot) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Matrix3x3 CreateFromQuaternion(Quaternion rot) { float x2 = rot.X + rot.X; float y2 = rot.Y + rot.Y; @@ -378,26 +394,61 @@ public static Matrix3x3 CreateFromQuaternion(Quaternion rot) ); } - public static Matrix3x3 CreateFromInverseQuaternion(Quaternion rot) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Matrix3x3 CreateFromQuaternion(ref Quaternion rot) { + float wx2, wy2, wz2; + float xx2, xy2, xz2; + float yy2, yz2; + float zz2; + + if (Sse41.IsSupported) + { + unsafe + { + Vector128 vrot = Sse.LoadVector128((float*)Unsafe.AsPointer(ref rot)); + Vector128 vrot2 = Sse.Add(vrot, vrot); + Vector128 v2 = Sse.Multiply(vrot, vrot2); + xx2 = Vector128.GetElement(v2, 0); + yy2 = Vector128.GetElement(v2, 1); + zz2 = Vector128.GetElement(v2, 3); + + v2 = Sse.Multiply(vrot2, Sse3.Shuffle(vrot, vrot, 0xff)); + wx2 = Vector128.GetElement(v2, 0); + wy2 = Vector128.GetElement(v2, 1); + wz2 = Vector128.GetElement(v2, 2); + + v2 = Sse.Multiply(vrot2, Sse3.Shuffle(vrot, vrot, 0x00)); + xy2 = Vector128.GetElement(v2, 1); + xz2 = Vector128.GetElement(v2, 2); + + yz2 = Vector128.GetElement(vrot, 1) * Vector128.GetElement(vrot2, 2); + + return new Matrix3x3( + 1.0f - yy2 - zz2, xy2 + wz2, xz2 - wy2, + xy2 - wz2, 1.0f - xx2 - zz2, yz2 + wx2, + xz2 + wy2, yz2 - wx2, 1.0f - xx2 - yy2); + } + } + float x2 = rot.X + rot.X; float y2 = rot.Y + rot.Y; float z2 = rot.Z + rot.Z; - float wx2 = rot.W * x2; - float wy2 = rot.W * y2; - float wz2 = rot.W * z2; - float xx2 = rot.X * x2; - float xy2 = rot.X * y2; - float xz2 = rot.X * z2; - float yy2 = rot.Y * y2; - float yz2 = rot.Y * z2; - float zz2 = rot.Z * z2; + wx2 = rot.W * x2; + wy2 = rot.W * y2; + wz2 = rot.W * z2; + xx2 = rot.X * x2; + xy2 = rot.X * y2; + xz2 = rot.X * z2; + yy2 = rot.Y * y2; + yz2 = rot.Y * z2; + zz2 = rot.Z * z2; return new Matrix3x3( - 1.0f - yy2 - zz2, xy2 - wz2, xz2 + wy2, - xy2 + wz2, 1.0f - xx2 - zz2, yz2 - wx2, - xz2 - wy2, yz2 + wx2, 1.0f - xx2 - yy2 + 1.0f - yy2 - zz2, xy2 + wz2, xz2 - wy2, + xy2 - wz2, 1.0f - xx2 - zz2, yz2 + wx2, + xz2 + wy2, yz2 - wx2, 1.0f - xx2 - yy2 ); } diff --git a/OpenMetaverseTypes/Matrix4.cs b/OpenMetaverseTypes/Matrix4.cs index 097f5e10..915a1a72 100644 --- a/OpenMetaverseTypes/Matrix4.cs +++ b/OpenMetaverseTypes/Matrix4.cs @@ -25,6 +25,7 @@ */ using System; +using System.Runtime.CompilerServices; using System.Runtime.InteropServices; namespace OpenMetaverse @@ -92,6 +93,8 @@ public Matrix4( float m31, float m32, float m33, float m34, float m41, float m42, float m43, float m44) { + Unsafe.SkipInit(out this); + M11 = m11; M12 = m12; M13 = m13; @@ -440,6 +443,28 @@ public static Matrix4 CreateFromQuaternion(Quaternion rot) 0, 0, 0, 1.0f); } + public static Matrix4 CreateFromQuaternion(ref Quaternion rot) + { + float x2 = rot.X + rot.X; + float y2 = rot.Y + rot.Y; + float z2 = rot.Z + rot.Z; + + float wx2 = rot.W * x2; + float wy2 = rot.W * y2; + float wz2 = rot.W * z2; + float xx2 = rot.X * x2; + float xy2 = rot.X * y2; + float xz2 = rot.X * z2; + float yy2 = rot.Y * y2; + float yz2 = rot.Y * z2; + float zz2 = rot.Z * z2; + + return new Matrix4( + 1.0f - yy2 - zz2, xy2 + wz2, xz2 - wy2, 0, + xy2 - wz2, 1.0f - xx2 - zz2, yz2 + wx2, 0, + xz2 + wy2, yz2 - wx2, 1.0f - xx2 - yy2, 0, + 0, 0, 0, 1.0f); + } public static Matrix4 CreateFromInverseQuaternion(Quaternion rot) { float x2 = rot.X + rot.X; @@ -463,6 +488,28 @@ public static Matrix4 CreateFromInverseQuaternion(Quaternion rot) 0, 0, 0, 1.0f); } + public static Matrix4 CreateFromInverseQuaternion(ref Quaternion rot) + { + float x2 = rot.X + rot.X; + float y2 = rot.Y + rot.Y; + float z2 = rot.Z + rot.Z; + + float wx2 = rot.W * x2; + float wy2 = rot.W * y2; + float wz2 = rot.W * z2; + float xx2 = rot.X * x2; + float xy2 = rot.X * y2; + float xz2 = rot.X * z2; + float yy2 = rot.Y * y2; + float yz2 = rot.Y * z2; + float zz2 = rot.Z * z2; + + return new Matrix4( + 1.0f - yy2 - zz2, xy2 - wz2, xz2 + wy2, 0, + xy2 + wz2, 1.0f - xx2 - zz2, yz2 - wx2, 0, + xz2 - wy2, yz2 + wx2, 1.0f - xx2 - yy2, 0, + 0, 0, 0, 1.0f); + } public static Matrix4 CreateLookAt(Vector3 cameraPosition, Vector3 cameraTarget, Vector3 cameraUpVector) { Matrix4 matrix; diff --git a/OpenMetaverseTypes/OSUTF8.cs b/OpenMetaverseTypes/OSUTF8.cs index 6f9d4301..967156e1 100644 --- a/OpenMetaverseTypes/OSUTF8.cs +++ b/OpenMetaverseTypes/OSUTF8.cs @@ -108,6 +108,7 @@ public osUTF8(string source, int maxlen) m_len = m_data.Length; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public osUTF8(string source, bool isascii) { if(isascii) @@ -273,6 +274,7 @@ public unsafe bool Equals(osUTF8 o) return true; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool Equals(string s) { if (string.IsNullOrEmpty(s)) @@ -407,6 +409,7 @@ public void Clear() m_len = 0; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public osUTF8 Clone() { byte[] b = new byte[m_data.Length]; @@ -414,6 +417,7 @@ public osUTF8 Clone() return new osUTF8(b); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public osUTF8 Extract() { byte[] b = new byte[m_len]; @@ -421,6 +425,7 @@ public osUTF8 Extract() return new osUTF8(b); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public byte[] ToArray() { byte[] b = new byte[m_len]; @@ -434,6 +439,7 @@ public byte[] GetArray() return m_data; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public osUTF8 Concat(osUTF8 other) { byte[] b = new byte[m_len + other.m_len]; @@ -520,6 +526,7 @@ public void Append(string s) m_len = indx; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(byte[] b) { int nbytes = b.Length; @@ -528,6 +535,18 @@ public void Append(byte[] b) m_len += nbytes; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(byte[] b, int bstart, int nbytes) + { + if(bstart + nbytes >= b.Length) + nbytes = b.Length - bstart; + + CheckCapacity(nbytes); + Array.Copy(b, bstart, m_data, m_len, nbytes); + m_len += nbytes; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(osUTF8 b) { int nbytes = b.m_len; @@ -536,6 +555,7 @@ public void Append(osUTF8 b) m_len += nbytes; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe void AppendInt(sbyte v) { CheckCapacity(4); @@ -543,12 +563,15 @@ public unsafe void AppendInt(sbyte v) m_len += Utils.IntToByteString(v, d + m_len); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe void AppendInt(byte v) { CheckCapacity(3); fixed (byte* d = m_data) m_len += Utils.UIntToByteString(v, d + m_len); } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe void AppendInt(int v) { CheckCapacity(16); @@ -556,6 +579,7 @@ public unsafe void AppendInt(int v) m_len += Utils.IntToByteString(v, d + m_len); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe void AppendInt(uint v) { CheckCapacity(16); @@ -563,6 +587,7 @@ public unsafe void AppendInt(uint v) m_len += Utils.UIntToByteString(v, d + m_len); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe void AppendInt(long v) { CheckCapacity(32); diff --git a/OpenMetaverseTypes/UUID.cs b/OpenMetaverseTypes/UUID.cs index b75b83a1..b38bddf6 100644 --- a/OpenMetaverseTypes/UUID.cs +++ b/OpenMetaverseTypes/UUID.cs @@ -77,19 +77,7 @@ public struct UUID : IComparable,IComparable, IEquatable, IEqualityC [FieldOffset(0)] public Guid Guid; #region Constructors - /* - public Guid Guid - { - get - { - return Unsafe.As(ref this); - } - set - { - Unsafe.As(ref this) = value; - } - } - */ + /// /// Constructor that takes a string UUID representation /// @@ -103,7 +91,8 @@ public UUID(string sval) : this(sval.AsSpan()) public unsafe UUID(ReadOnlySpan sval) { - this = new UUID(); + Unsafe.SkipInit(out this); + int len = sval.Length; if (len < 32) throw new FormatException("Invalid UUID"); @@ -301,14 +290,16 @@ public unsafe UUID(ReadOnlySpan sval) /// A Guid object that contains the unique identifier /// to be represented by this UUID [MethodImpl(MethodImplOptions.AggressiveInlining)] - public unsafe UUID(Guid val) + public UUID(Guid val) { - this = *(UUID*)&val; + Unsafe.SkipInit(out this); + Guid = val; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public unsafe UUID(ulong _la, ulong _lb) : this() + public UUID(ulong _la, ulong _lb) { + Unsafe.SkipInit(out this); ulonga = _la; ulongb = _lb; } @@ -319,9 +310,10 @@ public unsafe UUID(ulong _la, ulong _lb) : this() /// Byte array containing a 16 byte UUID /// Beginning offset in the array [MethodImpl(MethodImplOptions.AggressiveInlining)] - public unsafe UUID(byte[] source, int pos) : this() + public unsafe UUID(byte[] source, int pos) { - if(Ssse3.IsSupported) + Unsafe.SkipInit(out this); + if (Ssse3.IsSupported) { Vector128 rawval = Unsafe.As>(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(source), pos)); if (BitConverter.IsLittleEndian) @@ -369,8 +361,9 @@ public unsafe UUID(byte[] source, int pos) : this() /// /// 64-bit unsigned integer to convert to a UUID [MethodImpl(MethodImplOptions.AggressiveInlining)] - public UUID(ulong val) : this() + public UUID(ulong val) { + Unsafe.SkipInit(out this); if (BitConverter.IsLittleEndian) ulongb = val; else @@ -392,6 +385,7 @@ public UUID(ulong val) : this() /// UUID to copy public UUID(UUID val) { + Unsafe.SkipInit(out this); this = val; } @@ -407,7 +401,7 @@ public readonly int CompareTo(object val) if (val == null) return 1; - UUID id = (UUID)val; + ref UUID id = ref Unsafe.Unbox(val); if (id.a != a) return (uint)id.a > (uint)a ? -1 : 1; if (id.b != b) diff --git a/OpenMetaverseTypes/Vector3.cs b/OpenMetaverseTypes/Vector3.cs index 1b4a1784..0c0c5d48 100644 --- a/OpenMetaverseTypes/Vector3.cs +++ b/OpenMetaverseTypes/Vector3.cs @@ -48,7 +48,7 @@ public struct Vector3 : IComparable, IEquatable public float Y; /// Z value public float Z; - + #region Constructors [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -91,17 +91,37 @@ public Vector3(Vector3 vector) Z = vector.Z; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vector3(Vector128 v) + { + Unsafe.SkipInit(out this); + unsafe + { + Sse2.StoreScalar((double*)Unsafe.AsPointer(ref X), v.AsDouble()); + Sse2.StoreScalar((float*)Unsafe.AsPointer(ref Z), Sse2.Shuffle(v.AsInt32(), 0x02).AsSingle()); + } + } + /// /// Constructor, builds a vector from a byte array /// /// Byte array containing three four-byte floats /// Beginning position in the byte array + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vector3(byte[] byteArray) + { + this = Unsafe.ReadUnaligned(ref MemoryMarshal.GetArrayDataReference(byteArray)); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public Vector3(byte[] byteArray, int pos) { - X = Utils.BytesToFloatSafepos(byteArray, pos); - Y = Utils.BytesToFloatSafepos(byteArray, pos + 4); - Z = Utils.BytesToFloatSafepos(byteArray, pos + 8); + this = Unsafe.ReadUnaligned(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(byteArray), pos)); + } + + public Vector3(ReadOnlySpan bytes) + { + this = Unsafe.ReadUnaligned(ref MemoryMarshal.GetReference(bytes)); } #endregion Constructors @@ -326,7 +346,7 @@ public void FromBytes(byte[] byteArray, int pos) public readonly byte[] GetBytes() { byte[] dest = new byte[12]; - Unsafe.WriteUnaligned(ref MemoryMarshal.GetArrayDataReference(dest), this); + Unsafe.WriteUnaligned(ref MemoryMarshal.GetArrayDataReference(dest), this); return dest; } @@ -339,17 +359,16 @@ public readonly byte[] GetBytes() [MethodImpl(MethodImplOptions.AggressiveInlining)] public readonly unsafe void ToBytes(byte[] dest, int pos) { - if (Utils.CanDirectCopyLE) - { - fixed (byte* d = &dest[0]) - *(Vector3*)(d + pos) = this; - } - else - { - Utils.FloatToBytesSafepos(X, dest, pos); - Utils.FloatToBytesSafepos(Y, dest, pos + 4); - Utils.FloatToBytesSafepos(Z, dest, pos + 8); - } + //if (Utils.CanDirectCopyLE) + //{ + Unsafe.WriteUnaligned(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(dest), pos), this); + //} + //else + //{ + // Utils.FloatToBytesSafepos(X, dest, pos); + // Utils.FloatToBytesSafepos(Y, dest, pos + 4); + // Utils.FloatToBytesSafepos(Z, dest, pos + 8); + //} } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -1191,6 +1210,130 @@ public static Vector3 InverseRotateByShortQZ(Vector3 vec, Vector2 shortQuaternio vec.Y * zz2 - vec.X * wz2, vec.Z); } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vector3 TransformPositionOffset(ref Quaternion ParentRot, ref Vector3 ParentPos) + { + float x2 = ParentRot.X + ParentRot.X; + float y2 = ParentRot.Y + ParentRot.Y; + float z2 = ParentRot.Z + ParentRot.Z; + + float wx2 = ParentRot.W * x2; + float wy2 = ParentRot.W * y2; + float wz2 = ParentRot.W * z2; + + float xx2 = ParentRot.X * x2; + float xy2 = ParentRot.X * y2; + float xz2 = ParentRot.X * z2; + + float yy2 = ParentRot.Y * y2; + float yz2 = ParentRot.Y * z2; + + float zz2 = ParentRot.Z * z2; + + return new Vector3( + ParentPos.X + X * (1.0f - yy2 - zz2) + Y * (xy2 - wz2) + Z * (xz2 + wy2), + ParentPos.Y + X * (xy2 + wz2) + Y * (1.0f - xx2 - zz2) + Z * (yz2 - wx2), + ParentPos.Z + X * (xz2 - wy2) + Y * (yz2 + wx2) + Z * (1.0f - xx2 - yy2)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vector3 TransformPositionOffset(ref Matrix3x3 ParentRot, ref Vector3 ParentPos) + { + if (Sse.IsSupported) + { + unsafe + { + Vector128 result = Sse.Multiply(Sse.LoadVector128((float*)Unsafe.AsPointer(ref ParentRot.M11)), Vector128.Create(X)); + result = Sse.Add(result, Sse.Multiply(Sse.LoadVector128((float*)Unsafe.AsPointer(ref ParentRot.M21)), Vector128.Create(Y))); + result = Sse.Add(result, Sse.Multiply(Sse.LoadVector128((float*)Unsafe.AsPointer(ref ParentRot.M31)), Vector128.Create(Z))); + result = Sse.Add(result, Sse.LoadVector128((float*)Unsafe.AsPointer(ref ParentPos))); + return new Vector3(result); + } + } + + return new Vector3( + ParentPos.X + X * ParentRot.M11 + Y * ParentRot.M21 + Z * ParentRot.M31, + ParentPos.Y + X * ParentRot.M12 + Y * ParentRot.M22 + Z * ParentRot.M32, + ParentPos.Z + X * ParentRot.M13 + Y * ParentRot.M23 + Z * ParentRot.M33); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector3 TransformPositionOffset(ref Quaternion ParentRot, ref Vector3 ParentPos, ref Vector3 Partoffset) + { + float x2 = ParentRot.X + ParentRot.X; + float y2 = ParentRot.Y + ParentRot.Y; + float z2 = ParentRot.Z + ParentRot.Z; + + float wx2 = ParentRot.W * x2; + float wy2 = ParentRot.W * y2; + float wz2 = ParentRot.W * z2; + float xx2 = ParentRot.X * x2; + float xy2 = ParentRot.X * y2; + float xz2 = ParentRot.X * z2; + float yy2 = ParentRot.Y * y2; + float yz2 = ParentRot.Y * z2; + float zz2 = ParentRot.Z * z2; + + return new Vector3( + ParentPos.X + Partoffset.X * (1.0f - yy2 - zz2) + Partoffset.Y * (xy2 - wz2) + Partoffset.Z * (xz2 + wy2), + ParentPos.Y + Partoffset.X * (xy2 + wz2) + Partoffset.Y * (1.0f - xx2 - zz2) + Partoffset.Z * (yz2 - wx2), + ParentPos.Z + Partoffset.X * (xz2 - wy2) + Partoffset.Y * (yz2 + wx2) + Partoffset.Z * (1.0f - xx2 - yy2)); + } + + internal struct vtmp + { + public double a; + public float b; + public vtmp(Vector128 v) + { + a = Vector128.GetElement(v.AsDouble(), 0); + b = Vector128.GetElement(v, 2); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector3 TransformPositionOffset(ref Matrix3x3 ParentRot, ref Vector3 ParentPos, ref Vector3 Partoffset) + { + if (Sse.IsSupported) + { + unsafe + { + Vector128 result = Sse.Multiply(Sse.LoadVector128((float*)Unsafe.AsPointer(ref ParentRot.M11)), Vector128.Create(Partoffset.X)); + result = Sse.Add(result, Sse.Multiply(Sse.LoadVector128((float*)Unsafe.AsPointer(ref ParentRot.M21)), Vector128.Create(Partoffset.Y))); + result = Sse.Add(result, Sse.Multiply(Sse.LoadVector128((float*)Unsafe.AsPointer(ref ParentRot.M31)), Vector128.Create(Partoffset.Z))); + result = Sse.Add(result, Sse.LoadVector128((float*)Unsafe.AsPointer(ref ParentPos))); + return new Vector3(result); + } + } + + return new Vector3( + ParentPos.X + Partoffset.X * ParentRot.M11 + Partoffset.Y * ParentRot.M12 + Partoffset.Z * ParentRot.M13, + ParentPos.Y + Partoffset.X * ParentRot.M21 + Partoffset.Y * ParentRot.M22 + Partoffset.Z * ParentRot.M23, + ParentPos.Z + Partoffset.X * ParentRot.M31 + Partoffset.Y * ParentRot.M32 + Partoffset.Z * ParentRot.M33); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector3 TransformPositionOffset(Matrix3x3 ParentRot, Vector3 ParentPos, Vector3 Partoffset) + { + if (Sse.IsSupported) + { + unsafe + { + Vector128 result = Sse.Multiply(Sse.LoadVector128((float*)Unsafe.AsPointer(ref ParentRot.M11)), Vector128.Create(Partoffset.X)); + result = Sse.Add(result, Sse.Multiply(Sse.LoadVector128((float*)Unsafe.AsPointer(ref ParentRot.M21)), Vector128.Create(Partoffset.Y))); + result = Sse.Add(result, Sse.Multiply(Sse.LoadVector128((float*)Unsafe.AsPointer(ref ParentRot.M31)), Vector128.Create(Partoffset.Z))); + result = Sse.Add(result, Sse.LoadVector128((float*)Unsafe.AsPointer(ref ParentPos))); + return new Vector3(result); + } + } + + return new Vector3( + ParentPos.X + Partoffset.X * ParentRot.M11 + Partoffset.Y * ParentRot.M12 + Partoffset.Z * ParentRot.M13, + ParentPos.Y + Partoffset.X * ParentRot.M21 + Partoffset.Y * ParentRot.M22 + Partoffset.Z * ParentRot.M23, + ParentPos.Z + Partoffset.X * ParentRot.M31 + Partoffset.Y * ParentRot.M32 + Partoffset.Z * ParentRot.M33); + } + #endregion Static Methods #region Overrides diff --git a/README.md b/README.md index c30c442f..396694cc 100644 --- a/README.md +++ b/README.md @@ -6,11 +6,11 @@ for older Opensimulator versions >= 0.9.1.0 use branch Mono-Net4x get or update source from git - `git clone https://bitbucket.org/opensimulator/libopenmetaverse.git` + `clone https://bitbucket.org/opensimulator/libopenmetaverse.git` or - `git clone https://github.com/UbitUmarov/libopenmetaverse.git´ + `git clone https://github.com/UbitUmarov/libopenmetaverse.git` # Building on Windows diff --git a/prebuild.xml b/prebuild.xml index 71c3b88f..5e50a86b 100644 --- a/prebuild.xml +++ b/prebuild.xml @@ -1,6 +1,6 @@ - + TRACE;DEBUG From 5e527e029884bd651d7a447d4fbbd8748ee719cc Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Mon, 8 Apr 2024 23:48:10 +0100 Subject: [PATCH 112/149] oops workflow does not work, remove for now --- .github/workflows/dotnet.yml | 54 ------------------------------------ 1 file changed, 54 deletions(-) delete mode 100644 .github/workflows/dotnet.yml diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml deleted file mode 100644 index b1bc9015..00000000 --- a/.github/workflows/dotnet.yml +++ /dev/null @@ -1,54 +0,0 @@ -name: msbuild - -on: - push: - branches: [ "master" ] - paths: - - '**.cs' - workflow_dispatch: - -jobs: - build: - if: github.repository == 'UbitUmarov/libopenmetaverse' - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v3 - - name: readshortsha - id: vars - run: echo "::set-output name=sha_short::$(git rev-parse --short HEAD)" - - name: preBuild - run: bash ${GITHUB_WORKSPACE}/runprebuild.sh - - name: Build - id: build - run: dotnet build --configuration Release OpenMetaverse.sln - - name: release - if: success() - run: zip -r LastBuild.zip bin LICENSE.txt - - uses: softprops/action-gh-release@v1 - if: success() - with: - tag_name: r${{ steps.vars.outputs.sha_short }} - name: LastAutoBuild - files: LastBuild.zip - - name: report push to irc - if: github.event_name == 'push' - uses: rectalogic/notify-irc@v1 - with: - channel: "#opensim-dev" - server: "irc.libera.chat" - nickname: osgithubomv - message: | - ${{ github.actor }} pushed to ${{ github.repository }} - ${{ join(github.event.commits.*.message, '\n') }} - mono compile: ${{ steps.build.conclusion }} - - name: report manual irc - if: github.event_name == 'workflow_dispatch' - uses: rectalogic/notify-irc@v1 - with: - channel: "#opensim-dev" - server: "irc.libera.chat" - nickname: osgithub - message: | - ${{ github.repository }} - dotnet compile: ${{ steps.build.conclusion }} From 7751a44bcf264026c542eb35fdd77824b57c69ae Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Tue, 9 Apr 2024 00:17:18 +0100 Subject: [PATCH 113/149] update readme --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 396694cc..1392e735 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,11 @@ for older Opensimulator versions >= 0.9.1.0 use branch Mono-Net4x get or update source from git - `clone https://bitbucket.org/opensimulator/libopenmetaverse.git` + `git clone https://bitbucket.org/opensimulator/libopenmetaverse.git` + +or + + `git clone https://github.com/opensim/libopenmetaverse.git` or From 842985f40743c9ef772bbe824fbfd7bfc28a8e22 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Tue, 9 Apr 2024 00:44:15 +0100 Subject: [PATCH 114/149] change prebuild to only compile basic core libs for opensimulator --- prebuildCoreLib.xml | 190 ++++++++++++++++++++++++++++++++++++++++++++ runprebuild.bat | 2 +- runprebuild.sh | 2 +- runprebuildFull.bat | 19 +++++ runprebuildFull.sh | 28 +++++++ 5 files changed, 239 insertions(+), 2 deletions(-) create mode 100755 prebuildCoreLib.xml create mode 100755 runprebuildFull.bat create mode 100755 runprebuildFull.sh diff --git a/prebuildCoreLib.xml b/prebuildCoreLib.xml new file mode 100755 index 00000000..b5ce209b --- /dev/null +++ b/prebuildCoreLib.xml @@ -0,0 +1,190 @@ + + + + + + TRACE;DEBUG + false + false + true + 4 + false + 1591,1574,0419,0618 + bin + true + true + false + false + true + false + false + false + + + + + TRACE + true + false + true + 4 + false + 1591,1574,0419,0618 + bin + false + true + false + false + true + false + false + false + + + + + + + + + ../bin/ + + + + + ../bin/ + + + + ../bin/ + + + + + + + + + + + + + + ../bin/ + + + + + ../bin/ + + + + ../bin/ + + + + + + + + + + + + ../bin/ + + + + + ../bin/ + + + + ../bin/ + + + + + + + + + + + + ../bin/ + + + + + ../bin/ + + + + ../bin/ + + + + + + + + + + + + + + + + + + + ../bin/ + + + + + ../bin/ + + + + ../bin/ + + + + + + + + + + + + + + + + + ../../bin/ + + + + + ../../bin/ + + + + ../../bin/ + + + + + + + + + + + + diff --git a/runprebuild.bat b/runprebuild.bat index 58f6e4c7..d671c577 100644 --- a/runprebuild.bat +++ b/runprebuild.bat @@ -1,7 +1,7 @@ @echo OFF copy bin\System.Drawing.Common.dll.win bin\System.Drawing.Common.dll -dotnet bin\prebuild.dll /target vs2022 /targetframework net6_0 /excludedir = "obj | bin" /file prebuild.xml +dotnet bin\prebuild.dll /target vs2022 /targetframework net6_0 /excludedir = "obj | bin" /file prebuildCoreLib.xml @echo Creating compile.bat rem To compile in debug mode diff --git a/runprebuild.sh b/runprebuild.sh index a1999427..71ba485a 100755 --- a/runprebuild.sh +++ b/runprebuild.sh @@ -19,7 +19,7 @@ case "$1" in *) cp bin/System.Drawing.Common.dll.linux bin/System.Drawing.Common.dll - dotnet bin/prebuild.dll /target vs2022 /targetframework net6_0 /excludedir = "obj | bin" /file prebuild.xml + dotnet bin/prebuild.dll /target vs2022 /targetframework net6_0 /excludedir = "obj | bin" /file prebuildCoreLib.xml echo "dotnet build -c Release OpenMetaverse.sln" > compile.sh chmod +x compile.sh diff --git a/runprebuildFull.bat b/runprebuildFull.bat new file mode 100755 index 00000000..58f6e4c7 --- /dev/null +++ b/runprebuildFull.bat @@ -0,0 +1,19 @@ +@echo OFF + +copy bin\System.Drawing.Common.dll.win bin\System.Drawing.Common.dll +dotnet bin\prebuild.dll /target vs2022 /targetframework net6_0 /excludedir = "obj | bin" /file prebuild.xml + + @echo Creating compile.bat +rem To compile in debug mode + @echo dotnet build --configuration Release OpenMetaverse.sln > compile.bat +rem To compile in release mode comment line (add rem to start) above and uncomment next (remove rem) +rem @echo %ValueValue% /p:Configuration=Release opensim.sln > compile.bat +:done +if exist "bin\addin-db-002" ( + del /F/Q/S bin\addin-db-002 > NUL + rmdir /Q/S bin\addin-db-002 + ) +if exist "bin\addin-db-004" ( + del /F/Q/S bin\addin-db-004 > NUL + rmdir /Q/S bin\addin-db-004 + ) \ No newline at end of file diff --git a/runprebuildFull.sh b/runprebuildFull.sh new file mode 100755 index 00000000..a1999427 --- /dev/null +++ b/runprebuildFull.sh @@ -0,0 +1,28 @@ +#!/bin/sh + +case "$1" in + + 'clean') + dotnet bin/prebuild.dll /file prebuild.xml /clean + + ;; + + + 'autoclean') + + echo y|dotnet bin/prebuild.dll /file prebuild.xml /clean + + ;; + + + + *) + + cp bin/System.Drawing.Common.dll.linux bin/System.Drawing.Common.dll + dotnet bin/prebuild.dll /target vs2022 /targetframework net6_0 /excludedir = "obj | bin" /file prebuild.xml + echo "dotnet build -c Release OpenMetaverse.sln" > compile.sh + chmod +x compile.sh + + ;; + +esac \ No newline at end of file From 7a2e574991ae2bb550f7fa3bbb7a22877b12930d Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Tue, 9 Apr 2024 00:57:12 +0100 Subject: [PATCH 115/149] update readme --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 1392e735..9f2ed272 100644 --- a/README.md +++ b/README.md @@ -70,3 +70,5 @@ Now just run `OpenSim.exe` from the `bin` folder, and set up the region. ### Current building problems several projects will only compile and run on windows many of those project also need fixes on their project files to set the framework to netxxx-windows and allow windows forms + +so, for now, runprebuild.(bat/sh) will only create projects for the dlls needed for OpenSimular. From 6f2d01a68c8fda9574d7ee58587ea7b673e0729d Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Tue, 9 Apr 2024 21:30:34 +0100 Subject: [PATCH 116/149] workflow should work again just for core dlls ie projects with no GUI --- .github/workflows/dotnet.yml | 54 ++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 .github/workflows/dotnet.yml diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml new file mode 100644 index 00000000..b1bc9015 --- /dev/null +++ b/.github/workflows/dotnet.yml @@ -0,0 +1,54 @@ +name: msbuild + +on: + push: + branches: [ "master" ] + paths: + - '**.cs' + workflow_dispatch: + +jobs: + build: + if: github.repository == 'UbitUmarov/libopenmetaverse' + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + - name: readshortsha + id: vars + run: echo "::set-output name=sha_short::$(git rev-parse --short HEAD)" + - name: preBuild + run: bash ${GITHUB_WORKSPACE}/runprebuild.sh + - name: Build + id: build + run: dotnet build --configuration Release OpenMetaverse.sln + - name: release + if: success() + run: zip -r LastBuild.zip bin LICENSE.txt + - uses: softprops/action-gh-release@v1 + if: success() + with: + tag_name: r${{ steps.vars.outputs.sha_short }} + name: LastAutoBuild + files: LastBuild.zip + - name: report push to irc + if: github.event_name == 'push' + uses: rectalogic/notify-irc@v1 + with: + channel: "#opensim-dev" + server: "irc.libera.chat" + nickname: osgithubomv + message: | + ${{ github.actor }} pushed to ${{ github.repository }} + ${{ join(github.event.commits.*.message, '\n') }} + mono compile: ${{ steps.build.conclusion }} + - name: report manual irc + if: github.event_name == 'workflow_dispatch' + uses: rectalogic/notify-irc@v1 + with: + channel: "#opensim-dev" + server: "irc.libera.chat" + nickname: osgithub + message: | + ${{ github.repository }} + dotnet compile: ${{ steps.build.conclusion }} From 5acbbb07b24d2069aea4024de97688970dbd534d Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Tue, 9 Apr 2024 21:34:15 +0100 Subject: [PATCH 117/149] update readme --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 9f2ed272..8258ed0c 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,10 @@ libOpenMetaverse Library Fork for OpenSimulator (version >= 0.9.3.0) -for older Opensimulator versions >= 0.9.1.0 use branch Mono-Net4x +For OpenSimulator versions older than 0.9.1.0 use original Library + + `https://github.com/openmetaversefoundation/libopenmetaverse` + +for versions 0.9.1.x and 0.9.2.x use branch Mono-Net4x # git clone From fd927e538177fb8b045daa1c2b90253f721f5476 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Tue, 9 Apr 2024 21:38:07 +0100 Subject: [PATCH 118/149] update readme --- README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 8258ed0c..193d1352 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,11 @@ -libOpenMetaverse Library Fork for OpenSimulator (version >= 0.9.3.0) +libOpenMetaverse Fork for OpenSimulator (versions >= 0.9.3.0) -For OpenSimulator versions older than 0.9.1.0 use original Library +For OpenSimulator versions 0.9.1.x and 0.9.2.x use branch Mono-Net4x + +For OpenSimulator older versions use the original Library `https://github.com/openmetaversefoundation/libopenmetaverse` -for versions 0.9.1.x and 0.9.2.x use branch Mono-Net4x # git clone From c954eddabf7fa136267e0b49bbf24c7ba7b594ea Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Wed, 10 Apr 2024 21:39:57 +0100 Subject: [PATCH 119/149] update readme again --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 193d1352..c3e1acd9 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -libOpenMetaverse Fork for OpenSimulator (versions >= 0.9.3.0) +A fork of libOpenMetaverse for OpenSimulator (versions >= 0.9.3.0) use For OpenSimulator versions 0.9.1.x and 0.9.2.x use branch Mono-Net4x From 43d9983987db6026bb5faa76c9d6149be681161c Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Wed, 10 Apr 2024 21:41:35 +0100 Subject: [PATCH 120/149] update readme again --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index c3e1acd9..6a83172f 100644 --- a/README.md +++ b/README.md @@ -69,11 +69,11 @@ Now just run `OpenSim.exe` from the `bin` folder, and set up the region. then run - `compile.bat`` + `compile.bat` ### Current building problems several projects will only compile and run on windows many of those project also need fixes on their project files to set the framework to netxxx-windows and allow windows forms -so, for now, runprebuild.(bat/sh) will only create projects for the dlls needed for OpenSimular. +For now, runprebuild.(bat/sh) will only create projects for the dlls needed for OpenSimular. From 1b7ad663cefd49779ca344cf566162b2e2d17837 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Sun, 21 Apr 2024 01:53:47 +0100 Subject: [PATCH 121/149] move to dotnet 8 --- .../LLSD/NotationLLSD.cs | 3 +- OpenMetaverse/ObjectPool.cs | 4 +- OpenMetaverseTypes/OSUTF8.cs | 42 ++++++------- OpenMetaverseTypes/UtilsConversions.cs | 41 +++++++++++-- Programs/WinGridProxy/FormWinGridProxy.cs | 14 ++--- Programs/mapgenerator/ProtocolManager.cs | 16 ++--- Programs/mapgenerator/mapgenerator.cs | 33 +++++----- Programs/mapgenerator/template.cs | 57 ++++++++++++++++++ README.md | 10 ++- bin/prebuild.dll | Bin 262144 -> 245760 bytes bin/prebuild.exe | Bin 148480 -> 0 bytes bin/prebuild.runtimeconfig.json | 6 +- prebuild.xml | 2 +- prebuildCoreLib.xml | 2 +- runprebuild.bat | 2 +- runprebuild.sh | 2 +- runprebuildFull.bat | 2 +- runprebuildFull.sh | 2 +- 18 files changed, 158 insertions(+), 80 deletions(-) delete mode 100644 bin/prebuild.exe diff --git a/OpenMetaverse.StructuredData/LLSD/NotationLLSD.cs b/OpenMetaverse.StructuredData/LLSD/NotationLLSD.cs index 14efc824..78ca3951 100644 --- a/OpenMetaverse.StructuredData/LLSD/NotationLLSD.cs +++ b/OpenMetaverse.StructuredData/LLSD/NotationLLSD.cs @@ -550,8 +550,7 @@ private static void SerializeLLSDNotationArray(TextWriter writer, OSDArray osdAr { writer.Write(arrayBeginNotationMarker); int lastIndex = osdArray.Count - 1; - - for (int idx = 0; idx <= lastIndex; idx++) + for (int idx = 0; idx < osdArray.Count; idx++) { SerializeLLSDNotationElement(writer, osdArray[idx]); if (idx < lastIndex) diff --git a/OpenMetaverse/ObjectPool.cs b/OpenMetaverse/ObjectPool.cs index fe8f4f2c..bc719a96 100644 --- a/OpenMetaverse/ObjectPool.cs +++ b/OpenMetaverse/ObjectPool.cs @@ -22,7 +22,7 @@ public class UDPPacketBuffer /// public UDPPacketBuffer() { - Data = new byte[UDPPacketBuffer.BUFFER_SIZE]; + Data = GC.AllocateUninitializedArray(BUFFER_SIZE); // Will be modified later by BeginReceiveFrom() RemoteEndPoint = new IPEndPoint(Settings.BIND_ADDR, 0); } @@ -33,7 +33,7 @@ public UDPPacketBuffer() /// EndPoint of the remote host public UDPPacketBuffer(IPEndPoint endPoint) { - Data = new byte[UDPPacketBuffer.BUFFER_SIZE]; + Data = GC.AllocateUninitializedArray(BUFFER_SIZE); RemoteEndPoint = endPoint; } diff --git a/OpenMetaverseTypes/OSUTF8.cs b/OpenMetaverseTypes/OSUTF8.cs index 967156e1..0cbbec22 100644 --- a/OpenMetaverseTypes/OSUTF8.cs +++ b/OpenMetaverseTypes/OSUTF8.cs @@ -50,7 +50,7 @@ public class osUTF8 internal byte[] m_data; internal int m_len; - public static readonly osUTF8 Empty = new osUTF8(); + public static readonly osUTF8 Empty = new(); [MethodImpl(MethodImplOptions.AggressiveInlining)] public osUTF8() @@ -187,8 +187,8 @@ public override bool Equals(object obj) if (obj is osUTF8Slice osUTF8Sliceobj) return Equals(osUTF8Sliceobj); - if (obj is string) - return Equals((string)obj); + if (obj is string v) + return Equals(v); if (obj is byte[] byteobj) return Equals(byteobj); @@ -279,7 +279,7 @@ public bool Equals(string s) { if (string.IsNullOrEmpty(s)) return m_len == 0; - osUTF8 o = new osUTF8(s); + osUTF8 o = new(s); return Equals(o); } @@ -656,7 +656,7 @@ public osUTF8Slice SubUTF8(int start) [MethodImpl(MethodImplOptions.AggressiveInlining)] public osUTF8Slice SubUTF8(int start, int len) { - osUTF8Slice oss = new osUTF8Slice(this); + osUTF8Slice oss = new(this); return oss.SubUTF8(start, len); } @@ -670,91 +670,91 @@ public string SubString(int start) [MethodImpl(MethodImplOptions.AggressiveInlining)] public string SubString(int start, int len) { - osUTF8Slice oss = new osUTF8Slice(this); + osUTF8Slice oss = new(this); return oss.SubString(start, len); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public osUTF8Slice TrimStart() { - osUTF8Slice ret = new osUTF8Slice(this); + osUTF8Slice ret = new(this); return ret.TrimStart(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public osUTF8Slice TrimEnd() { - osUTF8Slice ret = new osUTF8Slice(this); + osUTF8Slice ret = new(this); return ret.TrimEnd(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public osUTF8Slice Trim() { - osUTF8Slice ret = new osUTF8Slice(this); + osUTF8Slice ret = new(this); return ret.Trim(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public osUTF8Slice TrimStart(byte b) { - osUTF8Slice ret = new osUTF8Slice(this); + osUTF8Slice ret = new(this); return ret.TrimStart(b); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public osUTF8Slice TrimEnd(byte b) { - osUTF8Slice ret = new osUTF8Slice(this); + osUTF8Slice ret = new(this); return ret.TrimEnd(b); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public osUTF8Slice Trim(byte b) { - osUTF8Slice ret = new osUTF8Slice(this); + osUTF8Slice ret = new(this); return ret.Trim(b); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public osUTF8Slice TrimStart(byte[] v) { - osUTF8Slice ret = new osUTF8Slice(this); + osUTF8Slice ret = new(this); return ret.TrimStart(v); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public osUTF8Slice TrimEnd(byte[] v) { - osUTF8Slice ret = new osUTF8Slice(this); + osUTF8Slice ret = new(this); return ret.TrimEnd(v); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public osUTF8Slice Trim(byte[] v) { - osUTF8Slice ret = new osUTF8Slice(this); + osUTF8Slice ret = new(this); return ret.Trim(v); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public osUTF8Slice TrimStart(char[] v) { - osUTF8Slice ret = new osUTF8Slice(this); + osUTF8Slice ret = new(this); return ret.TrimStart(v); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public osUTF8Slice TrimEnd(char[] v) { - osUTF8Slice ret = new osUTF8Slice(this); + osUTF8Slice ret = new(this); return ret.TrimEnd(v); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public osUTF8Slice Trim(char[] v) { - osUTF8Slice ret = new osUTF8Slice(this); + osUTF8Slice ret = new(this); return ret.Trim(v); } @@ -777,7 +777,7 @@ public unsafe bool StartsWith(osUTF8 other) public bool StartsWith(string s) { - osUTF8 other = new osUTF8(s); // yeack + osUTF8 other = new(s); // yeack return StartsWith(other); } @@ -898,7 +898,7 @@ public int IndexOf(string s) { if (string.IsNullOrEmpty(s)) return -1; - osUTF8 o = new osUTF8(s); + osUTF8 o = new(s); return IndexOf(o); } @@ -1303,7 +1303,7 @@ public osUTF8 RemoveBytes(int start, int len) if (start >= m_len) return Clone(); - osUTF8 o = new osUTF8(m_len); + osUTF8 o = new(m_len); Array.Copy(m_data, 0, o.m_data, 0, start); o.m_len = start; diff --git a/OpenMetaverseTypes/UtilsConversions.cs b/OpenMetaverseTypes/UtilsConversions.cs index c220ae74..b990fd31 100644 --- a/OpenMetaverseTypes/UtilsConversions.cs +++ b/OpenMetaverseTypes/UtilsConversions.cs @@ -394,6 +394,18 @@ public static short BytesToInt16(ref byte bytes) return Unsafe.ReadUnaligned(ref bytes); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static byte BytesToByte(byte[] bytes, int pos) + { + return Unsafe.ReadUnaligned(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(bytes), pos)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static byte BytesToByte(byte[] bytes, ref int pos) + { + return Unsafe.ReadUnaligned(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(bytes), pos++)); + } + /// /// Convert the first two bytes starting at the given position in /// native endian ordering to a signed short integer @@ -1155,6 +1167,18 @@ public static double BytesToDoubleSafepos(ref byte bytes, int pos) #endregion BytesTo #region ToBytes + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void ByteToBytes(byte value, byte[] dest, int pos) + { + Unsafe.WriteUnaligned(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(dest), pos), value); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void ByteToBytes(byte value, byte[] dest, ref int pos) + { + Unsafe.WriteUnaligned(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(dest), pos++), value); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static byte[] Int16ToBytes(short value) { @@ -1238,8 +1262,16 @@ public static unsafe void UInt16ToBytes(ushort value, byte* dest) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void UInt16ToBytesBig(ushort value, byte[] dest, int pos) { - dest[pos] = (byte)(value >> 8); - dest[pos + 1] = (byte)value; + Unsafe.WriteUnaligned(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(dest), pos), (byte)(value >> 8)); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(dest), pos + 1), (byte)(value)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void UInt16ToBytesBig(ushort value, byte[] dest, ref int pos) + { + Unsafe.WriteUnaligned(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(dest), pos), (byte)(value >> 8)); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(dest), pos + 1), (byte)(value)); + pos += 2; } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -2365,7 +2397,6 @@ public static int osUTF8GetBytesCount(ReadOnlySpan str) public static int osUTF8GetBytesCount(ReadOnlySpan str, out int maxsource) { - maxsource = 0; char c; char lastc = (char)0; int nbytes = 0; @@ -2416,7 +2447,6 @@ public static int osUTF8GetBytesCount(ReadOnlySpan str, out int maxsource) public static int osUTF8GetBytesCount(ReadOnlySpan str, int maxnbytes, out int maxsourcelen) { - maxsourcelen = 0; int max2 = maxnbytes - 2; int max3 = maxnbytes - 3; int max4 = maxnbytes - 4; @@ -3210,8 +3240,7 @@ public static byte SwapNibbles(byte value) public static IPAddress HostnameToIPv4(string hostname) { // Is it already a valid IP? - IPAddress ip; - if (IPAddress.TryParse(hostname, out ip)) + if (IPAddress.TryParse(hostname, out IPAddress ip)) return ip; IPAddress[] hosts = Dns.GetHostEntry(hostname).AddressList; diff --git a/Programs/WinGridProxy/FormWinGridProxy.cs b/Programs/WinGridProxy/FormWinGridProxy.cs index 681daae9..9637babc 100644 --- a/Programs/WinGridProxy/FormWinGridProxy.cs +++ b/Programs/WinGridProxy/FormWinGridProxy.cs @@ -139,7 +139,7 @@ void ProxyManager_OnEventMessageLog(CapsRequest req, CapsStage stage) { if (this.InvokeRequired) { - this.BeginInvoke(new MethodInvoker(() => ProxyManager_OnEventMessageLog(req, stage))); + this.BeginInvoke(new System.Windows.Forms.MethodInvoker(() => ProxyManager_OnEventMessageLog(req, stage))); } else { @@ -170,7 +170,7 @@ private void ProxyManager_OnCapabilityAdded(CapInfo cap) { if (this.InvokeRequired) { - this.BeginInvoke(new MethodInvoker(() => ProxyManager_OnCapabilityAdded(cap))); + this.BeginInvoke(new System.Windows.Forms.MethodInvoker(() => ProxyManager_OnCapabilityAdded(cap))); } else { @@ -195,7 +195,7 @@ private void ProxyManager_OnLoginResponse(object request, int rsize, Dictionary< { if (this.InvokeRequired) { - this.BeginInvoke(new MethodInvoker(() => ProxyManager_OnLoginResponse(request, rsize, headers, host, direction))); + this.BeginInvoke(new System.Windows.Forms.MethodInvoker(() => ProxyManager_OnLoginResponse(request, rsize, headers, host, direction))); } else { @@ -263,7 +263,7 @@ private void ProxyManager_OnMessageLog(CapsRequest req, CapsStage stage) { if (this.InvokeRequired) { - this.BeginInvoke(new MethodInvoker(() => ProxyManager_OnMessageLog(req, stage))); + this.BeginInvoke(new System.Windows.Forms.MethodInvoker(() => ProxyManager_OnMessageLog(req, stage))); } else { @@ -1041,7 +1041,7 @@ private void SearchSessions(FilterOptions opts) { if (this.InvokeRequired) { - this.BeginInvoke(new MethodInvoker(() => SearchSessions(opts))); + this.BeginInvoke(new System.Windows.Forms.MethodInvoker(() => SearchSessions(opts))); } else { @@ -1158,7 +1158,7 @@ private void timer1_Tick(object sender, EventArgs e) { if (this.InvokeRequired) { - this.BeginInvoke(new MethodInvoker(() => timer1_Tick(sender, e))); + this.BeginInvoke(new System.Windows.Forms.MethodInvoker(() => timer1_Tick(sender, e))); } else { @@ -1296,7 +1296,7 @@ void Instance_MessageLoggedEvent(object sender, MessageLoggedEventArgs e) if (InvokeRequired) { - BeginInvoke(new MethodInvoker(() => Instance_MessageLoggedEvent(sender, e))); + BeginInvoke(new System.Windows.Forms.MethodInvoker(() => Instance_MessageLoggedEvent(sender, e))); } else { diff --git a/Programs/mapgenerator/ProtocolManager.cs b/Programs/mapgenerator/ProtocolManager.cs index 9c4b519e..5a731e0f 100644 --- a/Programs/mapgenerator/ProtocolManager.cs +++ b/Programs/mapgenerator/ProtocolManager.cs @@ -310,17 +310,13 @@ public MapPacket Command(byte[] data) /// public MapPacket Command(ushort command, PacketFrequency frequency) { - switch (frequency) + return frequency switch { - case PacketFrequency.High: - return HighMaps[command]; - case PacketFrequency.Medium: - return MediumMaps[command]; - case PacketFrequency.Low: - return LowMaps[command]; - } - - throw new Exception("Cannot find map for command \"" + command + "\" with frequency \"" + frequency + "\""); + PacketFrequency.High => HighMaps[command], + PacketFrequency.Medium => MediumMaps[command], + PacketFrequency.Low => LowMaps[command], + _ => throw new Exception("Cannot find map for command \"" + command + "\" with frequency \"" + frequency + "\""), + }; } /// diff --git a/Programs/mapgenerator/mapgenerator.cs b/Programs/mapgenerator/mapgenerator.cs index caf2eaf3..50408329 100644 --- a/Programs/mapgenerator/mapgenerator.cs +++ b/Programs/mapgenerator/mapgenerator.cs @@ -95,7 +95,7 @@ static void WriteFieldFromBytes(TextWriter writer, MapField field) switch (field.Type) { case FieldType.BOOL: - writer.WriteLine(" " + field.Name + " = (bytes[i++] != 0) ? (bool)true : (bool)false;"); + writer.WriteLine(" " + field.Name + " = (Utils.BytesToByte(bytes, ref i) != 0);"); break; case FieldType.F32: writer.WriteLine(" " + field.Name + " = Utils.BytesToFloatSafepos(bytes, i); i += 4;"); @@ -142,22 +142,22 @@ static void WriteFieldFromBytes(TextWriter writer, MapField field) writer.WriteLine(" " + field.Name + " = Utils.BytesToIntSafepos(bytes, i); i +=4;"); break; case FieldType.S8: - writer.WriteLine(" " + field.Name + " = (sbyte)bytes[i++];"); + writer.WriteLine(" " + field.Name + " = (sbyte)Utils.BytesToByte(bytes, ref i);"); break; case FieldType.U64: writer.WriteLine(" " + field.Name + " = Utils.BytesToUInt64Safepos(bytes, i); i += 8;"); break; case FieldType.U8: - writer.WriteLine(" " + field.Name + " = (byte)bytes[i++];"); + writer.WriteLine(" " + field.Name + " = Utils.BytesToByte(bytes, ref i);"); break; case FieldType.Variable: if (field.Count == 1) { - writer.WriteLine(" length = bytes[i++];"); + writer.WriteLine(" length = Utils.BytesToByte(bytes, ref i);"); } else { - writer.WriteLine(" length = (bytes[i++] + (bytes[i++] << 8));"); + writer.WriteLine(" length = Utils.BytesToUInt16(bytes, i); i+=2;"); } writer.WriteLine(" " + field.Name + " = new byte[length];"); writer.WriteLine(" Buffer.BlockCopy(bytes, i, " + field.Name + ", 0, length); i += length;"); @@ -175,7 +175,7 @@ static void WriteFieldToBytes(TextWriter writer, MapField field) switch (field.Type) { case FieldType.BOOL: - writer.WriteLine("bytes[i++] = (byte)((" + field.Name + ") ? 1 : 0);"); + writer.WriteLine("Utils.ByteToBytes((byte)((" + field.Name + ") ? 1 : 0), bytes, i);"); break; case FieldType.F32: writer.WriteLine("Utils.FloatToBytesSafepos(" + field.Name + ", bytes, i); i += 4;"); @@ -189,8 +189,7 @@ static void WriteFieldToBytes(TextWriter writer, MapField field) break; case FieldType.IPPORT: // IPPORT is big endian while U16/S16 is little endian. Go figure - writer.WriteLine("bytes[i++] = (byte)((" + field.Name + " >> 8) % 256);"); - writer.WriteLine(" bytes[i++] = (byte)(" + field.Name + " % 256);"); + writer.WriteLine("Utils.UInt16ToBytesBig(" + field.Name + ", bytes, i); i += 2;"); break; case FieldType.U16: writer.WriteLine("Utils.UInt16ToBytes(" + field.Name + ", bytes, i); i += 2;"); @@ -210,10 +209,10 @@ static void WriteFieldToBytes(TextWriter writer, MapField field) writer.WriteLine(field.Name + ".ToBytes(bytes, i); i += 24;"); break; case FieldType.U8: - writer.WriteLine("bytes[i++] = " + field.Name + ";"); + writer.WriteLine("Utils.ByteToBytes( " + field.Name + ", bytes, ref i);"); break; case FieldType.S8: - writer.WriteLine("bytes[i++] = (byte)" + field.Name + ";"); + writer.WriteLine("Utils.ByteToBytes( (byte)" + field.Name + ", bytes, ref i);"); break; case FieldType.IPADDR: case FieldType.U32: @@ -230,13 +229,11 @@ static void WriteFieldToBytes(TextWriter writer, MapField field) //writer.Write(" "); if (field.Count == 1) { - writer.WriteLine("bytes[i++] = (byte)" + field.Name + ".Length;"); + writer.WriteLine("Utils.ByteToBytes((byte)" + field.Name + ".Length, bytes, ref i);"); } else { - writer.WriteLine("bytes[i++] = (byte)(" + field.Name + ".Length % 256);"); - writer.WriteLine(" bytes[i++] = (byte)((" + - field.Name + ".Length >> 8) % 256);"); + writer.WriteLine("Utils.UInt16ToBytes((ushort)" + field.Name + ".Length, bytes, i); i += 2;"); } writer.WriteLine(" Buffer.BlockCopy(" + field.Name + ", 0, bytes, i, " + field.Name + ".Length); " + "i += " + field.Name + ".Length;"); @@ -402,7 +399,7 @@ static void WritePacketClass(TextWriter writer, MapPacket packet) " {" + Environment.NewLine + " get" + Environment.NewLine + " {"); - int length = 0; + int length; if (packet.Frequency == PacketFrequency.Low) { length = 10; } else if (packet.Frequency == PacketFrequency.Medium) { length = 8; } else { length = 7; } @@ -659,7 +656,7 @@ static void WritePacketClass(TextWriter writer, MapPacket packet) if (block.Count == -1) { // Variable count block - writer.WriteLine(" bytes[i++] = (byte)" + sanitizedName + ".Length;"); + writer.WriteLine(" Utils.ByteToBytes((byte)" + sanitizedName + ".Length, bytes, ref i);"); writer.WriteLine(" for (int j = 0; j < " + sanitizedName + ".Length; j++) { " + sanitizedName + "[j].ToBytes(bytes, ref i); }"); } @@ -911,7 +908,7 @@ static void WriteToBytesMultiple(TextWriter writer, MapPacket packet) static int Main(string[] args) { ProtocolManager protocol; - List unused = new List(); + List unused = new(); TextWriter writer; try @@ -926,7 +923,7 @@ static int Main(string[] args) protocol = new ProtocolManager(args[0]); // Build a list of unused packets - using (StreamReader unusedReader = new StreamReader(args[2])) + using (StreamReader unusedReader = new(args[2])) { while (unusedReader.Peek() >= 0) { diff --git a/Programs/mapgenerator/template.cs b/Programs/mapgenerator/template.cs index 71313de7..0445510f 100644 --- a/Programs/mapgenerator/template.cs +++ b/Programs/mapgenerator/template.cs @@ -208,6 +208,63 @@ public static Header BuildHeader(byte[] bytes, ref int pos, ref int packetLength return header; } + + public static bool TryParseHeader(byte[] bytes, int packetLen, out Header header, out int messageBody, out int messageEnd) + { + messageBody = 0; + messageEnd = packetLen; + header = new Header(); + + try + { + byte flags = bytes[0]; + + header.AppendedAcks = (flags & Helpers.MSG_APPENDED_ACKS) != 0; + header.Reliable = (flags & Helpers.MSG_RELIABLE) != 0; + header.Resent = (flags & Helpers.MSG_RESENT) != 0; + header.Zerocoded = (flags & Helpers.MSG_ZEROCODED) != 0; + + header.Sequence = (uint)Utils.BytesToIntBig(bytes, 1); + + messageBody += bytes[5]; + + header.ID = bytes[messageBody + 6]; + // Set the frequency and packet ID number + if (header.ID == 0xFF) + { + header.ID = bytes[messageBody + 7]; + if (header.ID == 0xFF) + { + header.Frequency = PacketFrequency.Low; + if (header.Zerocoded && bytes[messageBody + 8] == 0) + header.ID = bytes[messageBody + 10]; + else + header.ID = (ushort)((bytes[messageBody + 8] << 8) + bytes[messageBody + 9]); + + messageBody += 10; + } + else + { + header.Frequency = PacketFrequency.Medium; + messageBody += 8; + } + } + else + { + header.Frequency = PacketFrequency.High; + messageBody += 7; + } + if (header.AppendedAcks) + { + --messageEnd; + int count = bytes[messageEnd]; + messageEnd -= 4 * count; + } + return messageEnd >= messageBody; + } + catch { } + return false; + } } /// diff --git a/README.md b/README.md index 6a83172f..071d4027 100644 --- a/README.md +++ b/README.md @@ -27,11 +27,11 @@ or ## Requirements To building under Windows, the following is required: - * [dotnet 6.0 SDK, Runtime and Desktop Runtime](https://dotnet.microsoft.com/en-us/download/dotnet/6.0) + * [dotnet 8.0 SDK](https://dotnet.microsoft.com/en-us/download/dotnet/8.0) optionally also - * [Visual Studio .NET](https://visualstudio.microsoft.com/vs/features/net-development/), version 2022 or later + * [Visual Studio](https://visualstudio.microsoft.com/vs/features/net-development/), version 2022 or later ### Building @@ -43,17 +43,15 @@ run `compile.bat` -Or load the generated OpenSim.sln into Visual Studio and build the solution. +Or load the generated OpenMetaverse.sln into Visual Studio and build the solution. -Configure, see below -Now just run `OpenSim.exe` from the `bin` folder, and set up the region. # Building on Linux / Mac ## Requirements - * [dotnet 6.0 SDK and Runtime](https://dotnet.microsoft.com/en-us/download/dotnet/6.0) + * [dotnet 8.0 SDK](https://dotnet.microsoft.com/en-us/download/dotnet/8.0) * libgdiplus if you have mono 6.x complete, you already have libgdiplus, otherwise you need to install it diff --git a/bin/prebuild.dll b/bin/prebuild.dll index 1769bfbe44b8cd4602b992fb111751dda041a2f4..235b9686918a3ab498d3cbc4431cfb1959dff5b8 100644 GIT binary patch literal 245760 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�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 diff --git a/bin/prebuild.exe b/bin/prebuild.exe deleted file mode 100644 index aada172a4f85022fcfcf5064eed16c4a4a345124..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 148480 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 diff --git a/bin/prebuild.runtimeconfig.json b/bin/prebuild.runtimeconfig.json index 418df653..b0a83d62 100644 --- a/bin/prebuild.runtimeconfig.json +++ b/bin/prebuild.runtimeconfig.json @@ -1,11 +1,13 @@ { "runtimeOptions": { - "tfm": "net6.0", + "tfm": "net8.0", "framework": { "name": "Microsoft.NETCore.App", - "version": "6.0.0" + "version": "8.0.0" }, "configProperties": { + "System.Reflection.Metadata.MetadataUpdater.IsSupported": false, + "System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization": false, "System.Runtime.TieredCompilation": false } } diff --git a/prebuild.xml b/prebuild.xml index 5e50a86b..be8d6f0f 100644 --- a/prebuild.xml +++ b/prebuild.xml @@ -1,6 +1,6 @@ - + TRACE;DEBUG diff --git a/prebuildCoreLib.xml b/prebuildCoreLib.xml index b5ce209b..b35a8d40 100755 --- a/prebuildCoreLib.xml +++ b/prebuildCoreLib.xml @@ -1,6 +1,6 @@ - + TRACE;DEBUG diff --git a/runprebuild.bat b/runprebuild.bat index d671c577..06c1501a 100644 --- a/runprebuild.bat +++ b/runprebuild.bat @@ -1,7 +1,7 @@ @echo OFF copy bin\System.Drawing.Common.dll.win bin\System.Drawing.Common.dll -dotnet bin\prebuild.dll /target vs2022 /targetframework net6_0 /excludedir = "obj | bin" /file prebuildCoreLib.xml +dotnet bin\prebuild.dll /target vs2022 /targetframework net8_0 /excludedir = "obj | bin" /file prebuildCoreLib.xml @echo Creating compile.bat rem To compile in debug mode diff --git a/runprebuild.sh b/runprebuild.sh index 71ba485a..bfd172e5 100755 --- a/runprebuild.sh +++ b/runprebuild.sh @@ -19,7 +19,7 @@ case "$1" in *) cp bin/System.Drawing.Common.dll.linux bin/System.Drawing.Common.dll - dotnet bin/prebuild.dll /target vs2022 /targetframework net6_0 /excludedir = "obj | bin" /file prebuildCoreLib.xml + dotnet bin/prebuild.dll /target vs2022 /targetframework net8_0 /excludedir = "obj | bin" /file prebuildCoreLib.xml echo "dotnet build -c Release OpenMetaverse.sln" > compile.sh chmod +x compile.sh diff --git a/runprebuildFull.bat b/runprebuildFull.bat index 58f6e4c7..46ac9289 100755 --- a/runprebuildFull.bat +++ b/runprebuildFull.bat @@ -1,7 +1,7 @@ @echo OFF copy bin\System.Drawing.Common.dll.win bin\System.Drawing.Common.dll -dotnet bin\prebuild.dll /target vs2022 /targetframework net6_0 /excludedir = "obj | bin" /file prebuild.xml +dotnet bin\prebuild.dll /target vs2022 /targetframework net8_0 /excludedir = "obj | bin" /file prebuild.xml @echo Creating compile.bat rem To compile in debug mode diff --git a/runprebuildFull.sh b/runprebuildFull.sh index a1999427..3ccfbc3f 100755 --- a/runprebuildFull.sh +++ b/runprebuildFull.sh @@ -19,7 +19,7 @@ case "$1" in *) cp bin/System.Drawing.Common.dll.linux bin/System.Drawing.Common.dll - dotnet bin/prebuild.dll /target vs2022 /targetframework net6_0 /excludedir = "obj | bin" /file prebuild.xml + dotnet bin/prebuild.dll /target vs2022 /targetframework net8_0 /excludedir = "obj | bin" /file prebuild.xml echo "dotnet build -c Release OpenMetaverse.sln" > compile.sh chmod +x compile.sh From 9408d4d7896bccac90070c7f9e00f3befbbd935d Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Sun, 21 Apr 2024 02:02:08 +0100 Subject: [PATCH 122/149] remove some files not part of source --- bin/GridProxyApp.runtimeconfig.json | 13 ------------- bin/IRCGateway.runtimeconfig.json | 13 ------------- bin/PacketDump.runtimeconfig.json | 13 ------------- bin/PrimWorkshop.runtimeconfig.json | 19 ------------------- bin/TestClient.runtimeconfig.json | 13 ------------- bin/VisualParamGenerator.runtimeconfig.json | 13 ------------- bin/VoiceTest.runtimeconfig.json | 13 ------------- bin/WinGridProxy.runtimeconfig.json | 19 ------------------- bin/importprimscript.runtimeconfig.json | 13 ------------- bin/mapgenerator.runtimeconfig.json | 13 ------------- 10 files changed, 142 deletions(-) delete mode 100644 bin/GridProxyApp.runtimeconfig.json delete mode 100644 bin/IRCGateway.runtimeconfig.json delete mode 100644 bin/PacketDump.runtimeconfig.json delete mode 100644 bin/PrimWorkshop.runtimeconfig.json delete mode 100644 bin/TestClient.runtimeconfig.json delete mode 100644 bin/VisualParamGenerator.runtimeconfig.json delete mode 100644 bin/VoiceTest.runtimeconfig.json delete mode 100644 bin/WinGridProxy.runtimeconfig.json delete mode 100644 bin/importprimscript.runtimeconfig.json delete mode 100644 bin/mapgenerator.runtimeconfig.json diff --git a/bin/GridProxyApp.runtimeconfig.json b/bin/GridProxyApp.runtimeconfig.json deleted file mode 100644 index e355688b..00000000 --- a/bin/GridProxyApp.runtimeconfig.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "runtimeOptions": { - "tfm": "net6.0", - "framework": { - "name": "Microsoft.NETCore.App", - "version": "6.0.0" - }, - "configProperties": { - "System.Reflection.Metadata.MetadataUpdater.IsSupported": false, - "System.Runtime.TieredCompilation": false - } - } -} \ No newline at end of file diff --git a/bin/IRCGateway.runtimeconfig.json b/bin/IRCGateway.runtimeconfig.json deleted file mode 100644 index e355688b..00000000 --- a/bin/IRCGateway.runtimeconfig.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "runtimeOptions": { - "tfm": "net6.0", - "framework": { - "name": "Microsoft.NETCore.App", - "version": "6.0.0" - }, - "configProperties": { - "System.Reflection.Metadata.MetadataUpdater.IsSupported": false, - "System.Runtime.TieredCompilation": false - } - } -} \ No newline at end of file diff --git a/bin/PacketDump.runtimeconfig.json b/bin/PacketDump.runtimeconfig.json deleted file mode 100644 index e355688b..00000000 --- a/bin/PacketDump.runtimeconfig.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "runtimeOptions": { - "tfm": "net6.0", - "framework": { - "name": "Microsoft.NETCore.App", - "version": "6.0.0" - }, - "configProperties": { - "System.Reflection.Metadata.MetadataUpdater.IsSupported": false, - "System.Runtime.TieredCompilation": false - } - } -} \ No newline at end of file diff --git a/bin/PrimWorkshop.runtimeconfig.json b/bin/PrimWorkshop.runtimeconfig.json deleted file mode 100644 index 1b351ac9..00000000 --- a/bin/PrimWorkshop.runtimeconfig.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "runtimeOptions": { - "tfm": "net6.0", - "frameworks": [ - { - "name": "Microsoft.NETCore.App", - "version": "6.0.0" - }, - { - "name": "Microsoft.WindowsDesktop.App", - "version": "6.0.0" - } - ], - "configProperties": { - "System.Reflection.Metadata.MetadataUpdater.IsSupported": false, - "System.Runtime.TieredCompilation": false - } - } -} \ No newline at end of file diff --git a/bin/TestClient.runtimeconfig.json b/bin/TestClient.runtimeconfig.json deleted file mode 100644 index e355688b..00000000 --- a/bin/TestClient.runtimeconfig.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "runtimeOptions": { - "tfm": "net6.0", - "framework": { - "name": "Microsoft.NETCore.App", - "version": "6.0.0" - }, - "configProperties": { - "System.Reflection.Metadata.MetadataUpdater.IsSupported": false, - "System.Runtime.TieredCompilation": false - } - } -} \ No newline at end of file diff --git a/bin/VisualParamGenerator.runtimeconfig.json b/bin/VisualParamGenerator.runtimeconfig.json deleted file mode 100644 index e355688b..00000000 --- a/bin/VisualParamGenerator.runtimeconfig.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "runtimeOptions": { - "tfm": "net6.0", - "framework": { - "name": "Microsoft.NETCore.App", - "version": "6.0.0" - }, - "configProperties": { - "System.Reflection.Metadata.MetadataUpdater.IsSupported": false, - "System.Runtime.TieredCompilation": false - } - } -} \ No newline at end of file diff --git a/bin/VoiceTest.runtimeconfig.json b/bin/VoiceTest.runtimeconfig.json deleted file mode 100644 index e355688b..00000000 --- a/bin/VoiceTest.runtimeconfig.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "runtimeOptions": { - "tfm": "net6.0", - "framework": { - "name": "Microsoft.NETCore.App", - "version": "6.0.0" - }, - "configProperties": { - "System.Reflection.Metadata.MetadataUpdater.IsSupported": false, - "System.Runtime.TieredCompilation": false - } - } -} \ No newline at end of file diff --git a/bin/WinGridProxy.runtimeconfig.json b/bin/WinGridProxy.runtimeconfig.json deleted file mode 100644 index 1b351ac9..00000000 --- a/bin/WinGridProxy.runtimeconfig.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "runtimeOptions": { - "tfm": "net6.0", - "frameworks": [ - { - "name": "Microsoft.NETCore.App", - "version": "6.0.0" - }, - { - "name": "Microsoft.WindowsDesktop.App", - "version": "6.0.0" - } - ], - "configProperties": { - "System.Reflection.Metadata.MetadataUpdater.IsSupported": false, - "System.Runtime.TieredCompilation": false - } - } -} \ No newline at end of file diff --git a/bin/importprimscript.runtimeconfig.json b/bin/importprimscript.runtimeconfig.json deleted file mode 100644 index e355688b..00000000 --- a/bin/importprimscript.runtimeconfig.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "runtimeOptions": { - "tfm": "net6.0", - "framework": { - "name": "Microsoft.NETCore.App", - "version": "6.0.0" - }, - "configProperties": { - "System.Reflection.Metadata.MetadataUpdater.IsSupported": false, - "System.Runtime.TieredCompilation": false - } - } -} \ No newline at end of file diff --git a/bin/mapgenerator.runtimeconfig.json b/bin/mapgenerator.runtimeconfig.json deleted file mode 100644 index e355688b..00000000 --- a/bin/mapgenerator.runtimeconfig.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "runtimeOptions": { - "tfm": "net6.0", - "framework": { - "name": "Microsoft.NETCore.App", - "version": "6.0.0" - }, - "configProperties": { - "System.Reflection.Metadata.MetadataUpdater.IsSupported": false, - "System.Runtime.TieredCompilation": false - } - } -} \ No newline at end of file From 96a3fefb883e68e53a5038f0296213a8fd43032e Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Sun, 21 Apr 2024 02:04:33 +0100 Subject: [PATCH 123/149] remove some files not part of source --- bin/AvatarPreview.runtimeconfig.json | 19 ------------------- bin/Baker.runtimeconfig.json | 19 ------------------- bin/Dashboard.runtimeconfig.json | 19 ------------------- bin/GridAccountant.runtimeconfig.json | 19 ------------------- bin/GridImageUpload.runtimeconfig.json | 19 ------------------- bin/Heightmap.runtimeconfig.json | 19 ------------------- bin/groupmanager.runtimeconfig.json | 19 ------------------- 7 files changed, 133 deletions(-) delete mode 100644 bin/AvatarPreview.runtimeconfig.json delete mode 100644 bin/Baker.runtimeconfig.json delete mode 100644 bin/Dashboard.runtimeconfig.json delete mode 100644 bin/GridAccountant.runtimeconfig.json delete mode 100644 bin/GridImageUpload.runtimeconfig.json delete mode 100644 bin/Heightmap.runtimeconfig.json delete mode 100644 bin/groupmanager.runtimeconfig.json diff --git a/bin/AvatarPreview.runtimeconfig.json b/bin/AvatarPreview.runtimeconfig.json deleted file mode 100644 index 1b351ac9..00000000 --- a/bin/AvatarPreview.runtimeconfig.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "runtimeOptions": { - "tfm": "net6.0", - "frameworks": [ - { - "name": "Microsoft.NETCore.App", - "version": "6.0.0" - }, - { - "name": "Microsoft.WindowsDesktop.App", - "version": "6.0.0" - } - ], - "configProperties": { - "System.Reflection.Metadata.MetadataUpdater.IsSupported": false, - "System.Runtime.TieredCompilation": false - } - } -} \ No newline at end of file diff --git a/bin/Baker.runtimeconfig.json b/bin/Baker.runtimeconfig.json deleted file mode 100644 index 1b351ac9..00000000 --- a/bin/Baker.runtimeconfig.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "runtimeOptions": { - "tfm": "net6.0", - "frameworks": [ - { - "name": "Microsoft.NETCore.App", - "version": "6.0.0" - }, - { - "name": "Microsoft.WindowsDesktop.App", - "version": "6.0.0" - } - ], - "configProperties": { - "System.Reflection.Metadata.MetadataUpdater.IsSupported": false, - "System.Runtime.TieredCompilation": false - } - } -} \ No newline at end of file diff --git a/bin/Dashboard.runtimeconfig.json b/bin/Dashboard.runtimeconfig.json deleted file mode 100644 index 1b351ac9..00000000 --- a/bin/Dashboard.runtimeconfig.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "runtimeOptions": { - "tfm": "net6.0", - "frameworks": [ - { - "name": "Microsoft.NETCore.App", - "version": "6.0.0" - }, - { - "name": "Microsoft.WindowsDesktop.App", - "version": "6.0.0" - } - ], - "configProperties": { - "System.Reflection.Metadata.MetadataUpdater.IsSupported": false, - "System.Runtime.TieredCompilation": false - } - } -} \ No newline at end of file diff --git a/bin/GridAccountant.runtimeconfig.json b/bin/GridAccountant.runtimeconfig.json deleted file mode 100644 index 1b351ac9..00000000 --- a/bin/GridAccountant.runtimeconfig.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "runtimeOptions": { - "tfm": "net6.0", - "frameworks": [ - { - "name": "Microsoft.NETCore.App", - "version": "6.0.0" - }, - { - "name": "Microsoft.WindowsDesktop.App", - "version": "6.0.0" - } - ], - "configProperties": { - "System.Reflection.Metadata.MetadataUpdater.IsSupported": false, - "System.Runtime.TieredCompilation": false - } - } -} \ No newline at end of file diff --git a/bin/GridImageUpload.runtimeconfig.json b/bin/GridImageUpload.runtimeconfig.json deleted file mode 100644 index 1b351ac9..00000000 --- a/bin/GridImageUpload.runtimeconfig.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "runtimeOptions": { - "tfm": "net6.0", - "frameworks": [ - { - "name": "Microsoft.NETCore.App", - "version": "6.0.0" - }, - { - "name": "Microsoft.WindowsDesktop.App", - "version": "6.0.0" - } - ], - "configProperties": { - "System.Reflection.Metadata.MetadataUpdater.IsSupported": false, - "System.Runtime.TieredCompilation": false - } - } -} \ No newline at end of file diff --git a/bin/Heightmap.runtimeconfig.json b/bin/Heightmap.runtimeconfig.json deleted file mode 100644 index 1b351ac9..00000000 --- a/bin/Heightmap.runtimeconfig.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "runtimeOptions": { - "tfm": "net6.0", - "frameworks": [ - { - "name": "Microsoft.NETCore.App", - "version": "6.0.0" - }, - { - "name": "Microsoft.WindowsDesktop.App", - "version": "6.0.0" - } - ], - "configProperties": { - "System.Reflection.Metadata.MetadataUpdater.IsSupported": false, - "System.Runtime.TieredCompilation": false - } - } -} \ No newline at end of file diff --git a/bin/groupmanager.runtimeconfig.json b/bin/groupmanager.runtimeconfig.json deleted file mode 100644 index 1b351ac9..00000000 --- a/bin/groupmanager.runtimeconfig.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "runtimeOptions": { - "tfm": "net6.0", - "frameworks": [ - { - "name": "Microsoft.NETCore.App", - "version": "6.0.0" - }, - { - "name": "Microsoft.WindowsDesktop.App", - "version": "6.0.0" - } - ], - "configProperties": { - "System.Reflection.Metadata.MetadataUpdater.IsSupported": false, - "System.Runtime.TieredCompilation": false - } - } -} \ No newline at end of file From f51f809ba6e897c8c14ac1b852affbc0ddcb1c35 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Sun, 21 Apr 2024 02:11:31 +0100 Subject: [PATCH 124/149] a few changes to mapgenerator and packets.cs --- OpenMetaverse/_Packets_.cs | 2921 ++++++++++++------------- Programs/mapgenerator/mapgenerator.cs | 2 +- 2 files changed, 1461 insertions(+), 1462 deletions(-) diff --git a/OpenMetaverse/_Packets_.cs b/OpenMetaverse/_Packets_.cs index eeac1cdd..11218f32 100644 --- a/OpenMetaverse/_Packets_.cs +++ b/OpenMetaverse/_Packets_.cs @@ -208,6 +208,63 @@ public static Header BuildHeader(byte[] bytes, ref int pos, ref int packetLength return header; } + + public static bool TryParseHeader(byte[] bytes, int packetLen, out Header header, out int messageBody, out int messageEnd) + { + messageBody = 0; + messageEnd = packetLen; + header = new Header(); + + try + { + byte flags = bytes[0]; + + header.AppendedAcks = (flags & Helpers.MSG_APPENDED_ACKS) != 0; + header.Reliable = (flags & Helpers.MSG_RELIABLE) != 0; + header.Resent = (flags & Helpers.MSG_RESENT) != 0; + header.Zerocoded = (flags & Helpers.MSG_ZEROCODED) != 0; + + header.Sequence = (uint)Utils.BytesToIntBig(bytes, 1); + + messageBody += bytes[5]; + + header.ID = bytes[messageBody + 6]; + // Set the frequency and packet ID number + if (header.ID == 0xFF) + { + header.ID = bytes[messageBody + 7]; + if (header.ID == 0xFF) + { + header.Frequency = PacketFrequency.Low; + if (header.Zerocoded && bytes[messageBody + 8] == 0) + header.ID = bytes[messageBody + 10]; + else + header.ID = (ushort)((bytes[messageBody + 8] << 8) + bytes[messageBody + 9]); + + messageBody += 10; + } + else + { + header.Frequency = PacketFrequency.Medium; + messageBody += 8; + } + } + else + { + header.Frequency = PacketFrequency.High; + messageBody += 7; + } + if (header.AppendedAcks) + { + --messageEnd; + int count = bytes[messageEnd]; + messageEnd -= 4 * count; + } + return messageEnd >= messageBody; + } + catch { } + return false; + } } ///

@@ -2202,7 +2259,7 @@ public override void FromBytes(byte[] bytes, ref int i) try { ObjectID.FromBytes(bytes, i); i += 16; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); ObjectName = new byte[length]; Buffer.BlockCopy(bytes, i, ObjectName, 0, length); i += length; TelehubPos.FromBytes(bytes, i); i += 12; @@ -2217,7 +2274,7 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { ObjectID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)ObjectName.Length; + Utils.ByteToBytes((byte)ObjectName.Length, bytes, ref i); Buffer.BlockCopy(ObjectName, 0, bytes, i, ObjectName.Length); i += ObjectName.Length; TelehubPos.ToBytes(bytes, i); i += 12; TelehubRot.ToBytes(bytes, i); i += 12; @@ -2344,7 +2401,7 @@ public override byte[] ToBytes() int i = 0; Header.ToBytes(bytes, ref i); TelehubBlock.ToBytes(bytes, ref i); - bytes[i++] = (byte)SpawnPointBlock.Length; + Utils.ByteToBytes((byte)SpawnPointBlock.Length, bytes, ref i); for (int j = 0; j < SpawnPointBlock.Length; j++) { SpawnPointBlock[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -2706,7 +2763,7 @@ public override void FromBytes(byte[] bytes, ref int i) int length; try { - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Name = new byte[length]; Buffer.BlockCopy(bytes, i, Name, 0, length); i += length; } @@ -2718,7 +2775,7 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { - bytes[i++] = (byte)Name.Length; + Utils.ByteToBytes((byte)Name.Length, bytes, ref i); Buffer.BlockCopy(Name, 0, bytes, i, Name.Length); i += Name.Length; } @@ -2874,10 +2931,10 @@ public override void FromBytes(byte[] bytes, ref int i) try { AvatarID.FromBytes(bytes, i); i += 16; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); FirstName = new byte[length]; Buffer.BlockCopy(bytes, i, FirstName, 0, length); i += length; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); LastName = new byte[length]; Buffer.BlockCopy(bytes, i, LastName, 0, length); i += length; } @@ -2890,9 +2947,9 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { AvatarID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)FirstName.Length; + Utils.ByteToBytes((byte)FirstName.Length, bytes, ref i); Buffer.BlockCopy(FirstName, 0, bytes, i, FirstName.Length); i += FirstName.Length; - bytes[i++] = (byte)LastName.Length; + Utils.ByteToBytes((byte)LastName.Length, bytes, ref i); Buffer.BlockCopy(LastName, 0, bytes, i, LastName.Length); i += LastName.Length; } @@ -2979,7 +3036,7 @@ public override byte[] ToBytes() int i = 0; Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); - bytes[i++] = (byte)Data.Length; + Utils.ByteToBytes((byte)Data.Length, bytes, ref i); for (int j = 0; j < Data.Length; j++) { Data[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -3159,12 +3216,12 @@ public override void FromBytes(byte[] bytes, ref int i) int length; try { - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); QueryText = new byte[length]; Buffer.BlockCopy(bytes, i, QueryText, 0, length); i += length; QueryFlags = Utils.BytesToUIntSafepos(bytes, i); i += 4; - Category = (sbyte)bytes[i++]; - length = bytes[i++]; + Category = (sbyte)Utils.BytesToByte(bytes, ref i); + length = Utils.BytesToByte(bytes, ref i); SimName = new byte[length]; Buffer.BlockCopy(bytes, i, SimName, 0, length); i += length; } @@ -3176,11 +3233,11 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { - bytes[i++] = (byte)QueryText.Length; + Utils.ByteToBytes((byte)QueryText.Length, bytes, ref i); Buffer.BlockCopy(QueryText, 0, bytes, i, QueryText.Length); i += QueryText.Length; Utils.UIntToBytesSafepos(QueryFlags, bytes, i); i += 4; - bytes[i++] = (byte)Category; - bytes[i++] = (byte)SimName.Length; + Utils.ByteToBytes( (byte)Category, bytes, ref i); + Utils.ByteToBytes((byte)SimName.Length, bytes, ref i); Buffer.BlockCopy(SimName, 0, bytes, i, SimName.Length); i += SimName.Length; } @@ -3393,19 +3450,19 @@ public override void FromBytes(byte[] bytes, ref int i) try { OwnerID.FromBytes(bytes, i); i += 16; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Name = new byte[length]; Buffer.BlockCopy(bytes, i, Name, 0, length); i += length; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Desc = new byte[length]; Buffer.BlockCopy(bytes, i, Desc, 0, length); i += length; ActualArea = Utils.BytesToIntSafepos(bytes, i); i +=4; BillableArea = Utils.BytesToIntSafepos(bytes, i); i +=4; - Flags = (byte)bytes[i++]; + Flags = Utils.BytesToByte(bytes, ref i); GlobalX = Utils.BytesToFloatSafepos(bytes, i); i += 4; GlobalY = Utils.BytesToFloatSafepos(bytes, i); i += 4; GlobalZ = Utils.BytesToFloatSafepos(bytes, i); i += 4; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); SimName = new byte[length]; Buffer.BlockCopy(bytes, i, SimName, 0, length); i += length; SnapshotID.FromBytes(bytes, i); i += 16; @@ -3421,17 +3478,17 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { OwnerID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)Name.Length; + Utils.ByteToBytes((byte)Name.Length, bytes, ref i); Buffer.BlockCopy(Name, 0, bytes, i, Name.Length); i += Name.Length; - bytes[i++] = (byte)Desc.Length; + Utils.ByteToBytes((byte)Desc.Length, bytes, ref i); Buffer.BlockCopy(Desc, 0, bytes, i, Desc.Length); i += Desc.Length; Utils.IntToBytesSafepos(ActualArea, bytes, i); i += 4; Utils.IntToBytesSafepos(BillableArea, bytes, i); i += 4; - bytes[i++] = Flags; + Utils.ByteToBytes( Flags, bytes, ref i); Utils.FloatToBytesSafepos(GlobalX, bytes, i); i += 4; Utils.FloatToBytesSafepos(GlobalY, bytes, i); i += 4; Utils.FloatToBytesSafepos(GlobalZ, bytes, i); i += 4; - bytes[i++] = (byte)SimName.Length; + Utils.ByteToBytes((byte)SimName.Length, bytes, ref i); Buffer.BlockCopy(SimName, 0, bytes, i, SimName.Length); i += SimName.Length; SnapshotID.ToBytes(bytes, i); i += 16; Utils.FloatToBytesSafepos(Dwell, bytes, i); i += 4; @@ -3529,7 +3586,7 @@ public override byte[] ToBytes() Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); TransactionData.ToBytes(bytes, ref i); - bytes[i++] = (byte)QueryData.Length; + Utils.ByteToBytes((byte)QueryData.Length, bytes, ref i); for (int j = 0; j < QueryData.Length; j++) { QueryData[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -3670,7 +3727,7 @@ public override void FromBytes(byte[] bytes, ref int i) try { QueryID.FromBytes(bytes, i); i += 16; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); QueryText = new byte[length]; Buffer.BlockCopy(bytes, i, QueryText, 0, length); i += length; QueryFlags = Utils.BytesToUIntSafepos(bytes, i); i += 4; @@ -3685,7 +3742,7 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { QueryID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)QueryText.Length; + Utils.ByteToBytes((byte)QueryText.Length, bytes, ref i); Buffer.BlockCopy(QueryText, 0, bytes, i, QueryText.Length); i += QueryText.Length; Utils.UIntToBytesSafepos(QueryFlags, bytes, i); i += 4; Utils.IntToBytesSafepos(QueryStart, bytes, i); i += 4; @@ -3847,12 +3904,12 @@ public override void FromBytes(byte[] bytes, ref int i) try { QueryID.FromBytes(bytes, i); i += 16; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); QueryText = new byte[length]; Buffer.BlockCopy(bytes, i, QueryText, 0, length); i += length; QueryFlags = Utils.BytesToUIntSafepos(bytes, i); i += 4; - Category = (sbyte)bytes[i++]; - length = bytes[i++]; + Category = (sbyte)Utils.BytesToByte(bytes, ref i); + length = Utils.BytesToByte(bytes, ref i); SimName = new byte[length]; Buffer.BlockCopy(bytes, i, SimName, 0, length); i += length; QueryStart = Utils.BytesToIntSafepos(bytes, i); i +=4; @@ -3866,11 +3923,11 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { QueryID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)QueryText.Length; + Utils.ByteToBytes((byte)QueryText.Length, bytes, ref i); Buffer.BlockCopy(QueryText, 0, bytes, i, QueryText.Length); i += QueryText.Length; Utils.UIntToBytesSafepos(QueryFlags, bytes, i); i += 4; - bytes[i++] = (byte)Category; - bytes[i++] = (byte)SimName.Length; + Utils.ByteToBytes( (byte)Category, bytes, ref i); + Utils.ByteToBytes((byte)SimName.Length, bytes, ref i); Buffer.BlockCopy(SimName, 0, bytes, i, SimName.Length); i += SimName.Length; Utils.IntToBytesSafepos(QueryStart, bytes, i); i += 4; } @@ -4064,11 +4121,11 @@ public override void FromBytes(byte[] bytes, ref int i) try { ParcelID.FromBytes(bytes, i); i += 16; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Name = new byte[length]; Buffer.BlockCopy(bytes, i, Name, 0, length); i += length; - ForSale = (bytes[i++] != 0) ? (bool)true : (bool)false; - Auction = (bytes[i++] != 0) ? (bool)true : (bool)false; + ForSale = (Utils.BytesToByte(bytes, ref i) != 0); + Auction = (Utils.BytesToByte(bytes, ref i) != 0); Dwell = Utils.BytesToFloatSafepos(bytes, i); i += 4; } catch (Exception) @@ -4080,10 +4137,10 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { ParcelID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)Name.Length; + Utils.ByteToBytes((byte)Name.Length, bytes, ref i); Buffer.BlockCopy(Name, 0, bytes, i, Name.Length); i += Name.Length; - bytes[i++] = (byte)((ForSale) ? 1 : 0); - bytes[i++] = (byte)((Auction) ? 1 : 0); + Utils.ByteToBytes((byte)((ForSale) ? 1 : 0), bytes, ref i); + Utils.ByteToBytes((byte)((Auction) ? 1 : 0), bytes, ref i); Utils.FloatToBytesSafepos(Dwell, bytes, i); i += 4; } @@ -4253,11 +4310,11 @@ public override byte[] ToBytes() int i = 0; Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); - bytes[i++] = (byte)QueryData.Length; + Utils.ByteToBytes((byte)QueryData.Length, bytes, ref i); for (int j = 0; j < QueryData.Length; j++) { QueryData[j].ToBytes(bytes, ref i); } - bytes[i++] = (byte)QueryReplies.Length; + Utils.ByteToBytes((byte)QueryReplies.Length, bytes, ref i); for (int j = 0; j < QueryReplies.Length; j++) { QueryReplies[j].ToBytes(bytes, ref i); } - bytes[i++] = (byte)StatusData.Length; + Utils.ByteToBytes((byte)StatusData.Length, bytes, ref i); for (int j = 0; j < StatusData.Length; j++) { StatusData[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -4471,16 +4528,16 @@ public override void FromBytes(byte[] bytes, ref int i) try { AgentID.FromBytes(bytes, i); i += 16; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); FirstName = new byte[length]; Buffer.BlockCopy(bytes, i, FirstName, 0, length); i += length; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); LastName = new byte[length]; Buffer.BlockCopy(bytes, i, LastName, 0, length); i += length; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Group = new byte[length]; Buffer.BlockCopy(bytes, i, Group, 0, length); i += length; - Online = (bytes[i++] != 0) ? (bool)true : (bool)false; + Online = (Utils.BytesToByte(bytes, ref i) != 0); Reputation = Utils.BytesToIntSafepos(bytes, i); i +=4; } catch (Exception) @@ -4492,13 +4549,13 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { AgentID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)FirstName.Length; + Utils.ByteToBytes((byte)FirstName.Length, bytes, ref i); Buffer.BlockCopy(FirstName, 0, bytes, i, FirstName.Length); i += FirstName.Length; - bytes[i++] = (byte)LastName.Length; + Utils.ByteToBytes((byte)LastName.Length, bytes, ref i); Buffer.BlockCopy(LastName, 0, bytes, i, LastName.Length); i += LastName.Length; - bytes[i++] = (byte)Group.Length; + Utils.ByteToBytes((byte)Group.Length, bytes, ref i); Buffer.BlockCopy(Group, 0, bytes, i, Group.Length); i += Group.Length; - bytes[i++] = (byte)((Online) ? 1 : 0); + Utils.ByteToBytes((byte)((Online) ? 1 : 0), bytes, ref i); Utils.IntToBytesSafepos(Reputation, bytes, i); i += 4; } @@ -4593,7 +4650,7 @@ public override byte[] ToBytes() Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); QueryData.ToBytes(bytes, ref i); - bytes[i++] = (byte)QueryReplies.Length; + Utils.ByteToBytes((byte)QueryReplies.Length, bytes, ref i); for (int j = 0; j < QueryReplies.Length; j++) { QueryReplies[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -4772,11 +4829,11 @@ public override void FromBytes(byte[] bytes, ref int i) try { OwnerID.FromBytes(bytes, i); i += 16; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Name = new byte[length]; Buffer.BlockCopy(bytes, i, Name, 0, length); i += length; EventID = Utils.BytesToUIntSafepos(bytes, i); i += 4; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Date = new byte[length]; Buffer.BlockCopy(bytes, i, Date, 0, length); i += length; UnixTime = Utils.BytesToUIntSafepos(bytes, i); i += 4; @@ -4791,10 +4848,10 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { OwnerID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)Name.Length; + Utils.ByteToBytes((byte)Name.Length, bytes, ref i); Buffer.BlockCopy(Name, 0, bytes, i, Name.Length); i += Name.Length; Utils.UIntToBytesSafepos(EventID, bytes, i); i += 4; - bytes[i++] = (byte)Date.Length; + Utils.ByteToBytes((byte)Date.Length, bytes, ref i); Buffer.BlockCopy(Date, 0, bytes, i, Date.Length); i += Date.Length; Utils.UIntToBytesSafepos(UnixTime, bytes, i); i += 4; Utils.UIntToBytesSafepos(EventFlags, bytes, i); i += 4; @@ -4951,9 +5008,9 @@ public override byte[] ToBytes() Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); QueryData.ToBytes(bytes, ref i); - bytes[i++] = (byte)QueryReplies.Length; + Utils.ByteToBytes((byte)QueryReplies.Length, bytes, ref i); for (int j = 0; j < QueryReplies.Length; j++) { QueryReplies[j].ToBytes(bytes, ref i); } - bytes[i++] = (byte)StatusData.Length; + Utils.ByteToBytes((byte)StatusData.Length, bytes, ref i); for (int j = 0; j < StatusData.Length; j++) { StatusData[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -5147,7 +5204,7 @@ public override void FromBytes(byte[] bytes, ref int i) try { GroupID.FromBytes(bytes, i); i += 16; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); GroupName = new byte[length]; Buffer.BlockCopy(bytes, i, GroupName, 0, length); i += length; Members = Utils.BytesToIntSafepos(bytes, i); i +=4; @@ -5162,7 +5219,7 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { GroupID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)GroupName.Length; + Utils.ByteToBytes((byte)GroupName.Length, bytes, ref i); Buffer.BlockCopy(GroupName, 0, bytes, i, GroupName.Length); i += GroupName.Length; Utils.IntToBytesSafepos(Members, bytes, i); i += 4; Utils.FloatToBytesSafepos(SearchOrder, bytes, i); i += 4; @@ -5259,7 +5316,7 @@ public override byte[] ToBytes() Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); QueryData.ToBytes(bytes, ref i); - bytes[i++] = (byte)QueryReplies.Length; + Utils.ByteToBytes((byte)QueryReplies.Length, bytes, ref i); for (int j = 0; j < QueryReplies.Length; j++) { QueryReplies[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -5401,7 +5458,7 @@ public override void FromBytes(byte[] bytes, ref int i) try { QueryID.FromBytes(bytes, i); i += 16; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); QueryText = new byte[length]; Buffer.BlockCopy(bytes, i, QueryText, 0, length); i += length; QueryFlags = Utils.BytesToUIntSafepos(bytes, i); i += 4; @@ -5417,7 +5474,7 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { QueryID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)QueryText.Length; + Utils.ByteToBytes((byte)QueryText.Length, bytes, ref i); Buffer.BlockCopy(QueryText, 0, bytes, i, QueryText.Length); i += QueryText.Length; Utils.UIntToBytesSafepos(QueryFlags, bytes, i); i += 4; Utils.UIntToBytesSafepos(Category, bytes, i); i += 4; @@ -5614,10 +5671,10 @@ public override void FromBytes(byte[] bytes, ref int i) try { ClassifiedID.FromBytes(bytes, i); i += 16; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Name = new byte[length]; Buffer.BlockCopy(bytes, i, Name, 0, length); i += length; - ClassifiedFlags = (byte)bytes[i++]; + ClassifiedFlags = Utils.BytesToByte(bytes, ref i); CreationDate = Utils.BytesToUIntSafepos(bytes, i); i += 4; ExpirationDate = Utils.BytesToUIntSafepos(bytes, i); i += 4; PriceForListing = Utils.BytesToIntSafepos(bytes, i); i +=4; @@ -5631,9 +5688,9 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { ClassifiedID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)Name.Length; + Utils.ByteToBytes((byte)Name.Length, bytes, ref i); Buffer.BlockCopy(Name, 0, bytes, i, Name.Length); i += Name.Length; - bytes[i++] = ClassifiedFlags; + Utils.ByteToBytes( ClassifiedFlags, bytes, ref i); Utils.UIntToBytesSafepos(CreationDate, bytes, i); i += 4; Utils.UIntToBytesSafepos(ExpirationDate, bytes, i); i += 4; Utils.IntToBytesSafepos(PriceForListing, bytes, i); i += 4; @@ -5790,9 +5847,9 @@ public override byte[] ToBytes() Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); QueryData.ToBytes(bytes, ref i); - bytes[i++] = (byte)QueryReplies.Length; + Utils.ByteToBytes((byte)QueryReplies.Length, bytes, ref i); for (int j = 0; j < QueryReplies.Length; j++) { QueryReplies[j].ToBytes(bytes, ref i); } - bytes[i++] = (byte)StatusData.Length; + Utils.ByteToBytes((byte)StatusData.Length, bytes, ref i); for (int j = 0; j < StatusData.Length; j++) { StatusData[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -5949,7 +6006,7 @@ public override void FromBytes(byte[] bytes, ref int i) try { ClassifiedID.FromBytes(bytes, i); i += 16; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Name = new byte[length]; Buffer.BlockCopy(bytes, i, Name, 0, length); i += length; } @@ -5962,7 +6019,7 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { ClassifiedID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)Name.Length; + Utils.ByteToBytes((byte)Name.Length, bytes, ref i); Buffer.BlockCopy(Name, 0, bytes, i, Name.Length); i += Name.Length; } @@ -6049,7 +6106,7 @@ public override byte[] ToBytes() int i = 0; Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); - bytes[i++] = (byte)Data.Length; + Utils.ByteToBytes((byte)Data.Length, bytes, ref i); for (int j = 0; j < Data.Length; j++) { Data[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -6362,23 +6419,23 @@ public override void FromBytes(byte[] bytes, ref int i) CreationDate = Utils.BytesToUIntSafepos(bytes, i); i += 4; ExpirationDate = Utils.BytesToUIntSafepos(bytes, i); i += 4; Category = Utils.BytesToUIntSafepos(bytes, i); i += 4; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Name = new byte[length]; Buffer.BlockCopy(bytes, i, Name, 0, length); i += length; - length = (bytes[i++] + (bytes[i++] << 8)); + length = Utils.BytesToUInt16(bytes, i); i+=2; Desc = new byte[length]; Buffer.BlockCopy(bytes, i, Desc, 0, length); i += length; ParcelID.FromBytes(bytes, i); i += 16; ParentEstate = Utils.BytesToUIntSafepos(bytes, i); i += 4; SnapshotID.FromBytes(bytes, i); i += 16; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); SimName = new byte[length]; Buffer.BlockCopy(bytes, i, SimName, 0, length); i += length; PosGlobal.FromBytes(bytes, i); i += 24; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); ParcelName = new byte[length]; Buffer.BlockCopy(bytes, i, ParcelName, 0, length); i += length; - ClassifiedFlags = (byte)bytes[i++]; + ClassifiedFlags = Utils.BytesToByte(bytes, ref i); PriceForListing = Utils.BytesToIntSafepos(bytes, i); i +=4; } catch (Exception) @@ -6394,20 +6451,19 @@ public override void ToBytes(byte[] bytes, ref int i) Utils.UIntToBytesSafepos(CreationDate, bytes, i); i += 4; Utils.UIntToBytesSafepos(ExpirationDate, bytes, i); i += 4; Utils.UIntToBytesSafepos(Category, bytes, i); i += 4; - bytes[i++] = (byte)Name.Length; + Utils.ByteToBytes((byte)Name.Length, bytes, ref i); Buffer.BlockCopy(Name, 0, bytes, i, Name.Length); i += Name.Length; - bytes[i++] = (byte)(Desc.Length % 256); - bytes[i++] = (byte)((Desc.Length >> 8) % 256); + Utils.UInt16ToBytes((ushort)Desc.Length, bytes, i); i += 2; Buffer.BlockCopy(Desc, 0, bytes, i, Desc.Length); i += Desc.Length; ParcelID.ToBytes(bytes, i); i += 16; Utils.UIntToBytesSafepos(ParentEstate, bytes, i); i += 4; SnapshotID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)SimName.Length; + Utils.ByteToBytes((byte)SimName.Length, bytes, ref i); Buffer.BlockCopy(SimName, 0, bytes, i, SimName.Length); i += SimName.Length; PosGlobal.ToBytes(bytes, i); i += 24; - bytes[i++] = (byte)ParcelName.Length; + Utils.ByteToBytes((byte)ParcelName.Length, bytes, ref i); Buffer.BlockCopy(ParcelName, 0, bytes, i, ParcelName.Length); i += ParcelName.Length; - bytes[i++] = ClassifiedFlags; + Utils.ByteToBytes( ClassifiedFlags, bytes, ref i); Utils.IntToBytesSafepos(PriceForListing, bytes, i); i += 4; } @@ -6571,17 +6627,17 @@ public override void FromBytes(byte[] bytes, ref int i) { ClassifiedID.FromBytes(bytes, i); i += 16; Category = Utils.BytesToUIntSafepos(bytes, i); i += 4; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Name = new byte[length]; Buffer.BlockCopy(bytes, i, Name, 0, length); i += length; - length = (bytes[i++] + (bytes[i++] << 8)); + length = Utils.BytesToUInt16(bytes, i); i+=2; Desc = new byte[length]; Buffer.BlockCopy(bytes, i, Desc, 0, length); i += length; ParcelID.FromBytes(bytes, i); i += 16; ParentEstate = Utils.BytesToUIntSafepos(bytes, i); i += 4; SnapshotID.FromBytes(bytes, i); i += 16; PosGlobal.FromBytes(bytes, i); i += 24; - ClassifiedFlags = (byte)bytes[i++]; + ClassifiedFlags = Utils.BytesToByte(bytes, ref i); PriceForListing = Utils.BytesToIntSafepos(bytes, i); i +=4; } catch (Exception) @@ -6594,16 +6650,15 @@ public override void ToBytes(byte[] bytes, ref int i) { ClassifiedID.ToBytes(bytes, i); i += 16; Utils.UIntToBytesSafepos(Category, bytes, i); i += 4; - bytes[i++] = (byte)Name.Length; + Utils.ByteToBytes((byte)Name.Length, bytes, ref i); Buffer.BlockCopy(Name, 0, bytes, i, Name.Length); i += Name.Length; - bytes[i++] = (byte)(Desc.Length % 256); - bytes[i++] = (byte)((Desc.Length >> 8) % 256); + Utils.UInt16ToBytes((ushort)Desc.Length, bytes, i); i += 2; Buffer.BlockCopy(Desc, 0, bytes, i, Desc.Length); i += Desc.Length; ParcelID.ToBytes(bytes, i); i += 16; Utils.UIntToBytesSafepos(ParentEstate, bytes, i); i += 4; SnapshotID.ToBytes(bytes, i); i += 16; PosGlobal.ToBytes(bytes, i); i += 24; - bytes[i++] = ClassifiedFlags; + Utils.ByteToBytes( ClassifiedFlags, bytes, ref i); Utils.IntToBytesSafepos(PriceForListing, bytes, i); i += 4; } @@ -7289,11 +7344,11 @@ public override void FromBytes(byte[] bytes, ref int i) try { ParcelID.FromBytes(bytes, i); i += 16; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Name = new byte[length]; Buffer.BlockCopy(bytes, i, Name, 0, length); i += length; - Auction = (bytes[i++] != 0) ? (bool)true : (bool)false; - ForSale = (bytes[i++] != 0) ? (bool)true : (bool)false; + Auction = (Utils.BytesToByte(bytes, ref i) != 0); + ForSale = (Utils.BytesToByte(bytes, ref i) != 0); SalePrice = Utils.BytesToIntSafepos(bytes, i); i +=4; ActualArea = Utils.BytesToIntSafepos(bytes, i); i +=4; } @@ -7306,10 +7361,10 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { ParcelID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)Name.Length; + Utils.ByteToBytes((byte)Name.Length, bytes, ref i); Buffer.BlockCopy(Name, 0, bytes, i, Name.Length); i += Name.Length; - bytes[i++] = (byte)((Auction) ? 1 : 0); - bytes[i++] = (byte)((ForSale) ? 1 : 0); + Utils.ByteToBytes((byte)((Auction) ? 1 : 0), bytes, ref i); + Utils.ByteToBytes((byte)((ForSale) ? 1 : 0), bytes, ref i); Utils.IntToBytesSafepos(SalePrice, bytes, i); i += 4; Utils.IntToBytesSafepos(ActualArea, bytes, i); i += 4; } @@ -7405,7 +7460,7 @@ public override byte[] ToBytes() Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); QueryData.ToBytes(bytes, ref i); - bytes[i++] = (byte)QueryReplies.Length; + Utils.ByteToBytes((byte)QueryReplies.Length, bytes, ref i); for (int j = 0; j < QueryReplies.Length; j++) { QueryReplies[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -7742,7 +7797,7 @@ public override void FromBytes(byte[] bytes, ref int i) try { ParcelID.FromBytes(bytes, i); i += 16; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Name = new byte[length]; Buffer.BlockCopy(bytes, i, Name, 0, length); i += length; Dwell = Utils.BytesToFloatSafepos(bytes, i); i += 4; @@ -7756,7 +7811,7 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { ParcelID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)Name.Length; + Utils.ByteToBytes((byte)Name.Length, bytes, ref i); Buffer.BlockCopy(Name, 0, bytes, i, Name.Length); i += Name.Length; Utils.FloatToBytesSafepos(Dwell, bytes, i); i += 4; } @@ -7852,7 +7907,7 @@ public override byte[] ToBytes() Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); QueryData.ToBytes(bytes, ref i); - bytes[i++] = (byte)QueryReplies.Length; + Utils.ByteToBytes((byte)QueryReplies.Length, bytes, ref i); for (int j = 0; j < QueryReplies.Length; j++) { QueryReplies[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -8162,19 +8217,19 @@ public override void FromBytes(byte[] bytes, ref int i) { ParcelID.FromBytes(bytes, i); i += 16; OwnerID.FromBytes(bytes, i); i += 16; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Name = new byte[length]; Buffer.BlockCopy(bytes, i, Name, 0, length); i += length; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Desc = new byte[length]; Buffer.BlockCopy(bytes, i, Desc, 0, length); i += length; ActualArea = Utils.BytesToIntSafepos(bytes, i); i +=4; BillableArea = Utils.BytesToIntSafepos(bytes, i); i +=4; - Flags = (byte)bytes[i++]; + Flags = Utils.BytesToByte(bytes, ref i); GlobalX = Utils.BytesToFloatSafepos(bytes, i); i += 4; GlobalY = Utils.BytesToFloatSafepos(bytes, i); i += 4; GlobalZ = Utils.BytesToFloatSafepos(bytes, i); i += 4; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); SimName = new byte[length]; Buffer.BlockCopy(bytes, i, SimName, 0, length); i += length; SnapshotID.FromBytes(bytes, i); i += 16; @@ -8192,17 +8247,17 @@ public override void ToBytes(byte[] bytes, ref int i) { ParcelID.ToBytes(bytes, i); i += 16; OwnerID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)Name.Length; + Utils.ByteToBytes((byte)Name.Length, bytes, ref i); Buffer.BlockCopy(Name, 0, bytes, i, Name.Length); i += Name.Length; - bytes[i++] = (byte)Desc.Length; + Utils.ByteToBytes((byte)Desc.Length, bytes, ref i); Buffer.BlockCopy(Desc, 0, bytes, i, Desc.Length); i += Desc.Length; Utils.IntToBytesSafepos(ActualArea, bytes, i); i += 4; Utils.IntToBytesSafepos(BillableArea, bytes, i); i += 4; - bytes[i++] = Flags; + Utils.ByteToBytes( Flags, bytes, ref i); Utils.FloatToBytesSafepos(GlobalX, bytes, i); i += 4; Utils.FloatToBytesSafepos(GlobalY, bytes, i); i += 4; Utils.FloatToBytesSafepos(GlobalZ, bytes, i); i += 4; - bytes[i++] = (byte)SimName.Length; + Utils.ByteToBytes((byte)SimName.Length, bytes, ref i); Buffer.BlockCopy(SimName, 0, bytes, i, SimName.Length); i += SimName.Length; SnapshotID.ToBytes(bytes, i); i += 16; Utils.FloatToBytesSafepos(Dwell, bytes, i); i += 4; @@ -8477,9 +8532,9 @@ public override void FromBytes(byte[] bytes, ref int i) try { OwnerID.FromBytes(bytes, i); i += 16; - IsGroupOwned = (bytes[i++] != 0) ? (bool)true : (bool)false; + IsGroupOwned = (Utils.BytesToByte(bytes, ref i) != 0); Count = Utils.BytesToIntSafepos(bytes, i); i +=4; - OnlineStatus = (bytes[i++] != 0) ? (bool)true : (bool)false; + OnlineStatus = (Utils.BytesToByte(bytes, ref i) != 0); } catch (Exception) { @@ -8490,9 +8545,9 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { OwnerID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)((IsGroupOwned) ? 1 : 0); + Utils.ByteToBytes((byte)((IsGroupOwned) ? 1 : 0), bytes, ref i); Utils.IntToBytesSafepos(Count, bytes, i); i += 4; - bytes[i++] = (byte)((OnlineStatus) ? 1 : 0); + Utils.ByteToBytes((byte)((OnlineStatus) ? 1 : 0), bytes, ref i); } } @@ -8572,7 +8627,7 @@ public override byte[] ToBytes() byte[] bytes = new byte[length]; int i = 0; Header.ToBytes(bytes, ref i); - bytes[i++] = (byte)Data.Length; + Utils.ByteToBytes((byte)Data.Length, bytes, ref i); for (int j = 0; j < Data.Length; j++) { Data[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -8871,14 +8926,14 @@ public override void FromBytes(byte[] bytes, ref int i) { NoticeID.FromBytes(bytes, i); i += 16; Timestamp = Utils.BytesToUIntSafepos(bytes, i); i += 4; - length = (bytes[i++] + (bytes[i++] << 8)); + length = Utils.BytesToUInt16(bytes, i); i+=2; FromName = new byte[length]; Buffer.BlockCopy(bytes, i, FromName, 0, length); i += length; - length = (bytes[i++] + (bytes[i++] << 8)); + length = Utils.BytesToUInt16(bytes, i); i+=2; Subject = new byte[length]; Buffer.BlockCopy(bytes, i, Subject, 0, length); i += length; - HasAttachment = (bytes[i++] != 0) ? (bool)true : (bool)false; - AssetType = (byte)bytes[i++]; + HasAttachment = (Utils.BytesToByte(bytes, ref i) != 0); + AssetType = Utils.BytesToByte(bytes, ref i); } catch (Exception) { @@ -8890,14 +8945,12 @@ public override void ToBytes(byte[] bytes, ref int i) { NoticeID.ToBytes(bytes, i); i += 16; Utils.UIntToBytesSafepos(Timestamp, bytes, i); i += 4; - bytes[i++] = (byte)(FromName.Length % 256); - bytes[i++] = (byte)((FromName.Length >> 8) % 256); + Utils.UInt16ToBytes((ushort)FromName.Length, bytes, i); i += 2; Buffer.BlockCopy(FromName, 0, bytes, i, FromName.Length); i += FromName.Length; - bytes[i++] = (byte)(Subject.Length % 256); - bytes[i++] = (byte)((Subject.Length >> 8) % 256); + Utils.UInt16ToBytes((ushort)Subject.Length, bytes, i); i += 2; Buffer.BlockCopy(Subject, 0, bytes, i, Subject.Length); i += Subject.Length; - bytes[i++] = (byte)((HasAttachment) ? 1 : 0); - bytes[i++] = AssetType; + Utils.ByteToBytes((byte)((HasAttachment) ? 1 : 0), bytes, ref i); + Utils.ByteToBytes( AssetType, bytes, ref i); } } @@ -8983,7 +9036,7 @@ public override byte[] ToBytes() int i = 0; Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); - bytes[i++] = (byte)Data.Length; + Utils.ByteToBytes((byte)Data.Length, bytes, ref i); for (int j = 0; j < Data.Length; j++) { Data[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -9842,7 +9895,7 @@ public override void FromBytes(byte[] bytes, ref int i) try { TeleportFlags = Utils.BytesToUIntSafepos(bytes, i); i += 4; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Message = new byte[length]; Buffer.BlockCopy(bytes, i, Message, 0, length); i += length; } @@ -9855,7 +9908,7 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { Utils.UIntToBytesSafepos(TeleportFlags, bytes, i); i += 4; - bytes[i++] = (byte)Message.Length; + Utils.ByteToBytes((byte)Message.Length, bytes, ref i); Buffer.BlockCopy(Message, 0, bytes, i, Message.Length); i += Message.Length; } @@ -9978,10 +10031,10 @@ public override void FromBytes(byte[] bytes, ref int i) SimIP = Utils.BytesToUIntSafepos(bytes, i); i += 4; SimPort = (ushort)((bytes[i++] << 8) + bytes[i++]); RegionHandle = Utils.BytesToUInt64Safepos(bytes, i); i += 8; - length = (bytes[i++] + (bytes[i++] << 8)); + length = Utils.BytesToUInt16(bytes, i); i+=2; SeedCapability = new byte[length]; Buffer.BlockCopy(bytes, i, SeedCapability, 0, length); i += length; - SimAccess = (byte)bytes[i++]; + SimAccess = Utils.BytesToByte(bytes, ref i); TeleportFlags = Utils.BytesToUIntSafepos(bytes, i); i += 4; } catch (Exception) @@ -9995,13 +10048,11 @@ public override void ToBytes(byte[] bytes, ref int i) AgentID.ToBytes(bytes, i); i += 16; Utils.UIntToBytesSafepos(LocationID, bytes, i); i += 4; Utils.UIntToBytesSafepos(SimIP, bytes, i); i += 4; - bytes[i++] = (byte)((SimPort >> 8) % 256); - bytes[i++] = (byte)(SimPort % 256); + Utils.UInt16ToBytesBig(SimPort, bytes, i); i += 2; Utils.UInt64ToBytesSafepos(RegionHandle, bytes, i); i += 8; - bytes[i++] = (byte)(SeedCapability.Length % 256); - bytes[i++] = (byte)((SeedCapability.Length >> 8) % 256); + Utils.UInt16ToBytes((ushort)SeedCapability.Length, bytes, i); i += 2; Buffer.BlockCopy(SeedCapability, 0, bytes, i, SeedCapability.Length); i += SeedCapability.Length; - bytes[i++] = SimAccess; + Utils.ByteToBytes( SimAccess, bytes, ref i); Utils.UIntToBytesSafepos(TeleportFlags, bytes, i); i += 4; } @@ -10147,8 +10198,8 @@ public override void FromBytes(byte[] bytes, ref int i) int length; try { - LureType = (byte)bytes[i++]; - length = bytes[i++]; + LureType = Utils.BytesToByte(bytes, ref i); + length = Utils.BytesToByte(bytes, ref i); Message = new byte[length]; Buffer.BlockCopy(bytes, i, Message, 0, length); i += length; } @@ -10160,8 +10211,8 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { - bytes[i++] = LureType; - bytes[i++] = (byte)Message.Length; + Utils.ByteToBytes( LureType, bytes, ref i); + Utils.ByteToBytes((byte)Message.Length, bytes, ref i); Buffer.BlockCopy(Message, 0, bytes, i, Message.Length); i += Message.Length; } @@ -10293,7 +10344,7 @@ public override byte[] ToBytes() Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); Info.ToBytes(bytes, ref i); - bytes[i++] = (byte)TargetData.Length; + Utils.ByteToBytes((byte)TargetData.Length, bytes, ref i); for (int j = 0; j < TargetData.Length; j++) { TargetData[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -10733,7 +10784,7 @@ public override void FromBytes(byte[] bytes, ref int i) try { AgentID.FromBytes(bytes, i); i += 16; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Reason = new byte[length]; Buffer.BlockCopy(bytes, i, Reason, 0, length); i += length; } @@ -10746,7 +10797,7 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { AgentID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)Reason.Length; + Utils.ByteToBytes((byte)Reason.Length, bytes, ref i); Buffer.BlockCopy(Reason, 0, bytes, i, Reason.Length); i += Reason.Length; } @@ -10780,10 +10831,10 @@ public override void FromBytes(byte[] bytes, ref int i) int length; try { - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Message = new byte[length]; Buffer.BlockCopy(bytes, i, Message, 0, length); i += length; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); ExtraParams = new byte[length]; Buffer.BlockCopy(bytes, i, ExtraParams, 0, length); i += length; } @@ -10795,9 +10846,9 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { - bytes[i++] = (byte)Message.Length; + Utils.ByteToBytes((byte)Message.Length, bytes, ref i); Buffer.BlockCopy(Message, 0, bytes, i, Message.Length); i += Message.Length; - bytes[i++] = (byte)ExtraParams.Length; + Utils.ByteToBytes((byte)ExtraParams.Length, bytes, ref i); Buffer.BlockCopy(ExtraParams, 0, bytes, i, ExtraParams.Length); i += ExtraParams.Length; } @@ -10884,7 +10935,7 @@ public override byte[] ToBytes() int i = 0; Header.ToBytes(bytes, ref i); Info.ToBytes(bytes, ref i); - bytes[i++] = (byte)AlertInfo.Length; + Utils.ByteToBytes((byte)AlertInfo.Length, bytes, ref i); for (int j = 0; j < AlertInfo.Length; j++) { AlertInfo[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -11115,7 +11166,7 @@ public override byte[] ToBytes() int i = 0; Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); - bytes[i++] = (byte)ObjectData.Length; + Utils.ByteToBytes((byte)ObjectData.Length, bytes, ref i); for (int j = 0; j < ObjectData.Length; j++) { ObjectData[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -11346,7 +11397,7 @@ public override byte[] ToBytes() int i = 0; Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); - bytes[i++] = (byte)ObjectData.Length; + Utils.ByteToBytes((byte)ObjectData.Length, bytes, ref i); for (int j = 0; j < ObjectData.Length; j++) { ObjectData[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -11828,10 +11879,10 @@ public override void FromBytes(byte[] bytes, ref int i) int length; try { - length = (bytes[i++] + (bytes[i++] << 8)); + length = Utils.BytesToUInt16(bytes, i); i+=2; Message = new byte[length]; Buffer.BlockCopy(bytes, i, Message, 0, length); i += length; - Type = (byte)bytes[i++]; + Type = Utils.BytesToByte(bytes, ref i); Channel = Utils.BytesToIntSafepos(bytes, i); i +=4; } catch (Exception) @@ -11842,10 +11893,9 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { - bytes[i++] = (byte)(Message.Length % 256); - bytes[i++] = (byte)((Message.Length >> 8) % 256); + Utils.UInt16ToBytes((ushort)Message.Length, bytes, i); i += 2; Buffer.BlockCopy(Message, 0, bytes, i, Message.Length); i += Message.Length; - bytes[i++] = Type; + Utils.ByteToBytes( Type, bytes, ref i); Utils.IntToBytesSafepos(Channel, bytes, i); i += 4; } @@ -12003,7 +12053,7 @@ public override void FromBytes(byte[] bytes, ref int i) try { GenCounter = Utils.BytesToUIntSafepos(bytes, i); i += 4; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Throttles = new byte[length]; Buffer.BlockCopy(bytes, i, Throttles, 0, length); i += length; } @@ -12016,7 +12066,7 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { Utils.UIntToBytesSafepos(GenCounter, bytes, i); i += 4; - bytes[i++] = (byte)Throttles.Length; + Utils.ByteToBytes((byte)Throttles.Length, bytes, ref i); Buffer.BlockCopy(Throttles, 0, bytes, i, Throttles.Length); i += Throttles.Length; } @@ -12505,7 +12555,7 @@ public override void FromBytes(byte[] bytes, ref int i) try { CacheID.FromBytes(bytes, i); i += 16; - TextureIndex = (byte)bytes[i++]; + TextureIndex = Utils.BytesToByte(bytes, ref i); } catch (Exception) { @@ -12516,7 +12566,7 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { CacheID.ToBytes(bytes, i); i += 16; - bytes[i++] = TextureIndex; + Utils.ByteToBytes( TextureIndex, bytes, ref i); } } @@ -12547,7 +12597,7 @@ public override void FromBytes(byte[] bytes, ref int i) int length; try { - length = (bytes[i++] + (bytes[i++] << 8)); + length = Utils.BytesToUInt16(bytes, i); i+=2; TextureEntry = new byte[length]; Buffer.BlockCopy(bytes, i, TextureEntry, 0, length); i += length; } @@ -12559,8 +12609,7 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { - bytes[i++] = (byte)(TextureEntry.Length % 256); - bytes[i++] = (byte)((TextureEntry.Length >> 8) % 256); + Utils.UInt16ToBytes((ushort)TextureEntry.Length, bytes, i); i += 2; Buffer.BlockCopy(TextureEntry, 0, bytes, i, TextureEntry.Length); i += TextureEntry.Length; } @@ -12589,7 +12638,7 @@ public override void FromBytes(byte[] bytes, ref int i) { try { - ParamValue = (byte)bytes[i++]; + ParamValue = Utils.BytesToByte(bytes, ref i); } catch (Exception) { @@ -12599,7 +12648,7 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { - bytes[i++] = ParamValue; + Utils.ByteToBytes( ParamValue, bytes, ref i); } } @@ -12714,10 +12763,10 @@ public override byte[] ToBytes() int i = 0; Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); - bytes[i++] = (byte)WearableData.Length; + Utils.ByteToBytes((byte)WearableData.Length, bytes, ref i); for (int j = 0; j < WearableData.Length; j++) { WearableData[j].ToBytes(bytes, ref i); } ObjectData.ToBytes(bytes, ref i); - bytes[i++] = (byte)VisualParam.Length; + Utils.ByteToBytes((byte)VisualParam.Length, bytes, ref i); for (int j = 0; j < VisualParam.Length; j++) { VisualParam[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -13137,7 +13186,7 @@ public override void FromBytes(byte[] bytes, ref int i) { AgentID.FromBytes(bytes, i); i += 16; SessionID.FromBytes(bytes, i); i += 16; - AlwaysRun = (bytes[i++] != 0) ? (bool)true : (bool)false; + AlwaysRun = (Utils.BytesToByte(bytes, ref i) != 0); } catch (Exception) { @@ -13149,7 +13198,7 @@ public override void ToBytes(byte[] bytes, ref int i) { AgentID.ToBytes(bytes, i); i += 16; SessionID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)((AlwaysRun) ? 1 : 0); + Utils.ByteToBytes((byte)((AlwaysRun) ? 1 : 0), bytes, ref i); } } @@ -13253,7 +13302,7 @@ public override void FromBytes(byte[] bytes, ref int i) { AgentID.FromBytes(bytes, i); i += 16; SessionID.FromBytes(bytes, i); i += 16; - Force = (bytes[i++] != 0) ? (bool)true : (bool)false; + Force = (Utils.BytesToByte(bytes, ref i) != 0); } catch (Exception) { @@ -13265,7 +13314,7 @@ public override void ToBytes(byte[] bytes, ref int i) { AgentID.ToBytes(bytes, i); i += 16; SessionID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)((Force) ? 1 : 0); + Utils.ByteToBytes((byte)((Force) ? 1 : 0), bytes, ref i); } } @@ -13390,7 +13439,7 @@ public override byte[] ToBytes() int i = 0; Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); - bytes[i++] = (byte)ObjectData.Length; + Utils.ByteToBytes((byte)ObjectData.Length, bytes, ref i); for (int j = 0; j < ObjectData.Length; j++) { ObjectData[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -13670,7 +13719,7 @@ public override byte[] ToBytes() Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); SharedData.ToBytes(bytes, ref i); - bytes[i++] = (byte)ObjectData.Length; + Utils.ByteToBytes((byte)ObjectData.Length, bytes, ref i); for (int j = 0; j < ObjectData.Length; j++) { ObjectData[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -13778,10 +13827,10 @@ public override void FromBytes(byte[] bytes, ref int i) GroupID.FromBytes(bytes, i); i += 16; RayStart.FromBytes(bytes, i); i += 12; RayEnd.FromBytes(bytes, i); i += 12; - BypassRaycast = (bytes[i++] != 0) ? (bool)true : (bool)false; - RayEndIsIntersection = (bytes[i++] != 0) ? (bool)true : (bool)false; - CopyCenters = (bytes[i++] != 0) ? (bool)true : (bool)false; - CopyRotates = (bytes[i++] != 0) ? (bool)true : (bool)false; + BypassRaycast = (Utils.BytesToByte(bytes, ref i) != 0); + RayEndIsIntersection = (Utils.BytesToByte(bytes, ref i) != 0); + CopyCenters = (Utils.BytesToByte(bytes, ref i) != 0); + CopyRotates = (Utils.BytesToByte(bytes, ref i) != 0); RayTargetID.FromBytes(bytes, i); i += 16; DuplicateFlags = Utils.BytesToUIntSafepos(bytes, i); i += 4; } @@ -13798,10 +13847,10 @@ public override void ToBytes(byte[] bytes, ref int i) GroupID.ToBytes(bytes, i); i += 16; RayStart.ToBytes(bytes, i); i += 12; RayEnd.ToBytes(bytes, i); i += 12; - bytes[i++] = (byte)((BypassRaycast) ? 1 : 0); - bytes[i++] = (byte)((RayEndIsIntersection) ? 1 : 0); - bytes[i++] = (byte)((CopyCenters) ? 1 : 0); - bytes[i++] = (byte)((CopyRotates) ? 1 : 0); + Utils.ByteToBytes((byte)((BypassRaycast) ? 1 : 0), bytes, ref i); + Utils.ByteToBytes((byte)((RayEndIsIntersection) ? 1 : 0), bytes, ref i); + Utils.ByteToBytes((byte)((CopyCenters) ? 1 : 0), bytes, ref i); + Utils.ByteToBytes((byte)((CopyRotates) ? 1 : 0), bytes, ref i); RayTargetID.ToBytes(bytes, i); i += 16; Utils.UIntToBytesSafepos(DuplicateFlags, bytes, i); i += 4; } @@ -13928,7 +13977,7 @@ public override byte[] ToBytes() int i = 0; Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); - bytes[i++] = (byte)ObjectData.Length; + Utils.ByteToBytes((byte)ObjectData.Length, bytes, ref i); for (int j = 0; j < ObjectData.Length; j++) { ObjectData[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -14160,7 +14209,7 @@ public override byte[] ToBytes() int i = 0; Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); - bytes[i++] = (byte)ObjectData.Length; + Utils.ByteToBytes((byte)ObjectData.Length, bytes, ref i); for (int j = 0; j < ObjectData.Length; j++) { ObjectData[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -14392,7 +14441,7 @@ public override byte[] ToBytes() int i = 0; Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); - bytes[i++] = (byte)ObjectData.Length; + Utils.ByteToBytes((byte)ObjectData.Length, bytes, ref i); for (int j = 0; j < ObjectData.Length; j++) { ObjectData[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -14492,10 +14541,10 @@ public override void FromBytes(byte[] bytes, ref int i) AgentID.FromBytes(bytes, i); i += 16; SessionID.FromBytes(bytes, i); i += 16; ObjectLocalID = Utils.BytesToUIntSafepos(bytes, i); i += 4; - UsePhysics = (bytes[i++] != 0) ? (bool)true : (bool)false; - IsTemporary = (bytes[i++] != 0) ? (bool)true : (bool)false; - IsPhantom = (bytes[i++] != 0) ? (bool)true : (bool)false; - CastsShadows = (bytes[i++] != 0) ? (bool)true : (bool)false; + UsePhysics = (Utils.BytesToByte(bytes, ref i) != 0); + IsTemporary = (Utils.BytesToByte(bytes, ref i) != 0); + IsPhantom = (Utils.BytesToByte(bytes, ref i) != 0); + CastsShadows = (Utils.BytesToByte(bytes, ref i) != 0); } catch (Exception) { @@ -14508,10 +14557,10 @@ public override void ToBytes(byte[] bytes, ref int i) AgentID.ToBytes(bytes, i); i += 16; SessionID.ToBytes(bytes, i); i += 16; Utils.UIntToBytesSafepos(ObjectLocalID, bytes, i); i += 4; - bytes[i++] = (byte)((UsePhysics) ? 1 : 0); - bytes[i++] = (byte)((IsTemporary) ? 1 : 0); - bytes[i++] = (byte)((IsPhantom) ? 1 : 0); - bytes[i++] = (byte)((CastsShadows) ? 1 : 0); + Utils.ByteToBytes((byte)((UsePhysics) ? 1 : 0), bytes, ref i); + Utils.ByteToBytes((byte)((IsTemporary) ? 1 : 0), bytes, ref i); + Utils.ByteToBytes((byte)((IsPhantom) ? 1 : 0), bytes, ref i); + Utils.ByteToBytes((byte)((CastsShadows) ? 1 : 0), bytes, ref i); } } @@ -14543,7 +14592,7 @@ public override void FromBytes(byte[] bytes, ref int i) { try { - PhysicsShapeType = (byte)bytes[i++]; + PhysicsShapeType = Utils.BytesToByte(bytes, ref i); Density = Utils.BytesToFloatSafepos(bytes, i); i += 4; Friction = Utils.BytesToFloatSafepos(bytes, i); i += 4; Restitution = Utils.BytesToFloatSafepos(bytes, i); i += 4; @@ -14557,7 +14606,7 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { - bytes[i++] = PhysicsShapeType; + Utils.ByteToBytes( PhysicsShapeType, bytes, ref i); Utils.FloatToBytesSafepos(Density, bytes, i); i += 4; Utils.FloatToBytesSafepos(Friction, bytes, i); i += 4; Utils.FloatToBytesSafepos(Restitution, bytes, i); i += 4; @@ -14648,7 +14697,7 @@ public override byte[] ToBytes() int i = 0; Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); - bytes[i++] = (byte)ExtraPhysics.Length; + Utils.ByteToBytes((byte)ExtraPhysics.Length, bytes, ref i); for (int j = 0; j < ExtraPhysics.Length; j++) { ExtraPhysics[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -14782,7 +14831,7 @@ public override void FromBytes(byte[] bytes, ref int i) try { ObjectLocalID = Utils.BytesToUIntSafepos(bytes, i); i += 4; - ClickAction = (byte)bytes[i++]; + ClickAction = Utils.BytesToByte(bytes, ref i); } catch (Exception) { @@ -14793,7 +14842,7 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { Utils.UIntToBytesSafepos(ObjectLocalID, bytes, i); i += 4; - bytes[i++] = ClickAction; + Utils.ByteToBytes( ClickAction, bytes, ref i); } } @@ -14880,7 +14929,7 @@ public override byte[] ToBytes() int i = 0; Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); - bytes[i++] = (byte)ObjectData.Length; + Utils.ByteToBytes((byte)ObjectData.Length, bytes, ref i); for (int j = 0; j < ObjectData.Length; j++) { ObjectData[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -15019,10 +15068,10 @@ public override void FromBytes(byte[] bytes, ref int i) try { ObjectLocalID = Utils.BytesToUIntSafepos(bytes, i); i += 4; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); MediaURL = new byte[length]; Buffer.BlockCopy(bytes, i, MediaURL, 0, length); i += length; - length = (bytes[i++] + (bytes[i++] << 8)); + length = Utils.BytesToUInt16(bytes, i); i+=2; TextureEntry = new byte[length]; Buffer.BlockCopy(bytes, i, TextureEntry, 0, length); i += length; } @@ -15035,10 +15084,9 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { Utils.UIntToBytesSafepos(ObjectLocalID, bytes, i); i += 4; - bytes[i++] = (byte)MediaURL.Length; + Utils.ByteToBytes((byte)MediaURL.Length, bytes, ref i); Buffer.BlockCopy(MediaURL, 0, bytes, i, MediaURL.Length); i += MediaURL.Length; - bytes[i++] = (byte)(TextureEntry.Length % 256); - bytes[i++] = (byte)((TextureEntry.Length >> 8) % 256); + Utils.UInt16ToBytes((ushort)TextureEntry.Length, bytes, i); i += 2; Buffer.BlockCopy(TextureEntry, 0, bytes, i, TextureEntry.Length); i += TextureEntry.Length; } @@ -15126,7 +15174,7 @@ public override byte[] ToBytes() int i = 0; Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); - bytes[i++] = (byte)ObjectData.Length; + Utils.ByteToBytes((byte)ObjectData.Length, bytes, ref i); for (int j = 0; j < ObjectData.Length; j++) { ObjectData[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -15260,7 +15308,7 @@ public override void FromBytes(byte[] bytes, ref int i) try { ObjectLocalID = Utils.BytesToUIntSafepos(bytes, i); i += 4; - Material = (byte)bytes[i++]; + Material = Utils.BytesToByte(bytes, ref i); } catch (Exception) { @@ -15271,7 +15319,7 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { Utils.UIntToBytesSafepos(ObjectLocalID, bytes, i); i += 4; - bytes[i++] = Material; + Utils.ByteToBytes( Material, bytes, ref i); } } @@ -15358,7 +15406,7 @@ public override byte[] ToBytes() int i = 0; Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); - bytes[i++] = (byte)ObjectData.Length; + Utils.ByteToBytes((byte)ObjectData.Length, bytes, ref i); for (int j = 0; j < ObjectData.Length; j++) { ObjectData[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -15509,21 +15557,21 @@ public override void FromBytes(byte[] bytes, ref int i) try { ObjectLocalID = Utils.BytesToUIntSafepos(bytes, i); i += 4; - PathCurve = (byte)bytes[i++]; - ProfileCurve = (byte)bytes[i++]; + PathCurve = Utils.BytesToByte(bytes, ref i); + ProfileCurve = Utils.BytesToByte(bytes, ref i); PathBegin = Utils.BytesToUInt16(bytes, i); i+=2; PathEnd = Utils.BytesToUInt16(bytes, i); i+=2; - PathScaleX = (byte)bytes[i++]; - PathScaleY = (byte)bytes[i++]; - PathShearX = (byte)bytes[i++]; - PathShearY = (byte)bytes[i++]; - PathTwist = (sbyte)bytes[i++]; - PathTwistBegin = (sbyte)bytes[i++]; - PathRadiusOffset = (sbyte)bytes[i++]; - PathTaperX = (sbyte)bytes[i++]; - PathTaperY = (sbyte)bytes[i++]; - PathRevolutions = (byte)bytes[i++]; - PathSkew = (sbyte)bytes[i++]; + PathScaleX = Utils.BytesToByte(bytes, ref i); + PathScaleY = Utils.BytesToByte(bytes, ref i); + PathShearX = Utils.BytesToByte(bytes, ref i); + PathShearY = Utils.BytesToByte(bytes, ref i); + PathTwist = (sbyte)Utils.BytesToByte(bytes, ref i); + PathTwistBegin = (sbyte)Utils.BytesToByte(bytes, ref i); + PathRadiusOffset = (sbyte)Utils.BytesToByte(bytes, ref i); + PathTaperX = (sbyte)Utils.BytesToByte(bytes, ref i); + PathTaperY = (sbyte)Utils.BytesToByte(bytes, ref i); + PathRevolutions = Utils.BytesToByte(bytes, ref i); + PathSkew = (sbyte)Utils.BytesToByte(bytes, ref i); ProfileBegin = Utils.BytesToUInt16(bytes, i); i+=2; ProfileEnd = Utils.BytesToUInt16(bytes, i); i+=2; ProfileHollow = Utils.BytesToUInt16(bytes, i); i+=2; @@ -15537,21 +15585,21 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { Utils.UIntToBytesSafepos(ObjectLocalID, bytes, i); i += 4; - bytes[i++] = PathCurve; - bytes[i++] = ProfileCurve; + Utils.ByteToBytes( PathCurve, bytes, ref i); + Utils.ByteToBytes( ProfileCurve, bytes, ref i); Utils.UInt16ToBytes(PathBegin, bytes, i); i += 2; Utils.UInt16ToBytes(PathEnd, bytes, i); i += 2; - bytes[i++] = PathScaleX; - bytes[i++] = PathScaleY; - bytes[i++] = PathShearX; - bytes[i++] = PathShearY; - bytes[i++] = (byte)PathTwist; - bytes[i++] = (byte)PathTwistBegin; - bytes[i++] = (byte)PathRadiusOffset; - bytes[i++] = (byte)PathTaperX; - bytes[i++] = (byte)PathTaperY; - bytes[i++] = PathRevolutions; - bytes[i++] = (byte)PathSkew; + Utils.ByteToBytes( PathScaleX, bytes, ref i); + Utils.ByteToBytes( PathScaleY, bytes, ref i); + Utils.ByteToBytes( PathShearX, bytes, ref i); + Utils.ByteToBytes( PathShearY, bytes, ref i); + Utils.ByteToBytes( (byte)PathTwist, bytes, ref i); + Utils.ByteToBytes( (byte)PathTwistBegin, bytes, ref i); + Utils.ByteToBytes( (byte)PathRadiusOffset, bytes, ref i); + Utils.ByteToBytes( (byte)PathTaperX, bytes, ref i); + Utils.ByteToBytes( (byte)PathTaperY, bytes, ref i); + Utils.ByteToBytes( PathRevolutions, bytes, ref i); + Utils.ByteToBytes( (byte)PathSkew, bytes, ref i); Utils.UInt16ToBytes(ProfileBegin, bytes, i); i += 2; Utils.UInt16ToBytes(ProfileEnd, bytes, i); i += 2; Utils.UInt16ToBytes(ProfileHollow, bytes, i); i += 2; @@ -15641,7 +15689,7 @@ public override byte[] ToBytes() int i = 0; Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); - bytes[i++] = (byte)ObjectData.Length; + Utils.ByteToBytes((byte)ObjectData.Length, bytes, ref i); for (int j = 0; j < ObjectData.Length; j++) { ObjectData[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -15782,9 +15830,9 @@ public override void FromBytes(byte[] bytes, ref int i) { ObjectLocalID = Utils.BytesToUIntSafepos(bytes, i); i += 4; ParamType = Utils.BytesToUInt16(bytes, i); i+=2; - ParamInUse = (bytes[i++] != 0) ? (bool)true : (bool)false; + ParamInUse = (Utils.BytesToByte(bytes, ref i) != 0); ParamSize = Utils.BytesToUIntSafepos(bytes, i); i += 4; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); ParamData = new byte[length]; Buffer.BlockCopy(bytes, i, ParamData, 0, length); i += length; } @@ -15798,9 +15846,9 @@ public override void ToBytes(byte[] bytes, ref int i) { Utils.UIntToBytesSafepos(ObjectLocalID, bytes, i); i += 4; Utils.UInt16ToBytes(ParamType, bytes, i); i += 2; - bytes[i++] = (byte)((ParamInUse) ? 1 : 0); + Utils.ByteToBytes((byte)((ParamInUse) ? 1 : 0), bytes, ref i); Utils.UIntToBytesSafepos(ParamSize, bytes, i); i += 4; - bytes[i++] = (byte)ParamData.Length; + Utils.ByteToBytes((byte)ParamData.Length, bytes, ref i); Buffer.BlockCopy(ParamData, 0, bytes, i, ParamData.Length); i += ParamData.Length; } @@ -15888,7 +15936,7 @@ public override byte[] ToBytes() int i = 0; Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); - bytes[i++] = (byte)ObjectData.Length; + Utils.ByteToBytes((byte)ObjectData.Length, bytes, ref i); for (int j = 0; j < ObjectData.Length; j++) { ObjectData[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -16022,7 +16070,7 @@ public override void FromBytes(byte[] bytes, ref int i) { try { - Override = (bytes[i++] != 0) ? (bool)true : (bool)false; + Override = (Utils.BytesToByte(bytes, ref i) != 0); OwnerID.FromBytes(bytes, i); i += 16; GroupID.FromBytes(bytes, i); i += 16; } @@ -16034,7 +16082,7 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { - bytes[i++] = (byte)((Override) ? 1 : 0); + Utils.ByteToBytes((byte)((Override) ? 1 : 0), bytes, ref i); OwnerID.ToBytes(bytes, i); i += 16; GroupID.ToBytes(bytes, i); i += 16; } @@ -16168,7 +16216,7 @@ public override byte[] ToBytes() Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); HeaderData.ToBytes(bytes, ref i); - bytes[i++] = (byte)ObjectData.Length; + Utils.ByteToBytes((byte)ObjectData.Length, bytes, ref i); for (int j = 0; j < ObjectData.Length; j++) { ObjectData[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -16402,7 +16450,7 @@ public override byte[] ToBytes() int i = 0; Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); - bytes[i++] = (byte)ObjectData.Length; + Utils.ByteToBytes((byte)ObjectData.Length, bytes, ref i); for (int j = 0; j < ObjectData.Length; j++) { ObjectData[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -16543,7 +16591,7 @@ public override void FromBytes(byte[] bytes, ref int i) try { ObjectLocalID = Utils.BytesToUIntSafepos(bytes, i); i += 4; - SaleType = (byte)bytes[i++]; + SaleType = Utils.BytesToByte(bytes, ref i); SalePrice = Utils.BytesToIntSafepos(bytes, i); i +=4; } catch (Exception) @@ -16555,7 +16603,7 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { Utils.UIntToBytesSafepos(ObjectLocalID, bytes, i); i += 4; - bytes[i++] = SaleType; + Utils.ByteToBytes( SaleType, bytes, ref i); Utils.IntToBytesSafepos(SalePrice, bytes, i); i += 4; } @@ -16643,7 +16691,7 @@ public override byte[] ToBytes() int i = 0; Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); - bytes[i++] = (byte)ObjectData.Length; + Utils.ByteToBytes((byte)ObjectData.Length, bytes, ref i); for (int j = 0; j < ObjectData.Length; j++) { ObjectData[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -16901,7 +16949,7 @@ public override void FromBytes(byte[] bytes, ref int i) try { ObjectID.FromBytes(bytes, i); i += 16; - Delete = (bytes[i++] != 0) ? (bool)true : (bool)false; + Delete = (Utils.BytesToByte(bytes, ref i) != 0); } catch (Exception) { @@ -16912,7 +16960,7 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { ObjectID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)((Delete) ? 1 : 0); + Utils.ByteToBytes((byte)((Delete) ? 1 : 0), bytes, ref i); } } @@ -17054,7 +17102,7 @@ public override void FromBytes(byte[] bytes, ref int i) { try { - Override = (bytes[i++] != 0) ? (bool)true : (bool)false; + Override = (Utils.BytesToByte(bytes, ref i) != 0); } catch (Exception) { @@ -17064,7 +17112,7 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { - bytes[i++] = (byte)((Override) ? 1 : 0); + Utils.ByteToBytes((byte)((Override) ? 1 : 0), bytes, ref i); } } @@ -17096,8 +17144,8 @@ public override void FromBytes(byte[] bytes, ref int i) try { ObjectLocalID = Utils.BytesToUIntSafepos(bytes, i); i += 4; - Field = (byte)bytes[i++]; - Set = (byte)bytes[i++]; + Field = Utils.BytesToByte(bytes, ref i); + Set = Utils.BytesToByte(bytes, ref i); Mask = Utils.BytesToUIntSafepos(bytes, i); i += 4; } catch (Exception) @@ -17109,8 +17157,8 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { Utils.UIntToBytesSafepos(ObjectLocalID, bytes, i); i += 4; - bytes[i++] = Field; - bytes[i++] = Set; + Utils.ByteToBytes( Field, bytes, ref i); + Utils.ByteToBytes( Set, bytes, ref i); Utils.UIntToBytesSafepos(Mask, bytes, i); i += 4; } @@ -17205,7 +17253,7 @@ public override byte[] ToBytes() Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); HeaderData.ToBytes(bytes, ref i); - bytes[i++] = (byte)ObjectData.Length; + Utils.ByteToBytes((byte)ObjectData.Length, bytes, ref i); for (int j = 0; j < ObjectData.Length; j++) { ObjectData[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -17342,7 +17390,7 @@ public override void FromBytes(byte[] bytes, ref int i) try { LocalID = Utils.BytesToUIntSafepos(bytes, i); i += 4; - SaleType = (byte)bytes[i++]; + SaleType = Utils.BytesToByte(bytes, ref i); SalePrice = Utils.BytesToIntSafepos(bytes, i); i +=4; } catch (Exception) @@ -17354,7 +17402,7 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { Utils.UIntToBytesSafepos(LocalID, bytes, i); i += 4; - bytes[i++] = SaleType; + Utils.ByteToBytes( SaleType, bytes, ref i); Utils.IntToBytesSafepos(SalePrice, bytes, i); i += 4; } @@ -17442,7 +17490,7 @@ public override byte[] ToBytes() int i = 0; Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); - bytes[i++] = (byte)ObjectData.Length; + Utils.ByteToBytes((byte)ObjectData.Length, bytes, ref i); for (int j = 0; j < ObjectData.Length; j++) { ObjectData[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -17579,7 +17627,7 @@ public override void FromBytes(byte[] bytes, ref int i) try { LocalID = Utils.BytesToUIntSafepos(bytes, i); i += 4; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Name = new byte[length]; Buffer.BlockCopy(bytes, i, Name, 0, length); i += length; } @@ -17592,7 +17640,7 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { Utils.UIntToBytesSafepos(LocalID, bytes, i); i += 4; - bytes[i++] = (byte)Name.Length; + Utils.ByteToBytes((byte)Name.Length, bytes, ref i); Buffer.BlockCopy(Name, 0, bytes, i, Name.Length); i += Name.Length; } @@ -17680,7 +17728,7 @@ public override byte[] ToBytes() int i = 0; Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); - bytes[i++] = (byte)ObjectData.Length; + Utils.ByteToBytes((byte)ObjectData.Length, bytes, ref i); for (int j = 0; j < ObjectData.Length; j++) { ObjectData[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -17817,7 +17865,7 @@ public override void FromBytes(byte[] bytes, ref int i) try { LocalID = Utils.BytesToUIntSafepos(bytes, i); i += 4; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Description = new byte[length]; Buffer.BlockCopy(bytes, i, Description, 0, length); i += length; } @@ -17830,7 +17878,7 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { Utils.UIntToBytesSafepos(LocalID, bytes, i); i += 4; - bytes[i++] = (byte)Description.Length; + Utils.ByteToBytes((byte)Description.Length, bytes, ref i); Buffer.BlockCopy(Description, 0, bytes, i, Description.Length); i += Description.Length; } @@ -17918,7 +17966,7 @@ public override byte[] ToBytes() int i = 0; Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); - bytes[i++] = (byte)ObjectData.Length; + Utils.ByteToBytes((byte)ObjectData.Length, bytes, ref i); for (int j = 0; j < ObjectData.Length; j++) { ObjectData[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -18150,7 +18198,7 @@ public override byte[] ToBytes() int i = 0; Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); - bytes[i++] = (byte)ObjectData.Length; + Utils.ByteToBytes((byte)ObjectData.Length, bytes, ref i); for (int j = 0; j < ObjectData.Length; j++) { ObjectData[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -18379,7 +18427,7 @@ public override byte[] ToBytes() int i = 0; Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); - bytes[i++] = (byte)ObjectData.Length; + Utils.ByteToBytes((byte)ObjectData.Length, bytes, ref i); for (int j = 0; j < ObjectData.Length; j++) { ObjectData[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -18608,7 +18656,7 @@ public override byte[] ToBytes() int i = 0; Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); - bytes[i++] = (byte)ObjectData.Length; + Utils.ByteToBytes((byte)ObjectData.Length, bytes, ref i); for (int j = 0; j < ObjectData.Length; j++) { ObjectData[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -18703,7 +18751,7 @@ public override void FromBytes(byte[] bytes, ref int i) { AgentID.FromBytes(bytes, i); i += 16; SessionID.FromBytes(bytes, i); i += 16; - AttachmentPoint = (byte)bytes[i++]; + AttachmentPoint = Utils.BytesToByte(bytes, ref i); } catch (Exception) { @@ -18715,7 +18763,7 @@ public override void ToBytes(byte[] bytes, ref int i) { AgentID.ToBytes(bytes, i); i += 16; SessionID.ToBytes(bytes, i); i += 16; - bytes[i++] = AttachmentPoint; + Utils.ByteToBytes( AttachmentPoint, bytes, ref i); } } @@ -18843,7 +18891,7 @@ public override byte[] ToBytes() int i = 0; Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); - bytes[i++] = (byte)ObjectData.Length; + Utils.ByteToBytes((byte)ObjectData.Length, bytes, ref i); for (int j = 0; j < ObjectData.Length; j++) { ObjectData[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -19071,7 +19119,7 @@ public override byte[] ToBytes() int i = 0; Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); - bytes[i++] = (byte)ObjectData.Length; + Utils.ByteToBytes((byte)ObjectData.Length, bytes, ref i); for (int j = 0; j < ObjectData.Length; j++) { ObjectData[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -19299,7 +19347,7 @@ public override byte[] ToBytes() int i = 0; Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); - bytes[i++] = (byte)ObjectData.Length; + Utils.ByteToBytes((byte)ObjectData.Length, bytes, ref i); for (int j = 0; j < ObjectData.Length; j++) { ObjectData[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -19527,7 +19575,7 @@ public override byte[] ToBytes() int i = 0; Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); - bytes[i++] = (byte)ObjectData.Length; + Utils.ByteToBytes((byte)ObjectData.Length, bytes, ref i); for (int j = 0; j < ObjectData.Length; j++) { ObjectData[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -19755,7 +19803,7 @@ public override byte[] ToBytes() int i = 0; Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); - bytes[i++] = (byte)ObjectData.Length; + Utils.ByteToBytes((byte)ObjectData.Length, bytes, ref i); for (int j = 0; j < ObjectData.Length; j++) { ObjectData[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -20047,7 +20095,7 @@ public override byte[] ToBytes() Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); ObjectData.ToBytes(bytes, ref i); - bytes[i++] = (byte)SurfaceInfo.Length; + Utils.ByteToBytes((byte)SurfaceInfo.Length, bytes, ref i); for (int j = 0; j < SurfaceInfo.Length; j++) { SurfaceInfo[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -20347,7 +20395,7 @@ public override byte[] ToBytes() Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); ObjectData.ToBytes(bytes, ref i); - bytes[i++] = (byte)SurfaceInfo.Length; + Utils.ByteToBytes((byte)SurfaceInfo.Length, bytes, ref i); for (int j = 0; j < SurfaceInfo.Length; j++) { SurfaceInfo[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -20637,7 +20685,7 @@ public override byte[] ToBytes() Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); ObjectData.ToBytes(bytes, ref i); - bytes[i++] = (byte)SurfaceInfo.Length; + Utils.ByteToBytes((byte)SurfaceInfo.Length, bytes, ref i); for (int j = 0; j < SurfaceInfo.Length; j++) { SurfaceInfo[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -21351,7 +21399,7 @@ public override byte[] ToBytes() int i = 0; Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); - bytes[i++] = (byte)ObjectData.Length; + Utils.ByteToBytes((byte)ObjectData.Length, bytes, ref i); for (int j = 0; j < ObjectData.Length; j++) { ObjectData[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -21486,8 +21534,8 @@ public override void FromBytes(byte[] bytes, ref int i) { try { - Action = (byte)bytes[i++]; - BrushSize = (byte)bytes[i++]; + Action = Utils.BytesToByte(bytes, ref i); + BrushSize = Utils.BytesToByte(bytes, ref i); Seconds = Utils.BytesToFloatSafepos(bytes, i); i += 4; Height = Utils.BytesToFloatSafepos(bytes, i); i += 4; } @@ -21499,8 +21547,8 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { - bytes[i++] = Action; - bytes[i++] = BrushSize; + Utils.ByteToBytes( Action, bytes, ref i); + Utils.ByteToBytes( BrushSize, bytes, ref i); Utils.FloatToBytesSafepos(Seconds, bytes, i); i += 4; Utils.FloatToBytesSafepos(Height, bytes, i); i += 4; } @@ -21706,9 +21754,9 @@ public override byte[] ToBytes() Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); ModifyBlock.ToBytes(bytes, ref i); - bytes[i++] = (byte)ParcelData.Length; + Utils.ByteToBytes((byte)ParcelData.Length, bytes, ref i); for (int j = 0; j < ParcelData.Length; j++) { ParcelData[j].ToBytes(bytes, ref i); } - bytes[i++] = (byte)ModifyBlockExtended.Length; + Utils.ByteToBytes((byte)ModifyBlockExtended.Length, bytes, ref i); for (int j = 0; j < ModifyBlockExtended.Length; j++) { ModifyBlockExtended[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -22089,7 +22137,7 @@ public override void FromBytes(byte[] bytes, ref int i) int length; try { - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Filename = new byte[length]; Buffer.BlockCopy(bytes, i, Filename, 0, length); i += length; } @@ -22101,7 +22149,7 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { - bytes[i++] = (byte)Filename.Length; + Utils.ByteToBytes((byte)Filename.Length, bytes, ref i); Buffer.BlockCopy(Filename, 0, bytes, i, Filename.Length); i += Filename.Length; } @@ -22667,18 +22715,18 @@ public override void FromBytes(byte[] bytes, ref int i) RunTime = Utils.BytesToFloatSafepos(bytes, i); i += 4; SimFPS = Utils.BytesToFloatSafepos(bytes, i); i += 4; FPS = Utils.BytesToFloatSafepos(bytes, i); i += 4; - AgentsInView = (byte)bytes[i++]; + AgentsInView = Utils.BytesToByte(bytes, ref i); Ping = Utils.BytesToFloatSafepos(bytes, i); i += 4; MetersTraveled = Utils.BytesToDoubleSafepos(bytes, i); i += 8; RegionsVisited = Utils.BytesToIntSafepos(bytes, i); i +=4; SysRAM = Utils.BytesToUIntSafepos(bytes, i); i += 4; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); SysOS = new byte[length]; Buffer.BlockCopy(bytes, i, SysOS, 0, length); i += length; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); SysCPU = new byte[length]; Buffer.BlockCopy(bytes, i, SysCPU, 0, length); i += length; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); SysGPU = new byte[length]; Buffer.BlockCopy(bytes, i, SysGPU, 0, length); i += length; } @@ -22697,16 +22745,16 @@ public override void ToBytes(byte[] bytes, ref int i) Utils.FloatToBytesSafepos(RunTime, bytes, i); i += 4; Utils.FloatToBytesSafepos(SimFPS, bytes, i); i += 4; Utils.FloatToBytesSafepos(FPS, bytes, i); i += 4; - bytes[i++] = AgentsInView; + Utils.ByteToBytes( AgentsInView, bytes, ref i); Utils.FloatToBytesSafepos(Ping, bytes, i); i += 4; Utils.DoubleToBytesSafepos(MetersTraveled, bytes, i); i += 8; Utils.IntToBytesSafepos(RegionsVisited, bytes, i); i += 4; Utils.UIntToBytesSafepos(SysRAM, bytes, i); i += 4; - bytes[i++] = (byte)SysOS.Length; + Utils.ByteToBytes((byte)SysOS.Length, bytes, ref i); Buffer.BlockCopy(SysOS, 0, bytes, i, SysOS.Length); i += SysOS.Length; - bytes[i++] = (byte)SysCPU.Length; + Utils.ByteToBytes((byte)SysCPU.Length, bytes, ref i); Buffer.BlockCopy(SysCPU, 0, bytes, i, SysCPU.Length); i += SysCPU.Length; - bytes[i++] = (byte)SysGPU.Length; + Utils.ByteToBytes((byte)SysGPU.Length, bytes, ref i); Buffer.BlockCopy(SysGPU, 0, bytes, i, SysGPU.Length); i += SysGPU.Length; } @@ -23013,7 +23061,7 @@ public override byte[] ToBytes() DownloadTotals.ToBytes(bytes, ref i); for (int j = 0; j < 2; j++) { NetStats[j].ToBytes(bytes, ref i); } FailStats.ToBytes(bytes, ref i); - bytes[i++] = (byte)MiscStats.Length; + Utils.ByteToBytes((byte)MiscStats.Length, bytes, ref i); for (int j = 0; j < MiscStats.Length; j++) { MiscStats[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -23332,24 +23380,24 @@ public override void FromBytes(byte[] bytes, ref int i) int length; try { - ReportType = (byte)bytes[i++]; - Category = (byte)bytes[i++]; + ReportType = Utils.BytesToByte(bytes, ref i); + Category = Utils.BytesToByte(bytes, ref i); Position.FromBytes(bytes, i); i += 12; - CheckFlags = (byte)bytes[i++]; + CheckFlags = Utils.BytesToByte(bytes, ref i); ScreenshotID.FromBytes(bytes, i); i += 16; ObjectID.FromBytes(bytes, i); i += 16; AbuserID.FromBytes(bytes, i); i += 16; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); AbuseRegionName = new byte[length]; Buffer.BlockCopy(bytes, i, AbuseRegionName, 0, length); i += length; AbuseRegionID.FromBytes(bytes, i); i += 16; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Summary = new byte[length]; Buffer.BlockCopy(bytes, i, Summary, 0, length); i += length; - length = (bytes[i++] + (bytes[i++] << 8)); + length = Utils.BytesToUInt16(bytes, i); i+=2; Details = new byte[length]; Buffer.BlockCopy(bytes, i, Details, 0, length); i += length; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); VersionString = new byte[length]; Buffer.BlockCopy(bytes, i, VersionString, 0, length); i += length; } @@ -23361,22 +23409,21 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { - bytes[i++] = ReportType; - bytes[i++] = Category; + Utils.ByteToBytes( ReportType, bytes, ref i); + Utils.ByteToBytes( Category, bytes, ref i); Position.ToBytes(bytes, i); i += 12; - bytes[i++] = CheckFlags; + Utils.ByteToBytes( CheckFlags, bytes, ref i); ScreenshotID.ToBytes(bytes, i); i += 16; ObjectID.ToBytes(bytes, i); i += 16; AbuserID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)AbuseRegionName.Length; + Utils.ByteToBytes((byte)AbuseRegionName.Length, bytes, ref i); Buffer.BlockCopy(AbuseRegionName, 0, bytes, i, AbuseRegionName.Length); i += AbuseRegionName.Length; AbuseRegionID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)Summary.Length; + Utils.ByteToBytes((byte)Summary.Length, bytes, ref i); Buffer.BlockCopy(Summary, 0, bytes, i, Summary.Length); i += Summary.Length; - bytes[i++] = (byte)(Details.Length % 256); - bytes[i++] = (byte)((Details.Length >> 8) % 256); + Utils.UInt16ToBytes((ushort)Details.Length, bytes, i); i += 2; Buffer.BlockCopy(Details, 0, bytes, i, Details.Length); i += Details.Length; - bytes[i++] = (byte)VersionString.Length; + Utils.ByteToBytes((byte)VersionString.Length, bytes, ref i); Buffer.BlockCopy(VersionString, 0, bytes, i, VersionString.Length); i += VersionString.Length; } @@ -23488,7 +23535,7 @@ public override void FromBytes(byte[] bytes, ref int i) int length; try { - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Message = new byte[length]; Buffer.BlockCopy(bytes, i, Message, 0, length); i += length; } @@ -23500,7 +23547,7 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { - bytes[i++] = (byte)Message.Length; + Utils.ByteToBytes((byte)Message.Length, bytes, ref i); Buffer.BlockCopy(Message, 0, bytes, i, Message.Length); i += Message.Length; } @@ -23534,10 +23581,10 @@ public override void FromBytes(byte[] bytes, ref int i) int length; try { - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Message = new byte[length]; Buffer.BlockCopy(bytes, i, Message, 0, length); i += length; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); ExtraParams = new byte[length]; Buffer.BlockCopy(bytes, i, ExtraParams, 0, length); i += length; } @@ -23549,9 +23596,9 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { - bytes[i++] = (byte)Message.Length; + Utils.ByteToBytes((byte)Message.Length, bytes, ref i); Buffer.BlockCopy(Message, 0, bytes, i, Message.Length); i += Message.Length; - bytes[i++] = (byte)ExtraParams.Length; + Utils.ByteToBytes((byte)ExtraParams.Length, bytes, ref i); Buffer.BlockCopy(ExtraParams, 0, bytes, i, ExtraParams.Length); i += ExtraParams.Length; } @@ -23638,7 +23685,7 @@ public override byte[] ToBytes() int i = 0; Header.ToBytes(bytes, ref i); AlertData.ToBytes(bytes, ref i); - bytes[i++] = (byte)AlertInfo.Length; + Utils.ByteToBytes((byte)AlertInfo.Length, bytes, ref i); for (int j = 0; j < AlertInfo.Length; j++) { AlertInfo[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -23771,8 +23818,8 @@ public override void FromBytes(byte[] bytes, ref int i) int length; try { - Modal = (bytes[i++] != 0) ? (bool)true : (bool)false; - length = bytes[i++]; + Modal = (Utils.BytesToByte(bytes, ref i) != 0); + length = Utils.BytesToByte(bytes, ref i); Message = new byte[length]; Buffer.BlockCopy(bytes, i, Message, 0, length); i += length; } @@ -23784,8 +23831,8 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { - bytes[i++] = (byte)((Modal) ? 1 : 0); - bytes[i++] = (byte)Message.Length; + Utils.ByteToBytes((byte)((Modal) ? 1 : 0), bytes, ref i); + Utils.ByteToBytes((byte)Message.Length, bytes, ref i); Buffer.BlockCopy(Message, 0, bytes, i, Message.Length); i += Message.Length; } @@ -23901,7 +23948,7 @@ public override void FromBytes(byte[] bytes, ref int i) Perp.FromBytes(bytes, i); i += 16; Time = Utils.BytesToUIntSafepos(bytes, i); i += 4; Mag = Utils.BytesToFloatSafepos(bytes, i); i += 4; - Type = (byte)bytes[i++]; + Type = Utils.BytesToByte(bytes, ref i); } catch (Exception) { @@ -23915,7 +23962,7 @@ public override void ToBytes(byte[] bytes, ref int i) Perp.ToBytes(bytes, i); i += 16; Utils.UIntToBytesSafepos(Time, bytes, i); i += 4; Utils.FloatToBytesSafepos(Mag, bytes, i); i += 4; - bytes[i++] = Type; + Utils.ByteToBytes( Type, bytes, ref i); } } @@ -23995,7 +24042,7 @@ public override byte[] ToBytes() byte[] bytes = new byte[length]; int i = 0; Header.ToBytes(bytes, ref i); - bytes[i++] = (byte)MeanCollision.Length; + Utils.ByteToBytes((byte)MeanCollision.Length, bytes, ref i); for (int j = 0; j < MeanCollision.Length; j++) { MeanCollision[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -24084,7 +24131,7 @@ public override void FromBytes(byte[] bytes, ref int i) { try { - Data = (bytes[i++] != 0) ? (bool)true : (bool)false; + Data = (Utils.BytesToByte(bytes, ref i) != 0); } catch (Exception) { @@ -24094,7 +24141,7 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { - bytes[i++] = (byte)((Data) ? 1 : 0); + Utils.ByteToBytes((byte)((Data) ? 1 : 0), bytes, ref i); } } @@ -24316,16 +24363,16 @@ public override void FromBytes(byte[] bytes, ref int i) int length; try { - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); FromName = new byte[length]; Buffer.BlockCopy(bytes, i, FromName, 0, length); i += length; SourceID.FromBytes(bytes, i); i += 16; OwnerID.FromBytes(bytes, i); i += 16; - SourceType = (byte)bytes[i++]; - ChatType = (byte)bytes[i++]; - Audible = (byte)bytes[i++]; + SourceType = Utils.BytesToByte(bytes, ref i); + ChatType = Utils.BytesToByte(bytes, ref i); + Audible = Utils.BytesToByte(bytes, ref i); Position.FromBytes(bytes, i); i += 12; - length = (bytes[i++] + (bytes[i++] << 8)); + length = Utils.BytesToUInt16(bytes, i); i+=2; Message = new byte[length]; Buffer.BlockCopy(bytes, i, Message, 0, length); i += length; } @@ -24337,16 +24384,15 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { - bytes[i++] = (byte)FromName.Length; + Utils.ByteToBytes((byte)FromName.Length, bytes, ref i); Buffer.BlockCopy(FromName, 0, bytes, i, FromName.Length); i += FromName.Length; SourceID.ToBytes(bytes, i); i += 16; OwnerID.ToBytes(bytes, i); i += 16; - bytes[i++] = SourceType; - bytes[i++] = ChatType; - bytes[i++] = Audible; + Utils.ByteToBytes( SourceType, bytes, ref i); + Utils.ByteToBytes( ChatType, bytes, ref i); + Utils.ByteToBytes( Audible, bytes, ref i); Position.ToBytes(bytes, i); i += 12; - bytes[i++] = (byte)(Message.Length % 256); - bytes[i++] = (byte)((Message.Length >> 8) % 256); + Utils.UInt16ToBytes((ushort)Message.Length, bytes, i); i += 2; Buffer.BlockCopy(Message, 0, bytes, i, Message.Length); i += Message.Length; } @@ -24697,10 +24743,10 @@ public override byte[] ToBytes() int i = 0; Header.ToBytes(bytes, ref i); Region.ToBytes(bytes, ref i); - bytes[i++] = (byte)Stat.Length; + Utils.ByteToBytes((byte)Stat.Length, bytes, ref i); for (int j = 0; j < Stat.Length; j++) { Stat[j].ToBytes(bytes, ref i); } PidStat.ToBytes(bytes, ref i); - bytes[i++] = (byte)RegionInfo.Length; + Utils.ByteToBytes((byte)RegionInfo.Length, bytes, ref i); for (int j = 0; j < RegionInfo.Length; j++) { RegionInfo[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -24910,14 +24956,14 @@ public override void FromBytes(byte[] bytes, ref int i) int length; try { - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); SimName = new byte[length]; Buffer.BlockCopy(bytes, i, SimName, 0, length); i += length; EstateID = Utils.BytesToUIntSafepos(bytes, i); i += 4; ParentEstateID = Utils.BytesToUIntSafepos(bytes, i); i += 4; RegionFlags = Utils.BytesToUIntSafepos(bytes, i); i += 4; - SimAccess = (byte)bytes[i++]; - MaxAgents = (byte)bytes[i++]; + SimAccess = Utils.BytesToByte(bytes, ref i); + MaxAgents = Utils.BytesToByte(bytes, ref i); BillableFactor = Utils.BytesToFloatSafepos(bytes, i); i += 4; ObjectBonusFactor = Utils.BytesToFloatSafepos(bytes, i); i += 4; WaterHeight = Utils.BytesToFloatSafepos(bytes, i); i += 4; @@ -24926,7 +24972,7 @@ public override void FromBytes(byte[] bytes, ref int i) PricePerMeter = Utils.BytesToIntSafepos(bytes, i); i +=4; RedirectGridX = Utils.BytesToIntSafepos(bytes, i); i +=4; RedirectGridY = Utils.BytesToIntSafepos(bytes, i); i +=4; - UseEstateSun = (bytes[i++] != 0) ? (bool)true : (bool)false; + UseEstateSun = (Utils.BytesToByte(bytes, ref i) != 0); SunHour = Utils.BytesToFloatSafepos(bytes, i); i += 4; } catch (Exception) @@ -24937,13 +24983,13 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { - bytes[i++] = (byte)SimName.Length; + Utils.ByteToBytes((byte)SimName.Length, bytes, ref i); Buffer.BlockCopy(SimName, 0, bytes, i, SimName.Length); i += SimName.Length; Utils.UIntToBytesSafepos(EstateID, bytes, i); i += 4; Utils.UIntToBytesSafepos(ParentEstateID, bytes, i); i += 4; Utils.UIntToBytesSafepos(RegionFlags, bytes, i); i += 4; - bytes[i++] = SimAccess; - bytes[i++] = MaxAgents; + Utils.ByteToBytes( SimAccess, bytes, ref i); + Utils.ByteToBytes( MaxAgents, bytes, ref i); Utils.FloatToBytesSafepos(BillableFactor, bytes, i); i += 4; Utils.FloatToBytesSafepos(ObjectBonusFactor, bytes, i); i += 4; Utils.FloatToBytesSafepos(WaterHeight, bytes, i); i += 4; @@ -24952,7 +24998,7 @@ public override void ToBytes(byte[] bytes, ref int i) Utils.IntToBytesSafepos(PricePerMeter, bytes, i); i += 4; Utils.IntToBytesSafepos(RedirectGridX, bytes, i); i += 4; Utils.IntToBytesSafepos(RedirectGridY, bytes, i); i += 4; - bytes[i++] = (byte)((UseEstateSun) ? 1 : 0); + Utils.ByteToBytes((byte)((UseEstateSun) ? 1 : 0), bytes, ref i); Utils.FloatToBytesSafepos(SunHour, bytes, i); i += 4; } @@ -24989,10 +25035,10 @@ public override void FromBytes(byte[] bytes, ref int i) int length; try { - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); ProductSKU = new byte[length]; Buffer.BlockCopy(bytes, i, ProductSKU, 0, length); i += length; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); ProductName = new byte[length]; Buffer.BlockCopy(bytes, i, ProductName, 0, length); i += length; MaxAgents32 = Utils.BytesToUIntSafepos(bytes, i); i += 4; @@ -25007,9 +25053,9 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { - bytes[i++] = (byte)ProductSKU.Length; + Utils.ByteToBytes((byte)ProductSKU.Length, bytes, ref i); Buffer.BlockCopy(ProductSKU, 0, bytes, i, ProductSKU.Length); i += ProductSKU.Length; - bytes[i++] = (byte)ProductName.Length; + Utils.ByteToBytes((byte)ProductName.Length, bytes, ref i); Buffer.BlockCopy(ProductName, 0, bytes, i, ProductName.Length); i += ProductName.Length; Utils.UIntToBytesSafepos(MaxAgents32, bytes, i); i += 4; Utils.UIntToBytesSafepos(HardMaxAgents, bytes, i); i += 4; @@ -25152,7 +25198,7 @@ public override byte[] ToBytes() AgentData.ToBytes(bytes, ref i); RegionInfo.ToBytes(bytes, ref i); RegionInfo2.ToBytes(bytes, ref i); - bytes[i++] = (byte)RegionInfo3.Length; + Utils.ByteToBytes((byte)RegionInfo3.Length, bytes, ref i); for (int j = 0; j < RegionInfo3.Length; j++) { RegionInfo3[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -25298,7 +25344,7 @@ public override void FromBytes(byte[] bytes, ref int i) int length; try { - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); SimName = new byte[length]; Buffer.BlockCopy(bytes, i, SimName, 0, length); i += length; EstateID = Utils.BytesToUIntSafepos(bytes, i); i += 4; @@ -25317,7 +25363,7 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { - bytes[i++] = (byte)SimName.Length; + Utils.ByteToBytes((byte)SimName.Length, bytes, ref i); Buffer.BlockCopy(SimName, 0, bytes, i, SimName.Length); i += SimName.Length; Utils.UIntToBytesSafepos(EstateID, bytes, i); i += 4; Utils.UIntToBytesSafepos(ParentEstateID, bytes, i); i += 4; @@ -25457,7 +25503,7 @@ public override byte[] ToBytes() Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); RegionInfo.ToBytes(bytes, ref i); - bytes[i++] = (byte)RegionInfo2.Length; + Utils.ByteToBytes((byte)RegionInfo2.Length, bytes, ref i); for (int j = 0; j < RegionInfo2.Length; j++) { RegionInfo2[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -25577,12 +25623,12 @@ public override void FromBytes(byte[] bytes, ref int i) try { RegionFlags = Utils.BytesToUIntSafepos(bytes, i); i += 4; - SimAccess = (byte)bytes[i++]; - length = bytes[i++]; + SimAccess = Utils.BytesToByte(bytes, ref i); + length = Utils.BytesToByte(bytes, ref i); SimName = new byte[length]; Buffer.BlockCopy(bytes, i, SimName, 0, length); i += length; SimOwner.FromBytes(bytes, i); i += 16; - IsEstateManager = (bytes[i++] != 0) ? (bool)true : (bool)false; + IsEstateManager = (Utils.BytesToByte(bytes, ref i) != 0); WaterHeight = Utils.BytesToFloatSafepos(bytes, i); i += 4; BillableFactor = Utils.BytesToFloatSafepos(bytes, i); i += 4; CacheID.FromBytes(bytes, i); i += 16; @@ -25612,11 +25658,11 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { Utils.UIntToBytesSafepos(RegionFlags, bytes, i); i += 4; - bytes[i++] = SimAccess; - bytes[i++] = (byte)SimName.Length; + Utils.ByteToBytes( SimAccess, bytes, ref i); + Utils.ByteToBytes((byte)SimName.Length, bytes, ref i); Buffer.BlockCopy(SimName, 0, bytes, i, SimName.Length); i += SimName.Length; SimOwner.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)((IsEstateManager) ? 1 : 0); + Utils.ByteToBytes((byte)((IsEstateManager) ? 1 : 0), bytes, ref i); Utils.FloatToBytesSafepos(WaterHeight, bytes, i); i += 4; Utils.FloatToBytesSafepos(BillableFactor, bytes, i); i += 4; CacheID.ToBytes(bytes, i); i += 16; @@ -25712,13 +25758,13 @@ public override void FromBytes(byte[] bytes, ref int i) { CPUClassID = Utils.BytesToIntSafepos(bytes, i); i +=4; CPURatio = Utils.BytesToIntSafepos(bytes, i); i +=4; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); ColoName = new byte[length]; Buffer.BlockCopy(bytes, i, ColoName, 0, length); i += length; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); ProductSKU = new byte[length]; Buffer.BlockCopy(bytes, i, ProductSKU, 0, length); i += length; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); ProductName = new byte[length]; Buffer.BlockCopy(bytes, i, ProductName, 0, length); i += length; } @@ -25732,11 +25778,11 @@ public override void ToBytes(byte[] bytes, ref int i) { Utils.IntToBytesSafepos(CPUClassID, bytes, i); i += 4; Utils.IntToBytesSafepos(CPURatio, bytes, i); i += 4; - bytes[i++] = (byte)ColoName.Length; + Utils.ByteToBytes((byte)ColoName.Length, bytes, ref i); Buffer.BlockCopy(ColoName, 0, bytes, i, ColoName.Length); i += ColoName.Length; - bytes[i++] = (byte)ProductSKU.Length; + Utils.ByteToBytes((byte)ProductSKU.Length, bytes, ref i); Buffer.BlockCopy(ProductSKU, 0, bytes, i, ProductSKU.Length); i += ProductSKU.Length; - bytes[i++] = (byte)ProductName.Length; + Utils.ByteToBytes((byte)ProductName.Length, bytes, ref i); Buffer.BlockCopy(ProductName, 0, bytes, i, ProductName.Length); i += ProductName.Length; } @@ -25879,7 +25925,7 @@ public override byte[] ToBytes() RegionInfo.ToBytes(bytes, ref i); RegionInfo2.ToBytes(bytes, ref i); RegionInfo3.ToBytes(bytes, ref i); - bytes[i++] = (byte)RegionInfo4.Length; + Utils.ByteToBytes((byte)RegionInfo4.Length, bytes, ref i); for (int j = 0; j < RegionInfo4.Length; j++) { RegionInfo4[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -26274,8 +26320,7 @@ public override void ToBytes(byte[] bytes, ref int i) { Utils.UInt64ToBytesSafepos(Handle, bytes, i); i += 8; Utils.UIntToBytesSafepos(IP, bytes, i); i += 4; - bytes[i++] = (byte)((Port >> 8) % 256); - bytes[i++] = (byte)(Port % 256); + Utils.UInt16ToBytesBig(Port, bytes, i); i += 2; } } @@ -26451,7 +26496,7 @@ public override void FromBytes(byte[] bytes, ref int i) ChannelType = Utils.BytesToIntSafepos(bytes, i); i +=4; SourceType = Utils.BytesToIntSafepos(bytes, i); i +=4; Priority = Utils.BytesToFloatSafepos(bytes, i); i += 4; - length = (bytes[i++] + (bytes[i++] << 8)); + length = Utils.BytesToUInt16(bytes, i); i+=2; Params = new byte[length]; Buffer.BlockCopy(bytes, i, Params, 0, length); i += length; } @@ -26467,8 +26512,7 @@ public override void ToBytes(byte[] bytes, ref int i) Utils.IntToBytesSafepos(ChannelType, bytes, i); i += 4; Utils.IntToBytesSafepos(SourceType, bytes, i); i += 4; Utils.FloatToBytesSafepos(Priority, bytes, i); i += 4; - bytes[i++] = (byte)(Params.Length % 256); - bytes[i++] = (byte)((Params.Length >> 8) % 256); + Utils.UInt16ToBytes((ushort)Params.Length, bytes, i); i += 2; Buffer.BlockCopy(Params, 0, bytes, i, Params.Length); i += Params.Length; } @@ -26583,7 +26627,7 @@ public override void FromBytes(byte[] bytes, ref int i) TargetType = Utils.BytesToIntSafepos(bytes, i); i +=4; Status = Utils.BytesToIntSafepos(bytes, i); i +=4; Size = Utils.BytesToIntSafepos(bytes, i); i +=4; - length = (bytes[i++] + (bytes[i++] << 8)); + length = Utils.BytesToUInt16(bytes, i); i+=2; Params = new byte[length]; Buffer.BlockCopy(bytes, i, Params, 0, length); i += length; } @@ -26600,8 +26644,7 @@ public override void ToBytes(byte[] bytes, ref int i) Utils.IntToBytesSafepos(TargetType, bytes, i); i += 4; Utils.IntToBytesSafepos(Status, bytes, i); i += 4; Utils.IntToBytesSafepos(Size, bytes, i); i += 4; - bytes[i++] = (byte)(Params.Length % 256); - bytes[i++] = (byte)((Params.Length >> 8) % 256); + Utils.UInt16ToBytes((ushort)Params.Length, bytes, i); i += 2; Buffer.BlockCopy(Params, 0, bytes, i, Params.Length); i += Params.Length; } @@ -26827,12 +26870,12 @@ public override void FromBytes(byte[] bytes, ref int i) try { ID = Utils.BytesToUInt64Safepos(bytes, i); i += 8; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Filename = new byte[length]; Buffer.BlockCopy(bytes, i, Filename, 0, length); i += length; - FilePath = (byte)bytes[i++]; - DeleteOnCompletion = (bytes[i++] != 0) ? (bool)true : (bool)false; - UseBigPackets = (bytes[i++] != 0) ? (bool)true : (bool)false; + FilePath = Utils.BytesToByte(bytes, ref i); + DeleteOnCompletion = (Utils.BytesToByte(bytes, ref i) != 0); + UseBigPackets = (Utils.BytesToByte(bytes, ref i) != 0); VFileID.FromBytes(bytes, i); i += 16; VFileType = Utils.BytesToInt16(bytes, i); i+=2; } @@ -26845,11 +26888,11 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { Utils.UInt64ToBytesSafepos(ID, bytes, i); i += 8; - bytes[i++] = (byte)Filename.Length; + Utils.ByteToBytes((byte)Filename.Length, bytes, ref i); Buffer.BlockCopy(Filename, 0, bytes, i, Filename.Length); i += Filename.Length; - bytes[i++] = FilePath; - bytes[i++] = (byte)((DeleteOnCompletion) ? 1 : 0); - bytes[i++] = (byte)((UseBigPackets) ? 1 : 0); + Utils.ByteToBytes( FilePath, bytes, ref i); + Utils.ByteToBytes((byte)((DeleteOnCompletion) ? 1 : 0), bytes, ref i); + Utils.ByteToBytes((byte)((UseBigPackets) ? 1 : 0), bytes, ref i); VFileID.ToBytes(bytes, i); i += 16; Utils.Int16ToBytes(VFileType, bytes, i); i += 2; } @@ -27067,7 +27110,7 @@ public override void FromBytes(byte[] bytes, ref int i) try { ID.FromBytes(bytes, i); i += 16; - IsTrial = (bytes[i++] != 0) ? (bool)true : (bool)false; + IsTrial = (Utils.BytesToByte(bytes, ref i) != 0); } catch (Exception) { @@ -27078,7 +27121,7 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { ID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)((IsTrial) ? 1 : 0); + Utils.ByteToBytes((byte)((IsTrial) ? 1 : 0), bytes, ref i); } } @@ -27109,7 +27152,7 @@ public override void FromBytes(byte[] bytes, ref int i) int length; try { - length = (bytes[i++] + (bytes[i++] << 8)); + length = Utils.BytesToUInt16(bytes, i); i+=2; TextureEntry = new byte[length]; Buffer.BlockCopy(bytes, i, TextureEntry, 0, length); i += length; } @@ -27121,8 +27164,7 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { - bytes[i++] = (byte)(TextureEntry.Length % 256); - bytes[i++] = (byte)((TextureEntry.Length >> 8) % 256); + Utils.UInt16ToBytes((ushort)TextureEntry.Length, bytes, i); i += 2; Buffer.BlockCopy(TextureEntry, 0, bytes, i, TextureEntry.Length); i += TextureEntry.Length; } @@ -27151,7 +27193,7 @@ public override void FromBytes(byte[] bytes, ref int i) { try { - ParamValue = (byte)bytes[i++]; + ParamValue = Utils.BytesToByte(bytes, ref i); } catch (Exception) { @@ -27161,7 +27203,7 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { - bytes[i++] = ParamValue; + Utils.ByteToBytes( ParamValue, bytes, ref i); } } @@ -27191,7 +27233,7 @@ public override void FromBytes(byte[] bytes, ref int i) { try { - AppearanceVersion = (byte)bytes[i++]; + AppearanceVersion = Utils.BytesToByte(bytes, ref i); CofVersion = Utils.BytesToIntSafepos(bytes, i); i +=4; Flags = Utils.BytesToUIntSafepos(bytes, i); i += 4; } @@ -27203,7 +27245,7 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { - bytes[i++] = AppearanceVersion; + Utils.ByteToBytes( AppearanceVersion, bytes, ref i); Utils.IntToBytesSafepos(CofVersion, bytes, i); i += 4; Utils.UIntToBytesSafepos(Flags, bytes, i); i += 4; } @@ -27381,11 +27423,11 @@ public override byte[] ToBytes() Header.ToBytes(bytes, ref i); Sender.ToBytes(bytes, ref i); ObjectData.ToBytes(bytes, ref i); - bytes[i++] = (byte)VisualParam.Length; + Utils.ByteToBytes((byte)VisualParam.Length, bytes, ref i); for (int j = 0; j < VisualParam.Length; j++) { VisualParam[j].ToBytes(bytes, ref i); } - bytes[i++] = (byte)AppearanceData.Length; + Utils.ByteToBytes((byte)AppearanceData.Length, bytes, ref i); for (int j = 0; j < AppearanceData.Length; j++) { AppearanceData[j].ToBytes(bytes, ref i); } - bytes[i++] = (byte)AppearanceHover.Length; + Utils.ByteToBytes((byte)AppearanceHover.Length, bytes, ref i); for (int j = 0; j < AppearanceHover.Length; j++) { AppearanceHover[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -27651,7 +27693,7 @@ public override byte[] ToBytes() int i = 0; Header.ToBytes(bytes, ref i); ObjectData.ToBytes(bytes, ref i); - bytes[i++] = (byte)CameraProperty.Length; + Utils.ByteToBytes((byte)CameraProperty.Length, bytes, ref i); for (int j = 0; j < CameraProperty.Length; j++) { CameraProperty[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -28099,7 +28141,7 @@ public override byte[] ToBytes() int i = 0; Header.ToBytes(bytes, ref i); ObjectData.ToBytes(bytes, ref i); - bytes[i++] = (byte)ButtonData.Length; + Utils.ByteToBytes((byte)ButtonData.Length, bytes, ref i); for (int j = 0; j < ButtonData.Length; j++) { ButtonData[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -28203,8 +28245,7 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { Utils.UIntToBytesSafepos(TargetIP, bytes, i); i += 4; - bytes[i++] = (byte)((TargetPort >> 8) % 256); - bytes[i++] = (byte)(TargetPort % 256); + Utils.UInt16ToBytesBig(TargetPort, bytes, i); i += 2; } } @@ -28239,7 +28280,7 @@ public override void FromBytes(byte[] bytes, ref int i) { AgentID.FromBytes(bytes, i); i += 16; SessionID.FromBytes(bytes, i); i += 16; - length = (bytes[i++] + (bytes[i++] << 8)); + length = Utils.BytesToUInt16(bytes, i); i+=2; Reason = new byte[length]; Buffer.BlockCopy(bytes, i, Reason, 0, length); i += length; } @@ -28253,8 +28294,7 @@ public override void ToBytes(byte[] bytes, ref int i) { AgentID.ToBytes(bytes, i); i += 16; SessionID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)(Reason.Length % 256); - bytes[i++] = (byte)((Reason.Length >> 8) % 256); + Utils.UInt16ToBytes((ushort)Reason.Length, bytes, i); i += 2; Buffer.BlockCopy(Reason, 0, bytes, i, Reason.Length); i += Reason.Length; } @@ -28373,7 +28413,7 @@ public override void FromBytes(byte[] bytes, ref int i) GodSessionID.FromBytes(bytes, i); i += 16; AgentID.FromBytes(bytes, i); i += 16; KickFlags = Utils.BytesToUIntSafepos(bytes, i); i += 4; - length = (bytes[i++] + (bytes[i++] << 8)); + length = Utils.BytesToUInt16(bytes, i); i+=2; Reason = new byte[length]; Buffer.BlockCopy(bytes, i, Reason, 0, length); i += length; } @@ -28389,8 +28429,7 @@ public override void ToBytes(byte[] bytes, ref int i) GodSessionID.ToBytes(bytes, i); i += 16; AgentID.ToBytes(bytes, i); i += 16; Utils.UIntToBytesSafepos(KickFlags, bytes, i); i += 4; - bytes[i++] = (byte)(Reason.Length % 256); - bytes[i++] = (byte)((Reason.Length >> 8) % 256); + Utils.UInt16ToBytes((ushort)Reason.Length, bytes, i); i += 2; Buffer.BlockCopy(Reason, 0, bytes, i, Reason.Length); i += Reason.Length; } @@ -28988,19 +29027,19 @@ public override void FromBytes(byte[] bytes, ref int i) ImageID.FromBytes(bytes, i); i += 16; FLImageID.FromBytes(bytes, i); i += 16; PartnerID.FromBytes(bytes, i); i += 16; - length = (bytes[i++] + (bytes[i++] << 8)); + length = Utils.BytesToUInt16(bytes, i); i+=2; AboutText = new byte[length]; Buffer.BlockCopy(bytes, i, AboutText, 0, length); i += length; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); FLAboutText = new byte[length]; Buffer.BlockCopy(bytes, i, FLAboutText, 0, length); i += length; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); BornOn = new byte[length]; Buffer.BlockCopy(bytes, i, BornOn, 0, length); i += length; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); ProfileURL = new byte[length]; Buffer.BlockCopy(bytes, i, ProfileURL, 0, length); i += length; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); CharterMember = new byte[length]; Buffer.BlockCopy(bytes, i, CharterMember, 0, length); i += length; Flags = Utils.BytesToUIntSafepos(bytes, i); i += 4; @@ -29016,16 +29055,15 @@ public override void ToBytes(byte[] bytes, ref int i) ImageID.ToBytes(bytes, i); i += 16; FLImageID.ToBytes(bytes, i); i += 16; PartnerID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)(AboutText.Length % 256); - bytes[i++] = (byte)((AboutText.Length >> 8) % 256); + Utils.UInt16ToBytes((ushort)AboutText.Length, bytes, i); i += 2; Buffer.BlockCopy(AboutText, 0, bytes, i, AboutText.Length); i += AboutText.Length; - bytes[i++] = (byte)FLAboutText.Length; + Utils.ByteToBytes((byte)FLAboutText.Length, bytes, ref i); Buffer.BlockCopy(FLAboutText, 0, bytes, i, FLAboutText.Length); i += FLAboutText.Length; - bytes[i++] = (byte)BornOn.Length; + Utils.ByteToBytes((byte)BornOn.Length, bytes, ref i); Buffer.BlockCopy(BornOn, 0, bytes, i, BornOn.Length); i += BornOn.Length; - bytes[i++] = (byte)ProfileURL.Length; + Utils.ByteToBytes((byte)ProfileURL.Length, bytes, ref i); Buffer.BlockCopy(ProfileURL, 0, bytes, i, ProfileURL.Length); i += ProfileURL.Length; - bytes[i++] = (byte)CharterMember.Length; + Utils.ByteToBytes((byte)CharterMember.Length, bytes, ref i); Buffer.BlockCopy(CharterMember, 0, bytes, i, CharterMember.Length); i += CharterMember.Length; Utils.UIntToBytesSafepos(Flags, bytes, i); i += 4; } @@ -29186,14 +29224,14 @@ public override void FromBytes(byte[] bytes, ref int i) try { WantToMask = Utils.BytesToUIntSafepos(bytes, i); i += 4; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); WantToText = new byte[length]; Buffer.BlockCopy(bytes, i, WantToText, 0, length); i += length; SkillsMask = Utils.BytesToUIntSafepos(bytes, i); i += 4; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); SkillsText = new byte[length]; Buffer.BlockCopy(bytes, i, SkillsText, 0, length); i += length; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); LanguagesText = new byte[length]; Buffer.BlockCopy(bytes, i, LanguagesText, 0, length); i += length; } @@ -29206,12 +29244,12 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { Utils.UIntToBytesSafepos(WantToMask, bytes, i); i += 4; - bytes[i++] = (byte)WantToText.Length; + Utils.ByteToBytes((byte)WantToText.Length, bytes, ref i); Buffer.BlockCopy(WantToText, 0, bytes, i, WantToText.Length); i += WantToText.Length; Utils.UIntToBytesSafepos(SkillsMask, bytes, i); i += 4; - bytes[i++] = (byte)SkillsText.Length; + Utils.ByteToBytes((byte)SkillsText.Length, bytes, ref i); Buffer.BlockCopy(SkillsText, 0, bytes, i, SkillsText.Length); i += SkillsText.Length; - bytes[i++] = (byte)LanguagesText.Length; + Utils.ByteToBytes((byte)LanguagesText.Length, bytes, ref i); Buffer.BlockCopy(LanguagesText, 0, bytes, i, LanguagesText.Length); i += LanguagesText.Length; } @@ -29371,12 +29409,12 @@ public override void FromBytes(byte[] bytes, ref int i) try { GroupPowers = Utils.BytesToUInt64Safepos(bytes, i); i += 8; - AcceptNotices = (bytes[i++] != 0) ? (bool)true : (bool)false; - length = bytes[i++]; + AcceptNotices = (Utils.BytesToByte(bytes, ref i) != 0); + length = Utils.BytesToByte(bytes, ref i); GroupTitle = new byte[length]; Buffer.BlockCopy(bytes, i, GroupTitle, 0, length); i += length; GroupID.FromBytes(bytes, i); i += 16; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); GroupName = new byte[length]; Buffer.BlockCopy(bytes, i, GroupName, 0, length); i += length; GroupInsigniaID.FromBytes(bytes, i); i += 16; @@ -29390,11 +29428,11 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { Utils.UInt64ToBytesSafepos(GroupPowers, bytes, i); i += 8; - bytes[i++] = (byte)((AcceptNotices) ? 1 : 0); - bytes[i++] = (byte)GroupTitle.Length; + Utils.ByteToBytes((byte)((AcceptNotices) ? 1 : 0), bytes, ref i); + Utils.ByteToBytes((byte)GroupTitle.Length, bytes, ref i); Buffer.BlockCopy(GroupTitle, 0, bytes, i, GroupTitle.Length); i += GroupTitle.Length; GroupID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)GroupName.Length; + Utils.ByteToBytes((byte)GroupName.Length, bytes, ref i); Buffer.BlockCopy(GroupName, 0, bytes, i, GroupName.Length); i += GroupName.Length; GroupInsigniaID.ToBytes(bytes, i); i += 16; } @@ -29424,7 +29462,7 @@ public override void FromBytes(byte[] bytes, ref int i) { try { - ListInProfile = (bytes[i++] != 0) ? (bool)true : (bool)false; + ListInProfile = (Utils.BytesToByte(bytes, ref i) != 0); } catch (Exception) { @@ -29434,7 +29472,7 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { - bytes[i++] = (byte)((ListInProfile) ? 1 : 0); + Utils.ByteToBytes((byte)((ListInProfile) ? 1 : 0), bytes, ref i); } } @@ -29527,7 +29565,7 @@ public override byte[] ToBytes() int i = 0; Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); - bytes[i++] = (byte)GroupData.Length; + Utils.ByteToBytes((byte)GroupData.Length, bytes, ref i); for (int j = 0; j < GroupData.Length; j++) { GroupData[j].ToBytes(bytes, ref i); } NewGroupData.ToBytes(bytes, ref i); if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } @@ -29620,15 +29658,15 @@ public override void FromBytes(byte[] bytes, ref int i) { ImageID.FromBytes(bytes, i); i += 16; FLImageID.FromBytes(bytes, i); i += 16; - length = (bytes[i++] + (bytes[i++] << 8)); + length = Utils.BytesToUInt16(bytes, i); i+=2; AboutText = new byte[length]; Buffer.BlockCopy(bytes, i, AboutText, 0, length); i += length; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); FLAboutText = new byte[length]; Buffer.BlockCopy(bytes, i, FLAboutText, 0, length); i += length; - AllowPublish = (bytes[i++] != 0) ? (bool)true : (bool)false; - MaturePublish = (bytes[i++] != 0) ? (bool)true : (bool)false; - length = bytes[i++]; + AllowPublish = (Utils.BytesToByte(bytes, ref i) != 0); + MaturePublish = (Utils.BytesToByte(bytes, ref i) != 0); + length = Utils.BytesToByte(bytes, ref i); ProfileURL = new byte[length]; Buffer.BlockCopy(bytes, i, ProfileURL, 0, length); i += length; } @@ -29642,14 +29680,13 @@ public override void ToBytes(byte[] bytes, ref int i) { ImageID.ToBytes(bytes, i); i += 16; FLImageID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)(AboutText.Length % 256); - bytes[i++] = (byte)((AboutText.Length >> 8) % 256); + Utils.UInt16ToBytes((ushort)AboutText.Length, bytes, i); i += 2; Buffer.BlockCopy(AboutText, 0, bytes, i, AboutText.Length); i += AboutText.Length; - bytes[i++] = (byte)FLAboutText.Length; + Utils.ByteToBytes((byte)FLAboutText.Length, bytes, ref i); Buffer.BlockCopy(FLAboutText, 0, bytes, i, FLAboutText.Length); i += FLAboutText.Length; - bytes[i++] = (byte)((AllowPublish) ? 1 : 0); - bytes[i++] = (byte)((MaturePublish) ? 1 : 0); - bytes[i++] = (byte)ProfileURL.Length; + Utils.ByteToBytes((byte)((AllowPublish) ? 1 : 0), bytes, ref i); + Utils.ByteToBytes((byte)((MaturePublish) ? 1 : 0), bytes, ref i); + Utils.ByteToBytes((byte)ProfileURL.Length, bytes, ref i); Buffer.BlockCopy(ProfileURL, 0, bytes, i, ProfileURL.Length); i += ProfileURL.Length; } @@ -29809,14 +29846,14 @@ public override void FromBytes(byte[] bytes, ref int i) try { WantToMask = Utils.BytesToUIntSafepos(bytes, i); i += 4; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); WantToText = new byte[length]; Buffer.BlockCopy(bytes, i, WantToText, 0, length); i += length; SkillsMask = Utils.BytesToUIntSafepos(bytes, i); i += 4; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); SkillsText = new byte[length]; Buffer.BlockCopy(bytes, i, SkillsText, 0, length); i += length; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); LanguagesText = new byte[length]; Buffer.BlockCopy(bytes, i, LanguagesText, 0, length); i += length; } @@ -29829,12 +29866,12 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { Utils.UIntToBytesSafepos(WantToMask, bytes, i); i += 4; - bytes[i++] = (byte)WantToText.Length; + Utils.ByteToBytes((byte)WantToText.Length, bytes, ref i); Buffer.BlockCopy(WantToText, 0, bytes, i, WantToText.Length); i += WantToText.Length; Utils.UIntToBytesSafepos(SkillsMask, bytes, i); i += 4; - bytes[i++] = (byte)SkillsText.Length; + Utils.ByteToBytes((byte)SkillsText.Length, bytes, ref i); Buffer.BlockCopy(SkillsText, 0, bytes, i, SkillsText.Length); i += SkillsText.Length; - bytes[i++] = (byte)LanguagesText.Length; + Utils.ByteToBytes((byte)LanguagesText.Length, bytes, ref i); Buffer.BlockCopy(LanguagesText, 0, bytes, i, LanguagesText.Length); i += LanguagesText.Length; } @@ -29986,7 +30023,7 @@ public override void FromBytes(byte[] bytes, ref int i) try { TargetID.FromBytes(bytes, i); i += 16; - length = (bytes[i++] + (bytes[i++] << 8)); + length = Utils.BytesToUInt16(bytes, i); i+=2; Notes = new byte[length]; Buffer.BlockCopy(bytes, i, Notes, 0, length); i += length; } @@ -29999,8 +30036,7 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { TargetID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)(Notes.Length % 256); - bytes[i++] = (byte)((Notes.Length >> 8) % 256); + Utils.UInt16ToBytes((ushort)Notes.Length, bytes, i); i += 2; Buffer.BlockCopy(Notes, 0, bytes, i, Notes.Length); i += Notes.Length; } @@ -30154,7 +30190,7 @@ public override void FromBytes(byte[] bytes, ref int i) try { TargetID.FromBytes(bytes, i); i += 16; - length = (bytes[i++] + (bytes[i++] << 8)); + length = Utils.BytesToUInt16(bytes, i); i+=2; Notes = new byte[length]; Buffer.BlockCopy(bytes, i, Notes, 0, length); i += length; } @@ -30167,8 +30203,7 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { TargetID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)(Notes.Length % 256); - bytes[i++] = (byte)((Notes.Length >> 8) % 256); + Utils.UInt16ToBytes((ushort)Notes.Length, bytes, i); i += 2; Buffer.BlockCopy(Notes, 0, bytes, i, Notes.Length); i += Notes.Length; } @@ -30322,7 +30357,7 @@ public override void FromBytes(byte[] bytes, ref int i) try { PickID.FromBytes(bytes, i); i += 16; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); PickName = new byte[length]; Buffer.BlockCopy(bytes, i, PickName, 0, length); i += length; } @@ -30335,7 +30370,7 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { PickID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)PickName.Length; + Utils.ByteToBytes((byte)PickName.Length, bytes, ref i); Buffer.BlockCopy(PickName, 0, bytes, i, PickName.Length); i += PickName.Length; } @@ -30422,7 +30457,7 @@ public override byte[] ToBytes() int i = 0; Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); - bytes[i++] = (byte)Data.Length; + Utils.ByteToBytes((byte)Data.Length, bytes, ref i); for (int j = 0; j < Data.Length; j++) { Data[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -30730,26 +30765,26 @@ public override void FromBytes(byte[] bytes, ref int i) try { EventID = Utils.BytesToUIntSafepos(bytes, i); i += 4; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Creator = new byte[length]; Buffer.BlockCopy(bytes, i, Creator, 0, length); i += length; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Name = new byte[length]; Buffer.BlockCopy(bytes, i, Name, 0, length); i += length; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Category = new byte[length]; Buffer.BlockCopy(bytes, i, Category, 0, length); i += length; - length = (bytes[i++] + (bytes[i++] << 8)); + length = Utils.BytesToUInt16(bytes, i); i+=2; Desc = new byte[length]; Buffer.BlockCopy(bytes, i, Desc, 0, length); i += length; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Date = new byte[length]; Buffer.BlockCopy(bytes, i, Date, 0, length); i += length; DateUTC = Utils.BytesToUIntSafepos(bytes, i); i += 4; Duration = Utils.BytesToUIntSafepos(bytes, i); i += 4; Cover = Utils.BytesToUIntSafepos(bytes, i); i += 4; Amount = Utils.BytesToUIntSafepos(bytes, i); i += 4; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); SimName = new byte[length]; Buffer.BlockCopy(bytes, i, SimName, 0, length); i += length; GlobalPos.FromBytes(bytes, i); i += 24; @@ -30764,22 +30799,21 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { Utils.UIntToBytesSafepos(EventID, bytes, i); i += 4; - bytes[i++] = (byte)Creator.Length; + Utils.ByteToBytes((byte)Creator.Length, bytes, ref i); Buffer.BlockCopy(Creator, 0, bytes, i, Creator.Length); i += Creator.Length; - bytes[i++] = (byte)Name.Length; + Utils.ByteToBytes((byte)Name.Length, bytes, ref i); Buffer.BlockCopy(Name, 0, bytes, i, Name.Length); i += Name.Length; - bytes[i++] = (byte)Category.Length; + Utils.ByteToBytes((byte)Category.Length, bytes, ref i); Buffer.BlockCopy(Category, 0, bytes, i, Category.Length); i += Category.Length; - bytes[i++] = (byte)(Desc.Length % 256); - bytes[i++] = (byte)((Desc.Length >> 8) % 256); + Utils.UInt16ToBytes((ushort)Desc.Length, bytes, i); i += 2; Buffer.BlockCopy(Desc, 0, bytes, i, Desc.Length); i += Desc.Length; - bytes[i++] = (byte)Date.Length; + Utils.ByteToBytes((byte)Date.Length, bytes, ref i); Buffer.BlockCopy(Date, 0, bytes, i, Date.Length); i += Date.Length; Utils.UIntToBytesSafepos(DateUTC, bytes, i); i += 4; Utils.UIntToBytesSafepos(Duration, bytes, i); i += 4; Utils.UIntToBytesSafepos(Cover, bytes, i); i += 4; Utils.UIntToBytesSafepos(Amount, bytes, i); i += 4; - bytes[i++] = (byte)SimName.Length; + Utils.ByteToBytes((byte)SimName.Length, bytes, ref i); Buffer.BlockCopy(SimName, 0, bytes, i, SimName.Length); i += SimName.Length; GlobalPos.ToBytes(bytes, i); i += 24; Utils.UIntToBytesSafepos(EventFlags, bytes, i); i += 4; @@ -31291,7 +31325,7 @@ public override void FromBytes(byte[] bytes, ref int i) try { QueryID.FromBytes(bytes, i); i += 16; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); QueryText = new byte[length]; Buffer.BlockCopy(bytes, i, QueryText, 0, length); i += length; QueryFlags = Utils.BytesToUIntSafepos(bytes, i); i += 4; @@ -31306,7 +31340,7 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { QueryID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)QueryText.Length; + Utils.ByteToBytes((byte)QueryText.Length, bytes, ref i); Buffer.BlockCopy(QueryText, 0, bytes, i, QueryText.Length); i += QueryText.Length; Utils.UIntToBytesSafepos(QueryFlags, bytes, i); i += 4; Utils.IntToBytesSafepos(QueryStart, bytes, i); i += 4; @@ -31482,27 +31516,27 @@ public override void FromBytes(byte[] bytes, ref int i) { PickID.FromBytes(bytes, i); i += 16; CreatorID.FromBytes(bytes, i); i += 16; - TopPick = (bytes[i++] != 0) ? (bool)true : (bool)false; + TopPick = (Utils.BytesToByte(bytes, ref i) != 0); ParcelID.FromBytes(bytes, i); i += 16; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Name = new byte[length]; Buffer.BlockCopy(bytes, i, Name, 0, length); i += length; - length = (bytes[i++] + (bytes[i++] << 8)); + length = Utils.BytesToUInt16(bytes, i); i+=2; Desc = new byte[length]; Buffer.BlockCopy(bytes, i, Desc, 0, length); i += length; SnapshotID.FromBytes(bytes, i); i += 16; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); User = new byte[length]; Buffer.BlockCopy(bytes, i, User, 0, length); i += length; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); OriginalName = new byte[length]; Buffer.BlockCopy(bytes, i, OriginalName, 0, length); i += length; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); SimName = new byte[length]; Buffer.BlockCopy(bytes, i, SimName, 0, length); i += length; PosGlobal.FromBytes(bytes, i); i += 24; SortOrder = Utils.BytesToIntSafepos(bytes, i); i +=4; - Enabled = (bytes[i++] != 0) ? (bool)true : (bool)false; + Enabled = (Utils.BytesToByte(bytes, ref i) != 0); } catch (Exception) { @@ -31514,23 +31548,22 @@ public override void ToBytes(byte[] bytes, ref int i) { PickID.ToBytes(bytes, i); i += 16; CreatorID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)((TopPick) ? 1 : 0); + Utils.ByteToBytes((byte)((TopPick) ? 1 : 0), bytes, ref i); ParcelID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)Name.Length; + Utils.ByteToBytes((byte)Name.Length, bytes, ref i); Buffer.BlockCopy(Name, 0, bytes, i, Name.Length); i += Name.Length; - bytes[i++] = (byte)(Desc.Length % 256); - bytes[i++] = (byte)((Desc.Length >> 8) % 256); + Utils.UInt16ToBytes((ushort)Desc.Length, bytes, i); i += 2; Buffer.BlockCopy(Desc, 0, bytes, i, Desc.Length); i += Desc.Length; SnapshotID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)User.Length; + Utils.ByteToBytes((byte)User.Length, bytes, ref i); Buffer.BlockCopy(User, 0, bytes, i, User.Length); i += User.Length; - bytes[i++] = (byte)OriginalName.Length; + Utils.ByteToBytes((byte)OriginalName.Length, bytes, ref i); Buffer.BlockCopy(OriginalName, 0, bytes, i, OriginalName.Length); i += OriginalName.Length; - bytes[i++] = (byte)SimName.Length; + Utils.ByteToBytes((byte)SimName.Length, bytes, ref i); Buffer.BlockCopy(SimName, 0, bytes, i, SimName.Length); i += SimName.Length; PosGlobal.ToBytes(bytes, i); i += 24; Utils.IntToBytesSafepos(SortOrder, bytes, i); i += 4; - bytes[i++] = (byte)((Enabled) ? 1 : 0); + Utils.ByteToBytes((byte)((Enabled) ? 1 : 0), bytes, ref i); } } @@ -31693,18 +31726,18 @@ public override void FromBytes(byte[] bytes, ref int i) { PickID.FromBytes(bytes, i); i += 16; CreatorID.FromBytes(bytes, i); i += 16; - TopPick = (bytes[i++] != 0) ? (bool)true : (bool)false; + TopPick = (Utils.BytesToByte(bytes, ref i) != 0); ParcelID.FromBytes(bytes, i); i += 16; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Name = new byte[length]; Buffer.BlockCopy(bytes, i, Name, 0, length); i += length; - length = (bytes[i++] + (bytes[i++] << 8)); + length = Utils.BytesToUInt16(bytes, i); i+=2; Desc = new byte[length]; Buffer.BlockCopy(bytes, i, Desc, 0, length); i += length; SnapshotID.FromBytes(bytes, i); i += 16; PosGlobal.FromBytes(bytes, i); i += 24; SortOrder = Utils.BytesToIntSafepos(bytes, i); i +=4; - Enabled = (bytes[i++] != 0) ? (bool)true : (bool)false; + Enabled = (Utils.BytesToByte(bytes, ref i) != 0); } catch (Exception) { @@ -31716,17 +31749,16 @@ public override void ToBytes(byte[] bytes, ref int i) { PickID.ToBytes(bytes, i); i += 16; CreatorID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)((TopPick) ? 1 : 0); + Utils.ByteToBytes((byte)((TopPick) ? 1 : 0), bytes, ref i); ParcelID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)Name.Length; + Utils.ByteToBytes((byte)Name.Length, bytes, ref i); Buffer.BlockCopy(Name, 0, bytes, i, Name.Length); i += Name.Length; - bytes[i++] = (byte)(Desc.Length % 256); - bytes[i++] = (byte)((Desc.Length >> 8) % 256); + Utils.UInt16ToBytes((ushort)Desc.Length, bytes, i); i += 2; Buffer.BlockCopy(Desc, 0, bytes, i, Desc.Length); i += Desc.Length; SnapshotID.ToBytes(bytes, i); i += 16; PosGlobal.ToBytes(bytes, i); i += 24; Utils.IntToBytesSafepos(SortOrder, bytes, i); i += 4; - bytes[i++] = (byte)((Enabled) ? 1 : 0); + Utils.ByteToBytes((byte)((Enabled) ? 1 : 0), bytes, ref i); } } @@ -32162,10 +32194,10 @@ public override void FromBytes(byte[] bytes, ref int i) { TaskID.FromBytes(bytes, i); i += 16; ItemID.FromBytes(bytes, i); i += 16; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); ObjectName = new byte[length]; Buffer.BlockCopy(bytes, i, ObjectName, 0, length); i += length; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); ObjectOwner = new byte[length]; Buffer.BlockCopy(bytes, i, ObjectOwner, 0, length); i += length; Questions = Utils.BytesToIntSafepos(bytes, i); i +=4; @@ -32180,9 +32212,9 @@ public override void ToBytes(byte[] bytes, ref int i) { TaskID.ToBytes(bytes, i); i += 16; ItemID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)ObjectName.Length; + Utils.ByteToBytes((byte)ObjectName.Length, bytes, ref i); Buffer.BlockCopy(ObjectName, 0, bytes, i, ObjectName.Length); i += ObjectName.Length; - bytes[i++] = (byte)ObjectOwner.Length; + Utils.ByteToBytes((byte)ObjectOwner.Length, bytes, ref i); Buffer.BlockCopy(ObjectOwner, 0, bytes, i, ObjectOwner.Length); i += ObjectOwner.Length; Utils.IntToBytesSafepos(Questions, bytes, i); i += 4; } @@ -32331,9 +32363,9 @@ public override void FromBytes(byte[] bytes, ref int i) { try { - TakeControls = (bytes[i++] != 0) ? (bool)true : (bool)false; + TakeControls = (Utils.BytesToByte(bytes, ref i) != 0); Controls = Utils.BytesToUIntSafepos(bytes, i); i += 4; - PassToAgent = (bytes[i++] != 0) ? (bool)true : (bool)false; + PassToAgent = (Utils.BytesToByte(bytes, ref i) != 0); } catch (Exception) { @@ -32343,9 +32375,9 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { - bytes[i++] = (byte)((TakeControls) ? 1 : 0); + Utils.ByteToBytes((byte)((TakeControls) ? 1 : 0), bytes, ref i); Utils.UIntToBytesSafepos(Controls, bytes, i); i += 4; - bytes[i++] = (byte)((PassToAgent) ? 1 : 0); + Utils.ByteToBytes((byte)((PassToAgent) ? 1 : 0), bytes, ref i); } } @@ -32424,7 +32456,7 @@ public override byte[] ToBytes() byte[] bytes = new byte[length]; int i = 0; Header.ToBytes(bytes, ref i); - bytes[i++] = (byte)Data.Length; + Utils.ByteToBytes((byte)Data.Length, bytes, ref i); for (int j = 0; j < Data.Length; j++) { Data[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -32526,16 +32558,16 @@ public override void FromBytes(byte[] bytes, ref int i) try { ObjectID.FromBytes(bytes, i); i += 16; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); FirstName = new byte[length]; Buffer.BlockCopy(bytes, i, FirstName, 0, length); i += length; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); LastName = new byte[length]; Buffer.BlockCopy(bytes, i, LastName, 0, length); i += length; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); ObjectName = new byte[length]; Buffer.BlockCopy(bytes, i, ObjectName, 0, length); i += length; - length = (bytes[i++] + (bytes[i++] << 8)); + length = Utils.BytesToUInt16(bytes, i); i+=2; Message = new byte[length]; Buffer.BlockCopy(bytes, i, Message, 0, length); i += length; ChatChannel = Utils.BytesToIntSafepos(bytes, i); i +=4; @@ -32550,14 +32582,13 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { ObjectID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)FirstName.Length; + Utils.ByteToBytes((byte)FirstName.Length, bytes, ref i); Buffer.BlockCopy(FirstName, 0, bytes, i, FirstName.Length); i += FirstName.Length; - bytes[i++] = (byte)LastName.Length; + Utils.ByteToBytes((byte)LastName.Length, bytes, ref i); Buffer.BlockCopy(LastName, 0, bytes, i, LastName.Length); i += LastName.Length; - bytes[i++] = (byte)ObjectName.Length; + Utils.ByteToBytes((byte)ObjectName.Length, bytes, ref i); Buffer.BlockCopy(ObjectName, 0, bytes, i, ObjectName.Length); i += ObjectName.Length; - bytes[i++] = (byte)(Message.Length % 256); - bytes[i++] = (byte)((Message.Length >> 8) % 256); + Utils.UInt16ToBytes((ushort)Message.Length, bytes, i); i += 2; Buffer.BlockCopy(Message, 0, bytes, i, Message.Length); i += Message.Length; Utils.IntToBytesSafepos(ChatChannel, bytes, i); i += 4; ImageID.ToBytes(bytes, i); i += 16; @@ -32591,7 +32622,7 @@ public override void FromBytes(byte[] bytes, ref int i) int length; try { - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); ButtonLabel = new byte[length]; Buffer.BlockCopy(bytes, i, ButtonLabel, 0, length); i += length; } @@ -32603,7 +32634,7 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { - bytes[i++] = (byte)ButtonLabel.Length; + Utils.ByteToBytes((byte)ButtonLabel.Length, bytes, ref i); Buffer.BlockCopy(ButtonLabel, 0, bytes, i, ButtonLabel.Length); i += ButtonLabel.Length; } @@ -32751,9 +32782,9 @@ public override byte[] ToBytes() int i = 0; Header.ToBytes(bytes, ref i); Data.ToBytes(bytes, ref i); - bytes[i++] = (byte)Buttons.Length; + Utils.ByteToBytes((byte)Buttons.Length, bytes, ref i); for (int j = 0; j < Buttons.Length; j++) { Buttons[j].ToBytes(bytes, ref i); } - bytes[i++] = (byte)OwnerData.Length; + Utils.ByteToBytes((byte)OwnerData.Length, bytes, ref i); for (int j = 0; j < OwnerData.Length; j++) { OwnerData[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -32912,7 +32943,7 @@ public override void FromBytes(byte[] bytes, ref int i) ObjectID.FromBytes(bytes, i); i += 16; ChatChannel = Utils.BytesToIntSafepos(bytes, i); i +=4; ButtonIndex = Utils.BytesToIntSafepos(bytes, i); i +=4; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); ButtonLabel = new byte[length]; Buffer.BlockCopy(bytes, i, ButtonLabel, 0, length); i += length; } @@ -32927,7 +32958,7 @@ public override void ToBytes(byte[] bytes, ref int i) ObjectID.ToBytes(bytes, i); i += 16; Utils.IntToBytesSafepos(ChatChannel, bytes, i); i += 4; Utils.IntToBytesSafepos(ButtonIndex, bytes, i); i += 4; - bytes[i++] = (byte)ButtonLabel.Length; + Utils.ByteToBytes((byte)ButtonLabel.Length, bytes, ref i); Buffer.BlockCopy(ButtonLabel, 0, bytes, i, ButtonLabel.Length); i += ButtonLabel.Length; } @@ -33320,16 +33351,16 @@ public override void FromBytes(byte[] bytes, ref int i) int length; try { - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); ObjectName = new byte[length]; Buffer.BlockCopy(bytes, i, ObjectName, 0, length); i += length; ObjectID.FromBytes(bytes, i); i += 16; OwnerID.FromBytes(bytes, i); i += 16; - OwnerIsGroup = (bytes[i++] != 0) ? (bool)true : (bool)false; - length = bytes[i++]; + OwnerIsGroup = (Utils.BytesToByte(bytes, ref i) != 0); + length = Utils.BytesToByte(bytes, ref i); Message = new byte[length]; Buffer.BlockCopy(bytes, i, Message, 0, length); i += length; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); URL = new byte[length]; Buffer.BlockCopy(bytes, i, URL, 0, length); i += length; } @@ -33341,14 +33372,14 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { - bytes[i++] = (byte)ObjectName.Length; + Utils.ByteToBytes((byte)ObjectName.Length, bytes, ref i); Buffer.BlockCopy(ObjectName, 0, bytes, i, ObjectName.Length); i += ObjectName.Length; ObjectID.ToBytes(bytes, i); i += 16; OwnerID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)((OwnerIsGroup) ? 1 : 0); - bytes[i++] = (byte)Message.Length; + Utils.ByteToBytes((byte)((OwnerIsGroup) ? 1 : 0), bytes, ref i); + Utils.ByteToBytes((byte)Message.Length, bytes, ref i); Buffer.BlockCopy(Message, 0, bytes, i, Message.Length); i += Message.Length; - bytes[i++] = (byte)URL.Length; + Utils.ByteToBytes((byte)URL.Length, bytes, ref i); Buffer.BlockCopy(URL, 0, bytes, i, URL.Length); i += URL.Length; } @@ -33456,10 +33487,10 @@ public override void FromBytes(byte[] bytes, ref int i) int length; try { - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); ObjectName = new byte[length]; Buffer.BlockCopy(bytes, i, ObjectName, 0, length); i += length; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); SimName = new byte[length]; Buffer.BlockCopy(bytes, i, SimName, 0, length); i += length; SimPosition.FromBytes(bytes, i); i += 12; @@ -33473,9 +33504,9 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { - bytes[i++] = (byte)ObjectName.Length; + Utils.ByteToBytes((byte)ObjectName.Length, bytes, ref i); Buffer.BlockCopy(ObjectName, 0, bytes, i, ObjectName.Length); i += ObjectName.Length; - bytes[i++] = (byte)SimName.Length; + Utils.ByteToBytes((byte)SimName.Length, bytes, ref i); Buffer.BlockCopy(SimName, 0, bytes, i, SimName.Length); i += SimName.Length; SimPosition.ToBytes(bytes, i); i += 12; LookAt.ToBytes(bytes, i); i += 12; @@ -33583,7 +33614,7 @@ public override void FromBytes(byte[] bytes, ref int i) try { SequenceID = Utils.BytesToIntSafepos(bytes, i); i +=4; - length = (bytes[i++] + (bytes[i++] << 8)); + length = Utils.BytesToUInt16(bytes, i); i+=2; Data = new byte[length]; Buffer.BlockCopy(bytes, i, Data, 0, length); i += length; } @@ -33596,8 +33627,7 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { Utils.IntToBytesSafepos(SequenceID, bytes, i); i += 4; - bytes[i++] = (byte)(Data.Length % 256); - bytes[i++] = (byte)((Data.Length >> 8) % 256); + Utils.UInt16ToBytes((ushort)Data.Length, bytes, i); i += 2; Buffer.BlockCopy(Data, 0, bytes, i, Data.Length); i += Data.Length; } @@ -33930,29 +33960,29 @@ public override void FromBytes(byte[] bytes, ref int i) Flags = Utils.BytesToUIntSafepos(bytes, i); i += 4; ParcelFlags = Utils.BytesToUIntSafepos(bytes, i); i += 4; SalePrice = Utils.BytesToIntSafepos(bytes, i); i +=4; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Name = new byte[length]; Buffer.BlockCopy(bytes, i, Name, 0, length); i += length; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Desc = new byte[length]; Buffer.BlockCopy(bytes, i, Desc, 0, length); i += length; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); MusicURL = new byte[length]; Buffer.BlockCopy(bytes, i, MusicURL, 0, length); i += length; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); MediaURL = new byte[length]; Buffer.BlockCopy(bytes, i, MediaURL, 0, length); i += length; MediaID.FromBytes(bytes, i); i += 16; - MediaAutoScale = (byte)bytes[i++]; + MediaAutoScale = Utils.BytesToByte(bytes, ref i); GroupID.FromBytes(bytes, i); i += 16; PassPrice = Utils.BytesToIntSafepos(bytes, i); i +=4; PassHours = Utils.BytesToFloatSafepos(bytes, i); i += 4; - Category = (byte)bytes[i++]; + Category = Utils.BytesToByte(bytes, ref i); AuthBuyerID.FromBytes(bytes, i); i += 16; SnapshotID.FromBytes(bytes, i); i += 16; UserLocation.FromBytes(bytes, i); i += 12; UserLookAt.FromBytes(bytes, i); i += 12; - LandingType = (byte)bytes[i++]; + LandingType = Utils.BytesToByte(bytes, ref i); } catch (Exception) { @@ -33966,25 +33996,25 @@ public override void ToBytes(byte[] bytes, ref int i) Utils.UIntToBytesSafepos(Flags, bytes, i); i += 4; Utils.UIntToBytesSafepos(ParcelFlags, bytes, i); i += 4; Utils.IntToBytesSafepos(SalePrice, bytes, i); i += 4; - bytes[i++] = (byte)Name.Length; + Utils.ByteToBytes((byte)Name.Length, bytes, ref i); Buffer.BlockCopy(Name, 0, bytes, i, Name.Length); i += Name.Length; - bytes[i++] = (byte)Desc.Length; + Utils.ByteToBytes((byte)Desc.Length, bytes, ref i); Buffer.BlockCopy(Desc, 0, bytes, i, Desc.Length); i += Desc.Length; - bytes[i++] = (byte)MusicURL.Length; + Utils.ByteToBytes((byte)MusicURL.Length, bytes, ref i); Buffer.BlockCopy(MusicURL, 0, bytes, i, MusicURL.Length); i += MusicURL.Length; - bytes[i++] = (byte)MediaURL.Length; + Utils.ByteToBytes((byte)MediaURL.Length, bytes, ref i); Buffer.BlockCopy(MediaURL, 0, bytes, i, MediaURL.Length); i += MediaURL.Length; MediaID.ToBytes(bytes, i); i += 16; - bytes[i++] = MediaAutoScale; + Utils.ByteToBytes( MediaAutoScale, bytes, ref i); GroupID.ToBytes(bytes, i); i += 16; Utils.IntToBytesSafepos(PassPrice, bytes, i); i += 4; Utils.FloatToBytesSafepos(PassHours, bytes, i); i += 4; - bytes[i++] = Category; + Utils.ByteToBytes( Category, bytes, ref i); AuthBuyerID.ToBytes(bytes, i); i += 16; SnapshotID.ToBytes(bytes, i); i += 16; UserLocation.ToBytes(bytes, i); i += 12; UserLookAt.ToBytes(bytes, i); i += 12; - bytes[i++] = LandingType; + Utils.ByteToBytes( LandingType, bytes, ref i); } } @@ -34338,9 +34368,9 @@ public override byte[] ToBytes() Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); ParcelData.ToBytes(bytes, ref i); - bytes[i++] = (byte)TaskIDs.Length; + Utils.ByteToBytes((byte)TaskIDs.Length, bytes, ref i); for (int j = 0; j < TaskIDs.Length; j++) { TaskIDs[j].ToBytes(bytes, ref i); } - bytes[i++] = (byte)OwnerIDs.Length; + Utils.ByteToBytes((byte)OwnerIDs.Length, bytes, ref i); for (int j = 0; j < OwnerIDs.Length; j++) { OwnerIDs[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -34859,9 +34889,9 @@ public override byte[] ToBytes() Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); ParcelData.ToBytes(bytes, ref i); - bytes[i++] = (byte)TaskIDs.Length; + Utils.ByteToBytes((byte)TaskIDs.Length, bytes, ref i); for (int j = 0; j < TaskIDs.Length; j++) { TaskIDs[j].ToBytes(bytes, ref i); } - bytes[i++] = (byte)OwnerIDs.Length; + Utils.ByteToBytes((byte)OwnerIDs.Length, bytes, ref i); for (int j = 0; j < OwnerIDs.Length; j++) { OwnerIDs[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -35158,7 +35188,7 @@ public override byte[] ToBytes() Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); ParcelData.ToBytes(bytes, ref i); - bytes[i++] = (byte)ReturnIDs.Length; + Utils.ByteToBytes((byte)ReturnIDs.Length, bytes, ref i); for (int j = 0; j < ReturnIDs.Length; j++) { ReturnIDs[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -35372,7 +35402,7 @@ public override void FromBytes(byte[] bytes, ref int i) { CovenantID.FromBytes(bytes, i); i += 16; CovenantTimestamp = Utils.BytesToUIntSafepos(bytes, i); i += 4; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); EstateName = new byte[length]; Buffer.BlockCopy(bytes, i, EstateName, 0, length); i += length; EstateOwnerID.FromBytes(bytes, i); i += 16; @@ -35387,7 +35417,7 @@ public override void ToBytes(byte[] bytes, ref int i) { CovenantID.ToBytes(bytes, i); i += 16; Utils.UIntToBytesSafepos(CovenantTimestamp, bytes, i); i += 4; - bytes[i++] = (byte)EstateName.Length; + Utils.ByteToBytes((byte)EstateName.Length, bytes, ref i); Buffer.BlockCopy(EstateName, 0, bytes, i, EstateName.Length); i += EstateName.Length; EstateOwnerID.ToBytes(bytes, i); i += 16; } @@ -35489,7 +35519,7 @@ public override void FromBytes(byte[] bytes, ref int i) { try { - ResetList = (bytes[i++] != 0) ? (bool)true : (bool)false; + ResetList = (Utils.BytesToByte(bytes, ref i) != 0); } catch (Exception) { @@ -35499,7 +35529,7 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { - bytes[i++] = (byte)((ResetList) ? 1 : 0); + Utils.ByteToBytes((byte)((ResetList) ? 1 : 0), bytes, ref i); } } @@ -35623,7 +35653,7 @@ public override byte[] ToBytes() int i = 0; Header.ToBytes(bytes, ref i); _Header.ToBytes(bytes, ref i); - bytes[i++] = (byte)Data.Length; + Utils.ByteToBytes((byte)Data.Length, bytes, ref i); for (int j = 0; j < Data.Length; j++) { Data[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -36235,8 +36265,8 @@ public override void FromBytes(byte[] bytes, ref int i) try { GroupID.FromBytes(bytes, i); i += 16; - IsGroupOwned = (bytes[i++] != 0) ? (bool)true : (bool)false; - Final = (bytes[i++] != 0) ? (bool)true : (bool)false; + IsGroupOwned = (Utils.BytesToByte(bytes, ref i) != 0); + Final = (Utils.BytesToByte(bytes, ref i) != 0); } catch (Exception) { @@ -36247,8 +36277,8 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { GroupID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)((IsGroupOwned) ? 1 : 0); - bytes[i++] = (byte)((Final) ? 1 : 0); + Utils.ByteToBytes((byte)((IsGroupOwned) ? 1 : 0), bytes, ref i); + Utils.ByteToBytes((byte)((Final) ? 1 : 0), bytes, ref i); } } @@ -36389,7 +36419,7 @@ public override byte[] ToBytes() Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); Data.ToBytes(bytes, ref i); - bytes[i++] = (byte)ParcelData.Length; + Utils.ByteToBytes((byte)ParcelData.Length, bytes, ref i); for (int j = 0; j < ParcelData.Length; j++) { ParcelData[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -37020,10 +37050,10 @@ public override void FromBytes(byte[] bytes, ref int i) try { GroupID.FromBytes(bytes, i); i += 16; - IsGroupOwned = (bytes[i++] != 0) ? (bool)true : (bool)false; - RemoveContribution = (bytes[i++] != 0) ? (bool)true : (bool)false; + IsGroupOwned = (Utils.BytesToByte(bytes, ref i) != 0); + RemoveContribution = (Utils.BytesToByte(bytes, ref i) != 0); LocalID = Utils.BytesToIntSafepos(bytes, i); i +=4; - Final = (bytes[i++] != 0) ? (bool)true : (bool)false; + Final = (Utils.BytesToByte(bytes, ref i) != 0); } catch (Exception) { @@ -37034,10 +37064,10 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { GroupID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)((IsGroupOwned) ? 1 : 0); - bytes[i++] = (byte)((RemoveContribution) ? 1 : 0); + Utils.ByteToBytes((byte)((IsGroupOwned) ? 1 : 0), bytes, ref i); + Utils.ByteToBytes((byte)((RemoveContribution) ? 1 : 0), bytes, ref i); Utils.IntToBytesSafepos(LocalID, bytes, i); i += 4; - bytes[i++] = (byte)((Final) ? 1 : 0); + Utils.ByteToBytes((byte)((Final) ? 1 : 0), bytes, ref i); } } @@ -37670,7 +37700,7 @@ public override byte[] ToBytes() int i = 0; Header.ToBytes(bytes, ref i); Data.ToBytes(bytes, ref i); - bytes[i++] = (byte)List.Length; + Utils.ByteToBytes((byte)List.Length, bytes, ref i); for (int j = 0; j < List.Length; j++) { List[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -37962,7 +37992,7 @@ public override byte[] ToBytes() Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); Data.ToBytes(bytes, ref i); - bytes[i++] = (byte)List.Length; + Utils.ByteToBytes((byte)List.Length, bytes, ref i); for (int j = 0; j < List.Length; j++) { List[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -38785,7 +38815,7 @@ public override byte[] ToBytes() byte[] bytes = new byte[length]; int i = 0; Header.ToBytes(bytes, ref i); - bytes[i++] = (byte)UUIDNameBlock.Length; + Utils.ByteToBytes((byte)UUIDNameBlock.Length, bytes, ref i); for (int j = 0; j < UUIDNameBlock.Length; j++) { UUIDNameBlock[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -38881,10 +38911,10 @@ public override void FromBytes(byte[] bytes, ref int i) try { ID.FromBytes(bytes, i); i += 16; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); FirstName = new byte[length]; Buffer.BlockCopy(bytes, i, FirstName, 0, length); i += length; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); LastName = new byte[length]; Buffer.BlockCopy(bytes, i, LastName, 0, length); i += length; } @@ -38897,9 +38927,9 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { ID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)FirstName.Length; + Utils.ByteToBytes((byte)FirstName.Length, bytes, ref i); Buffer.BlockCopy(FirstName, 0, bytes, i, FirstName.Length); i += FirstName.Length; - bytes[i++] = (byte)LastName.Length; + Utils.ByteToBytes((byte)LastName.Length, bytes, ref i); Buffer.BlockCopy(LastName, 0, bytes, i, LastName.Length); i += LastName.Length; } @@ -38979,7 +39009,7 @@ public override byte[] ToBytes() byte[] bytes = new byte[length]; int i = 0; Header.ToBytes(bytes, ref i); - bytes[i++] = (byte)UUIDNameBlock.Length; + Utils.ByteToBytes((byte)UUIDNameBlock.Length, bytes, ref i); for (int j = 0; j < UUIDNameBlock.Length; j++) { UUIDNameBlock[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -39157,7 +39187,7 @@ public override byte[] ToBytes() byte[] bytes = new byte[length]; int i = 0; Header.ToBytes(bytes, ref i); - bytes[i++] = (byte)UUIDNameBlock.Length; + Utils.ByteToBytes((byte)UUIDNameBlock.Length, bytes, ref i); for (int j = 0; j < UUIDNameBlock.Length; j++) { UUIDNameBlock[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -39251,7 +39281,7 @@ public override void FromBytes(byte[] bytes, ref int i) try { ID.FromBytes(bytes, i); i += 16; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); GroupName = new byte[length]; Buffer.BlockCopy(bytes, i, GroupName, 0, length); i += length; } @@ -39264,7 +39294,7 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { ID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)GroupName.Length; + Utils.ByteToBytes((byte)GroupName.Length, bytes, ref i); Buffer.BlockCopy(GroupName, 0, bytes, i, GroupName.Length); i += GroupName.Length; } @@ -39344,7 +39374,7 @@ public override byte[] ToBytes() byte[] bytes = new byte[length]; int i = 0; Header.ToBytes(bytes, ref i); - bytes[i++] = (byte)UUIDNameBlock.Length; + Utils.ByteToBytes((byte)UUIDNameBlock.Length, bytes, ref i); for (int j = 0; j < UUIDNameBlock.Length; j++) { UUIDNameBlock[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -39777,7 +39807,7 @@ public override void FromBytes(byte[] bytes, ref int i) { ObjectID.FromBytes(bytes, i); i += 16; ItemID.FromBytes(bytes, i); i += 16; - Running = (bytes[i++] != 0) ? (bool)true : (bool)false; + Running = (Utils.BytesToByte(bytes, ref i) != 0); } catch (Exception) { @@ -39789,7 +39819,7 @@ public override void ToBytes(byte[] bytes, ref int i) { ObjectID.ToBytes(bytes, i); i += 16; ItemID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)((Running) ? 1 : 0); + Utils.ByteToBytes((byte)((Running) ? 1 : 0), bytes, ref i); } } @@ -39934,7 +39964,7 @@ public override void FromBytes(byte[] bytes, ref int i) { ObjectID.FromBytes(bytes, i); i += 16; ItemID.FromBytes(bytes, i); i += 16; - Running = (bytes[i++] != 0) ? (bool)true : (bool)false; + Running = (Utils.BytesToByte(bytes, ref i) != 0); } catch (Exception) { @@ -39946,7 +39976,7 @@ public override void ToBytes(byte[] bytes, ref int i) { ObjectID.ToBytes(bytes, i); i += 16; ItemID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)((Running) ? 1 : 0); + Utils.ByteToBytes((byte)((Running) ? 1 : 0), bytes, ref i); } } @@ -40232,14 +40262,14 @@ public override void FromBytes(byte[] bytes, ref int i) SearchID.FromBytes(bytes, i); i += 16; SearchPos.FromBytes(bytes, i); i += 12; SearchDir.FromBytes(bytes, i, true); i += 12; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); SearchName = new byte[length]; Buffer.BlockCopy(bytes, i, SearchName, 0, length); i += length; Type = Utils.BytesToIntSafepos(bytes, i); i +=4; Range = Utils.BytesToFloatSafepos(bytes, i); i += 4; Arc = Utils.BytesToFloatSafepos(bytes, i); i += 4; RegionHandle = Utils.BytesToUInt64Safepos(bytes, i); i += 8; - SearchRegions = (byte)bytes[i++]; + SearchRegions = Utils.BytesToByte(bytes, ref i); } catch (Exception) { @@ -40254,13 +40284,13 @@ public override void ToBytes(byte[] bytes, ref int i) SearchID.ToBytes(bytes, i); i += 16; SearchPos.ToBytes(bytes, i); i += 12; SearchDir.ToBytes(bytes, i); i += 12; - bytes[i++] = (byte)SearchName.Length; + Utils.ByteToBytes((byte)SearchName.Length, bytes, ref i); Buffer.BlockCopy(SearchName, 0, bytes, i, SearchName.Length); i += SearchName.Length; Utils.IntToBytesSafepos(Type, bytes, i); i += 4; Utils.FloatToBytesSafepos(Range, bytes, i); i += 4; Utils.FloatToBytesSafepos(Arc, bytes, i); i += 4; Utils.UInt64ToBytesSafepos(RegionHandle, bytes, i); i += 8; - bytes[i++] = SearchRegions; + Utils.ByteToBytes( SearchRegions, bytes, ref i); } } @@ -40416,7 +40446,7 @@ public override void FromBytes(byte[] bytes, ref int i) Position.FromBytes(bytes, i); i += 12; Velocity.FromBytes(bytes, i); i += 12; Rotation.FromBytes(bytes, i, true); i += 12; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Name = new byte[length]; Buffer.BlockCopy(bytes, i, Name, 0, length); i += length; Type = Utils.BytesToIntSafepos(bytes, i); i +=4; @@ -40436,7 +40466,7 @@ public override void ToBytes(byte[] bytes, ref int i) Position.ToBytes(bytes, i); i += 12; Velocity.ToBytes(bytes, i); i += 12; Rotation.ToBytes(bytes, i); i += 12; - bytes[i++] = (byte)Name.Length; + Utils.ByteToBytes((byte)Name.Length, bytes, ref i); Buffer.BlockCopy(Name, 0, bytes, i, Name.Length); i += Name.Length; Utils.IntToBytesSafepos(Type, bytes, i); i += 4; Utils.FloatToBytesSafepos(Range, bytes, i); i += 4; @@ -40526,7 +40556,7 @@ public override byte[] ToBytes() int i = 0; Header.ToBytes(bytes, ref i); Requester.ToBytes(bytes, ref i); - bytes[i++] = (byte)SensedData.Length; + Utils.ByteToBytes((byte)SensedData.Length, bytes, ref i); for (int j = 0; j < SensedData.Length; j++) { SensedData[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -40824,7 +40854,7 @@ public override void FromBytes(byte[] bytes, ref int i) int length; try { - length = (bytes[i++] + (bytes[i++] << 8)); + length = Utils.BytesToUInt16(bytes, i); i+=2; ChannelVersion = new byte[length]; Buffer.BlockCopy(bytes, i, ChannelVersion, 0, length); i += length; } @@ -40836,8 +40866,7 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { - bytes[i++] = (byte)(ChannelVersion.Length % 256); - bytes[i++] = (byte)((ChannelVersion.Length >> 8) % 256); + Utils.UInt16ToBytes((ushort)ChannelVersion.Length, bytes, i); i += 2; Buffer.BlockCopy(ChannelVersion, 0, bytes, i, ChannelVersion.Length); i += ChannelVersion.Length; } @@ -41203,7 +41232,7 @@ public override byte[] ToBytes() int i = 0; Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); - bytes[i++] = (byte)InventoryData.Length; + Utils.ByteToBytes((byte)InventoryData.Length, bytes, ref i); for (int j = 0; j < InventoryData.Length; j++) { InventoryData[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -41351,22 +41380,22 @@ public override void FromBytes(byte[] bytes, ref int i) int length; try { - FromGroup = (bytes[i++] != 0) ? (bool)true : (bool)false; + FromGroup = (Utils.BytesToByte(bytes, ref i) != 0); ToAgentID.FromBytes(bytes, i); i += 16; ParentEstateID = Utils.BytesToUIntSafepos(bytes, i); i += 4; RegionID.FromBytes(bytes, i); i += 16; Position.FromBytes(bytes, i); i += 12; - Offline = (byte)bytes[i++]; - Dialog = (byte)bytes[i++]; + Offline = Utils.BytesToByte(bytes, ref i); + Dialog = Utils.BytesToByte(bytes, ref i); ID.FromBytes(bytes, i); i += 16; Timestamp = Utils.BytesToUIntSafepos(bytes, i); i += 4; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); FromAgentName = new byte[length]; Buffer.BlockCopy(bytes, i, FromAgentName, 0, length); i += length; - length = (bytes[i++] + (bytes[i++] << 8)); + length = Utils.BytesToUInt16(bytes, i); i+=2; Message = new byte[length]; Buffer.BlockCopy(bytes, i, Message, 0, length); i += length; - length = (bytes[i++] + (bytes[i++] << 8)); + length = Utils.BytesToUInt16(bytes, i); i+=2; BinaryBucket = new byte[length]; Buffer.BlockCopy(bytes, i, BinaryBucket, 0, length); i += length; } @@ -41378,22 +41407,20 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { - bytes[i++] = (byte)((FromGroup) ? 1 : 0); + Utils.ByteToBytes((byte)((FromGroup) ? 1 : 0), bytes, ref i); ToAgentID.ToBytes(bytes, i); i += 16; Utils.UIntToBytesSafepos(ParentEstateID, bytes, i); i += 4; RegionID.ToBytes(bytes, i); i += 16; Position.ToBytes(bytes, i); i += 12; - bytes[i++] = Offline; - bytes[i++] = Dialog; + Utils.ByteToBytes( Offline, bytes, ref i); + Utils.ByteToBytes( Dialog, bytes, ref i); ID.ToBytes(bytes, i); i += 16; Utils.UIntToBytesSafepos(Timestamp, bytes, i); i += 4; - bytes[i++] = (byte)FromAgentName.Length; + Utils.ByteToBytes((byte)FromAgentName.Length, bytes, ref i); Buffer.BlockCopy(FromAgentName, 0, bytes, i, FromAgentName.Length); i += FromAgentName.Length; - bytes[i++] = (byte)(Message.Length % 256); - bytes[i++] = (byte)((Message.Length >> 8) % 256); + Utils.UInt16ToBytes((ushort)Message.Length, bytes, i); i += 2; Buffer.BlockCopy(Message, 0, bytes, i, Message.Length); i += Message.Length; - bytes[i++] = (byte)(BinaryBucket.Length % 256); - bytes[i++] = (byte)((BinaryBucket.Length >> 8) % 256); + Utils.UInt16ToBytes((ushort)BinaryBucket.Length, bytes, i); i += 2; Buffer.BlockCopy(BinaryBucket, 0, bytes, i, BinaryBucket.Length); i += BinaryBucket.Length; } @@ -41758,7 +41785,7 @@ public override byte[] ToBytes() int i = 0; Header.ToBytes(bytes, ref i); AgentBlock.ToBytes(bytes, ref i); - bytes[i++] = (byte)LocationBlock.Length; + Utils.ByteToBytes((byte)LocationBlock.Length, bytes, ref i); for (int j = 0; j < LocationBlock.Length; j++) { LocationBlock[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -41891,7 +41918,7 @@ public override void FromBytes(byte[] bytes, ref int i) { try { - Godlike = (bytes[i++] != 0) ? (bool)true : (bool)false; + Godlike = (Utils.BytesToByte(bytes, ref i) != 0); Token.FromBytes(bytes, i); i += 16; } catch (Exception) @@ -41902,7 +41929,7 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { - bytes[i++] = (byte)((Godlike) ? 1 : 0); + Utils.ByteToBytes((byte)((Godlike) ? 1 : 0), bytes, ref i); Token.ToBytes(bytes, i); i += 16; } @@ -42052,7 +42079,7 @@ public override void FromBytes(byte[] bytes, ref int i) { try { - GodLevel = (byte)bytes[i++]; + GodLevel = Utils.BytesToByte(bytes, ref i); Token.FromBytes(bytes, i); i += 16; } catch (Exception) @@ -42063,7 +42090,7 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { - bytes[i++] = GodLevel; + Utils.ByteToBytes( GodLevel, bytes, ref i); Token.ToBytes(bytes, i); i += 16; } @@ -42219,7 +42246,7 @@ public override void FromBytes(byte[] bytes, ref int i) int length; try { - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Method = new byte[length]; Buffer.BlockCopy(bytes, i, Method, 0, length); i += length; Invoice.FromBytes(bytes, i); i += 16; @@ -42232,7 +42259,7 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { - bytes[i++] = (byte)Method.Length; + Utils.ByteToBytes((byte)Method.Length, bytes, ref i); Buffer.BlockCopy(Method, 0, bytes, i, Method.Length); i += Method.Length; Invoice.ToBytes(bytes, i); i += 16; } @@ -42265,7 +42292,7 @@ public override void FromBytes(byte[] bytes, ref int i) int length; try { - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Parameter = new byte[length]; Buffer.BlockCopy(bytes, i, Parameter, 0, length); i += length; } @@ -42277,7 +42304,7 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { - bytes[i++] = (byte)Parameter.Length; + Utils.ByteToBytes((byte)Parameter.Length, bytes, ref i); Buffer.BlockCopy(Parameter, 0, bytes, i, Parameter.Length); i += Parameter.Length; } @@ -42372,7 +42399,7 @@ public override byte[] ToBytes() Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); MethodData.ToBytes(bytes, ref i); - bytes[i++] = (byte)ParamList.Length; + Utils.ByteToBytes((byte)ParamList.Length, bytes, ref i); for (int j = 0; j < ParamList.Length; j++) { ParamList[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -42513,7 +42540,7 @@ public override void FromBytes(byte[] bytes, ref int i) int length; try { - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Method = new byte[length]; Buffer.BlockCopy(bytes, i, Method, 0, length); i += length; Invoice.FromBytes(bytes, i); i += 16; @@ -42526,7 +42553,7 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { - bytes[i++] = (byte)Method.Length; + Utils.ByteToBytes((byte)Method.Length, bytes, ref i); Buffer.BlockCopy(Method, 0, bytes, i, Method.Length); i += Method.Length; Invoice.ToBytes(bytes, i); i += 16; } @@ -42559,7 +42586,7 @@ public override void FromBytes(byte[] bytes, ref int i) int length; try { - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Parameter = new byte[length]; Buffer.BlockCopy(bytes, i, Parameter, 0, length); i += length; } @@ -42571,7 +42598,7 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { - bytes[i++] = (byte)Parameter.Length; + Utils.ByteToBytes((byte)Parameter.Length, bytes, ref i); Buffer.BlockCopy(Parameter, 0, bytes, i, Parameter.Length); i += Parameter.Length; } @@ -42666,7 +42693,7 @@ public override byte[] ToBytes() Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); MethodData.ToBytes(bytes, ref i); - bytes[i++] = (byte)ParamList.Length; + Utils.ByteToBytes((byte)ParamList.Length, bytes, ref i); for (int j = 0; j < ParamList.Length; j++) { ParamList[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -42807,7 +42834,7 @@ public override void FromBytes(byte[] bytes, ref int i) int length; try { - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Method = new byte[length]; Buffer.BlockCopy(bytes, i, Method, 0, length); i += length; Invoice.FromBytes(bytes, i); i += 16; @@ -42820,7 +42847,7 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { - bytes[i++] = (byte)Method.Length; + Utils.ByteToBytes((byte)Method.Length, bytes, ref i); Buffer.BlockCopy(Method, 0, bytes, i, Method.Length); i += Method.Length; Invoice.ToBytes(bytes, i); i += 16; } @@ -42853,7 +42880,7 @@ public override void FromBytes(byte[] bytes, ref int i) int length; try { - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Parameter = new byte[length]; Buffer.BlockCopy(bytes, i, Parameter, 0, length); i += length; } @@ -42865,7 +42892,7 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { - bytes[i++] = (byte)Parameter.Length; + Utils.ByteToBytes((byte)Parameter.Length, bytes, ref i); Buffer.BlockCopy(Parameter, 0, bytes, i, Parameter.Length); i += Parameter.Length; } @@ -42960,7 +42987,7 @@ public override byte[] ToBytes() Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); MethodData.ToBytes(bytes, ref i); - bytes[i++] = (byte)ParamList.Length; + Utils.ByteToBytes((byte)ParamList.Length, bytes, ref i); for (int j = 0; j < ParamList.Length; j++) { ParamList[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -43259,7 +43286,7 @@ public override void FromBytes(byte[] bytes, ref int i) try { MuteID.FromBytes(bytes, i); i += 16; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); MuteName = new byte[length]; Buffer.BlockCopy(bytes, i, MuteName, 0, length); i += length; MuteType = Utils.BytesToIntSafepos(bytes, i); i +=4; @@ -43274,7 +43301,7 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { MuteID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)MuteName.Length; + Utils.ByteToBytes((byte)MuteName.Length, bytes, ref i); Buffer.BlockCopy(MuteName, 0, bytes, i, MuteName.Length); i += MuteName.Length; Utils.IntToBytesSafepos(MuteType, bytes, i); i += 4; Utils.UIntToBytesSafepos(MuteFlags, bytes, i); i += 4; @@ -43430,7 +43457,7 @@ public override void FromBytes(byte[] bytes, ref int i) try { MuteID.FromBytes(bytes, i); i += 16; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); MuteName = new byte[length]; Buffer.BlockCopy(bytes, i, MuteName, 0, length); i += length; } @@ -43443,7 +43470,7 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { MuteID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)MuteName.Length; + Utils.ByteToBytes((byte)MuteName.Length, bytes, ref i); Buffer.BlockCopy(MuteName, 0, bytes, i, MuteName.Length); i += MuteName.Length; } @@ -43740,7 +43767,7 @@ public override byte[] ToBytes() Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); NotecardData.ToBytes(bytes, ref i); - bytes[i++] = (byte)InventoryData.Length; + Utils.ByteToBytes((byte)InventoryData.Length, bytes, ref i); for (int j = 0; j < InventoryData.Length; j++) { InventoryData[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -43913,17 +43940,17 @@ public override void FromBytes(byte[] bytes, ref int i) GroupMask = Utils.BytesToUIntSafepos(bytes, i); i += 4; EveryoneMask = Utils.BytesToUIntSafepos(bytes, i); i += 4; NextOwnerMask = Utils.BytesToUIntSafepos(bytes, i); i += 4; - GroupOwned = (bytes[i++] != 0) ? (bool)true : (bool)false; + GroupOwned = (Utils.BytesToByte(bytes, ref i) != 0); TransactionID.FromBytes(bytes, i); i += 16; - Type = (sbyte)bytes[i++]; - InvType = (sbyte)bytes[i++]; + Type = (sbyte)Utils.BytesToByte(bytes, ref i); + InvType = (sbyte)Utils.BytesToByte(bytes, ref i); Flags = Utils.BytesToUIntSafepos(bytes, i); i += 4; - SaleType = (byte)bytes[i++]; + SaleType = Utils.BytesToByte(bytes, ref i); SalePrice = Utils.BytesToIntSafepos(bytes, i); i +=4; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Name = new byte[length]; Buffer.BlockCopy(bytes, i, Name, 0, length); i += length; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Description = new byte[length]; Buffer.BlockCopy(bytes, i, Description, 0, length); i += length; CreationDate = Utils.BytesToIntSafepos(bytes, i); i +=4; @@ -43948,16 +43975,16 @@ public override void ToBytes(byte[] bytes, ref int i) Utils.UIntToBytesSafepos(GroupMask, bytes, i); i += 4; Utils.UIntToBytesSafepos(EveryoneMask, bytes, i); i += 4; Utils.UIntToBytesSafepos(NextOwnerMask, bytes, i); i += 4; - bytes[i++] = (byte)((GroupOwned) ? 1 : 0); + Utils.ByteToBytes((byte)((GroupOwned) ? 1 : 0), bytes, ref i); TransactionID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)Type; - bytes[i++] = (byte)InvType; + Utils.ByteToBytes( (byte)Type, bytes, ref i); + Utils.ByteToBytes( (byte)InvType, bytes, ref i); Utils.UIntToBytesSafepos(Flags, bytes, i); i += 4; - bytes[i++] = SaleType; + Utils.ByteToBytes( SaleType, bytes, ref i); Utils.IntToBytesSafepos(SalePrice, bytes, i); i += 4; - bytes[i++] = (byte)Name.Length; + Utils.ByteToBytes((byte)Name.Length, bytes, ref i); Buffer.BlockCopy(Name, 0, bytes, i, Name.Length); i += Name.Length; - bytes[i++] = (byte)Description.Length; + Utils.ByteToBytes((byte)Description.Length, bytes, ref i); Buffer.BlockCopy(Description, 0, bytes, i, Description.Length); i += Description.Length; Utils.IntToBytesSafepos(CreationDate, bytes, i); i += 4; Utils.UIntToBytesSafepos(CRC, bytes, i); i += 4; @@ -44047,7 +44074,7 @@ public override byte[] ToBytes() int i = 0; Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); - bytes[i++] = (byte)InventoryData.Length; + Utils.ByteToBytes((byte)InventoryData.Length, bytes, ref i); for (int j = 0; j < InventoryData.Length; j++) { InventoryData[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -44141,7 +44168,7 @@ public override void FromBytes(byte[] bytes, ref int i) try { AgentID.FromBytes(bytes, i); i += 16; - SimApproved = (bytes[i++] != 0) ? (bool)true : (bool)false; + SimApproved = (Utils.BytesToByte(bytes, ref i) != 0); TransactionID.FromBytes(bytes, i); i += 16; } catch (Exception) @@ -44153,7 +44180,7 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { AgentID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)((SimApproved) ? 1 : 0); + Utils.ByteToBytes((byte)((SimApproved) ? 1 : 0), bytes, ref i); TransactionID.ToBytes(bytes, i); i += 16; } @@ -44218,17 +44245,17 @@ public override void FromBytes(byte[] bytes, ref int i) GroupMask = Utils.BytesToUIntSafepos(bytes, i); i += 4; EveryoneMask = Utils.BytesToUIntSafepos(bytes, i); i += 4; NextOwnerMask = Utils.BytesToUIntSafepos(bytes, i); i += 4; - GroupOwned = (bytes[i++] != 0) ? (bool)true : (bool)false; + GroupOwned = (Utils.BytesToByte(bytes, ref i) != 0); AssetID.FromBytes(bytes, i); i += 16; - Type = (sbyte)bytes[i++]; - InvType = (sbyte)bytes[i++]; + Type = (sbyte)Utils.BytesToByte(bytes, ref i); + InvType = (sbyte)Utils.BytesToByte(bytes, ref i); Flags = Utils.BytesToUIntSafepos(bytes, i); i += 4; - SaleType = (byte)bytes[i++]; + SaleType = Utils.BytesToByte(bytes, ref i); SalePrice = Utils.BytesToIntSafepos(bytes, i); i +=4; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Name = new byte[length]; Buffer.BlockCopy(bytes, i, Name, 0, length); i += length; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Description = new byte[length]; Buffer.BlockCopy(bytes, i, Description, 0, length); i += length; CreationDate = Utils.BytesToIntSafepos(bytes, i); i +=4; @@ -44253,16 +44280,16 @@ public override void ToBytes(byte[] bytes, ref int i) Utils.UIntToBytesSafepos(GroupMask, bytes, i); i += 4; Utils.UIntToBytesSafepos(EveryoneMask, bytes, i); i += 4; Utils.UIntToBytesSafepos(NextOwnerMask, bytes, i); i += 4; - bytes[i++] = (byte)((GroupOwned) ? 1 : 0); + Utils.ByteToBytes((byte)((GroupOwned) ? 1 : 0), bytes, ref i); AssetID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)Type; - bytes[i++] = (byte)InvType; + Utils.ByteToBytes( (byte)Type, bytes, ref i); + Utils.ByteToBytes( (byte)InvType, bytes, ref i); Utils.UIntToBytesSafepos(Flags, bytes, i); i += 4; - bytes[i++] = SaleType; + Utils.ByteToBytes( SaleType, bytes, ref i); Utils.IntToBytesSafepos(SalePrice, bytes, i); i += 4; - bytes[i++] = (byte)Name.Length; + Utils.ByteToBytes((byte)Name.Length, bytes, ref i); Buffer.BlockCopy(Name, 0, bytes, i, Name.Length); i += Name.Length; - bytes[i++] = (byte)Description.Length; + Utils.ByteToBytes((byte)Description.Length, bytes, ref i); Buffer.BlockCopy(Description, 0, bytes, i, Description.Length); i += Description.Length; Utils.IntToBytesSafepos(CreationDate, bytes, i); i += 4; Utils.UIntToBytesSafepos(CRC, bytes, i); i += 4; @@ -44352,7 +44379,7 @@ public override byte[] ToBytes() int i = 0; Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); - bytes[i++] = (byte)InventoryData.Length; + Utils.ByteToBytes((byte)InventoryData.Length, bytes, ref i); for (int j = 0; j < InventoryData.Length; j++) { InventoryData[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -44447,7 +44474,7 @@ public override void FromBytes(byte[] bytes, ref int i) { AgentID.FromBytes(bytes, i); i += 16; SessionID.FromBytes(bytes, i); i += 16; - Stamp = (bytes[i++] != 0) ? (bool)true : (bool)false; + Stamp = (Utils.BytesToByte(bytes, ref i) != 0); } catch (Exception) { @@ -44459,7 +44486,7 @@ public override void ToBytes(byte[] bytes, ref int i) { AgentID.ToBytes(bytes, i); i += 16; SessionID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)((Stamp) ? 1 : 0); + Utils.ByteToBytes((byte)((Stamp) ? 1 : 0), bytes, ref i); } } @@ -44494,7 +44521,7 @@ public override void FromBytes(byte[] bytes, ref int i) { ItemID.FromBytes(bytes, i); i += 16; FolderID.FromBytes(bytes, i); i += 16; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); NewName = new byte[length]; Buffer.BlockCopy(bytes, i, NewName, 0, length); i += length; } @@ -44508,7 +44535,7 @@ public override void ToBytes(byte[] bytes, ref int i) { ItemID.ToBytes(bytes, i); i += 16; FolderID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)NewName.Length; + Utils.ByteToBytes((byte)NewName.Length, bytes, ref i); Buffer.BlockCopy(NewName, 0, bytes, i, NewName.Length); i += NewName.Length; } @@ -44596,7 +44623,7 @@ public override byte[] ToBytes() int i = 0; Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); - bytes[i++] = (byte)InventoryData.Length; + Utils.ByteToBytes((byte)InventoryData.Length, bytes, ref i); for (int j = 0; j < InventoryData.Length; j++) { InventoryData[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -44739,7 +44766,7 @@ public override void FromBytes(byte[] bytes, ref int i) OldAgentID.FromBytes(bytes, i); i += 16; OldItemID.FromBytes(bytes, i); i += 16; NewFolderID.FromBytes(bytes, i); i += 16; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); NewName = new byte[length]; Buffer.BlockCopy(bytes, i, NewName, 0, length); i += length; } @@ -44755,7 +44782,7 @@ public override void ToBytes(byte[] bytes, ref int i) OldAgentID.ToBytes(bytes, i); i += 16; OldItemID.ToBytes(bytes, i); i += 16; NewFolderID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)NewName.Length; + Utils.ByteToBytes((byte)NewName.Length, bytes, ref i); Buffer.BlockCopy(NewName, 0, bytes, i, NewName.Length); i += NewName.Length; } @@ -44843,7 +44870,7 @@ public override byte[] ToBytes() int i = 0; Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); - bytes[i++] = (byte)InventoryData.Length; + Utils.ByteToBytes((byte)InventoryData.Length, bytes, ref i); for (int j = 0; j < InventoryData.Length; j++) { InventoryData[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -45071,7 +45098,7 @@ public override byte[] ToBytes() int i = 0; Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); - bytes[i++] = (byte)InventoryData.Length; + Utils.ByteToBytes((byte)InventoryData.Length, bytes, ref i); for (int j = 0; j < InventoryData.Length; j++) { InventoryData[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -45302,7 +45329,7 @@ public override byte[] ToBytes() int i = 0; Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); - bytes[i++] = (byte)InventoryData.Length; + Utils.ByteToBytes((byte)InventoryData.Length, bytes, ref i); for (int j = 0; j < InventoryData.Length; j++) { InventoryData[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -45600,8 +45627,8 @@ public override void FromBytes(byte[] bytes, ref int i) { FolderID.FromBytes(bytes, i); i += 16; ParentID.FromBytes(bytes, i); i += 16; - Type = (sbyte)bytes[i++]; - length = bytes[i++]; + Type = (sbyte)Utils.BytesToByte(bytes, ref i); + length = Utils.BytesToByte(bytes, ref i); Name = new byte[length]; Buffer.BlockCopy(bytes, i, Name, 0, length); i += length; } @@ -45615,8 +45642,8 @@ public override void ToBytes(byte[] bytes, ref int i) { FolderID.ToBytes(bytes, i); i += 16; ParentID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)Type; - bytes[i++] = (byte)Name.Length; + Utils.ByteToBytes( (byte)Type, bytes, ref i); + Utils.ByteToBytes((byte)Name.Length, bytes, ref i); Buffer.BlockCopy(Name, 0, bytes, i, Name.Length); i += Name.Length; } @@ -45773,8 +45800,8 @@ public override void FromBytes(byte[] bytes, ref int i) { FolderID.FromBytes(bytes, i); i += 16; ParentID.FromBytes(bytes, i); i += 16; - Type = (sbyte)bytes[i++]; - length = bytes[i++]; + Type = (sbyte)Utils.BytesToByte(bytes, ref i); + length = Utils.BytesToByte(bytes, ref i); Name = new byte[length]; Buffer.BlockCopy(bytes, i, Name, 0, length); i += length; } @@ -45788,8 +45815,8 @@ public override void ToBytes(byte[] bytes, ref int i) { FolderID.ToBytes(bytes, i); i += 16; ParentID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)Type; - bytes[i++] = (byte)Name.Length; + Utils.ByteToBytes( (byte)Type, bytes, ref i); + Utils.ByteToBytes((byte)Name.Length, bytes, ref i); Buffer.BlockCopy(Name, 0, bytes, i, Name.Length); i += Name.Length; } @@ -45876,7 +45903,7 @@ public override byte[] ToBytes() int i = 0; Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); - bytes[i++] = (byte)FolderData.Length; + Utils.ByteToBytes((byte)FolderData.Length, bytes, ref i); for (int j = 0; j < FolderData.Length; j++) { FolderData[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -45971,7 +45998,7 @@ public override void FromBytes(byte[] bytes, ref int i) { AgentID.FromBytes(bytes, i); i += 16; SessionID.FromBytes(bytes, i); i += 16; - Stamp = (bytes[i++] != 0) ? (bool)true : (bool)false; + Stamp = (Utils.BytesToByte(bytes, ref i) != 0); } catch (Exception) { @@ -45983,7 +46010,7 @@ public override void ToBytes(byte[] bytes, ref int i) { AgentID.ToBytes(bytes, i); i += 16; SessionID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)((Stamp) ? 1 : 0); + Utils.ByteToBytes((byte)((Stamp) ? 1 : 0), bytes, ref i); } } @@ -46111,7 +46138,7 @@ public override byte[] ToBytes() int i = 0; Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); - bytes[i++] = (byte)InventoryData.Length; + Utils.ByteToBytes((byte)InventoryData.Length, bytes, ref i); for (int j = 0; j < InventoryData.Length; j++) { InventoryData[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -46339,7 +46366,7 @@ public override byte[] ToBytes() int i = 0; Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); - bytes[i++] = (byte)FolderData.Length; + Utils.ByteToBytes((byte)FolderData.Length, bytes, ref i); for (int j = 0; j < FolderData.Length; j++) { FolderData[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -46478,8 +46505,8 @@ public override void FromBytes(byte[] bytes, ref int i) FolderID.FromBytes(bytes, i); i += 16; OwnerID.FromBytes(bytes, i); i += 16; SortOrder = Utils.BytesToIntSafepos(bytes, i); i +=4; - FetchFolders = (bytes[i++] != 0) ? (bool)true : (bool)false; - FetchItems = (bytes[i++] != 0) ? (bool)true : (bool)false; + FetchFolders = (Utils.BytesToByte(bytes, ref i) != 0); + FetchItems = (Utils.BytesToByte(bytes, ref i) != 0); } catch (Exception) { @@ -46492,8 +46519,8 @@ public override void ToBytes(byte[] bytes, ref int i) FolderID.ToBytes(bytes, i); i += 16; OwnerID.ToBytes(bytes, i); i += 16; Utils.IntToBytesSafepos(SortOrder, bytes, i); i += 4; - bytes[i++] = (byte)((FetchFolders) ? 1 : 0); - bytes[i++] = (byte)((FetchItems) ? 1 : 0); + Utils.ByteToBytes((byte)((FetchFolders) ? 1 : 0), bytes, ref i); + Utils.ByteToBytes((byte)((FetchItems) ? 1 : 0), bytes, ref i); } } @@ -46659,8 +46686,8 @@ public override void FromBytes(byte[] bytes, ref int i) { FolderID.FromBytes(bytes, i); i += 16; ParentID.FromBytes(bytes, i); i += 16; - Type = (sbyte)bytes[i++]; - length = bytes[i++]; + Type = (sbyte)Utils.BytesToByte(bytes, ref i); + length = Utils.BytesToByte(bytes, ref i); Name = new byte[length]; Buffer.BlockCopy(bytes, i, Name, 0, length); i += length; } @@ -46674,8 +46701,8 @@ public override void ToBytes(byte[] bytes, ref int i) { FolderID.ToBytes(bytes, i); i += 16; ParentID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)Type; - bytes[i++] = (byte)Name.Length; + Utils.ByteToBytes( (byte)Type, bytes, ref i); + Utils.ByteToBytes((byte)Name.Length, bytes, ref i); Buffer.BlockCopy(Name, 0, bytes, i, Name.Length); i += Name.Length; } @@ -46738,17 +46765,17 @@ public override void FromBytes(byte[] bytes, ref int i) GroupMask = Utils.BytesToUIntSafepos(bytes, i); i += 4; EveryoneMask = Utils.BytesToUIntSafepos(bytes, i); i += 4; NextOwnerMask = Utils.BytesToUIntSafepos(bytes, i); i += 4; - GroupOwned = (bytes[i++] != 0) ? (bool)true : (bool)false; + GroupOwned = (Utils.BytesToByte(bytes, ref i) != 0); AssetID.FromBytes(bytes, i); i += 16; - Type = (sbyte)bytes[i++]; - InvType = (sbyte)bytes[i++]; + Type = (sbyte)Utils.BytesToByte(bytes, ref i); + InvType = (sbyte)Utils.BytesToByte(bytes, ref i); Flags = Utils.BytesToUIntSafepos(bytes, i); i += 4; - SaleType = (byte)bytes[i++]; + SaleType = Utils.BytesToByte(bytes, ref i); SalePrice = Utils.BytesToIntSafepos(bytes, i); i +=4; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Name = new byte[length]; Buffer.BlockCopy(bytes, i, Name, 0, length); i += length; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Description = new byte[length]; Buffer.BlockCopy(bytes, i, Description, 0, length); i += length; CreationDate = Utils.BytesToIntSafepos(bytes, i); i +=4; @@ -46772,16 +46799,16 @@ public override void ToBytes(byte[] bytes, ref int i) Utils.UIntToBytesSafepos(GroupMask, bytes, i); i += 4; Utils.UIntToBytesSafepos(EveryoneMask, bytes, i); i += 4; Utils.UIntToBytesSafepos(NextOwnerMask, bytes, i); i += 4; - bytes[i++] = (byte)((GroupOwned) ? 1 : 0); + Utils.ByteToBytes((byte)((GroupOwned) ? 1 : 0), bytes, ref i); AssetID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)Type; - bytes[i++] = (byte)InvType; + Utils.ByteToBytes( (byte)Type, bytes, ref i); + Utils.ByteToBytes( (byte)InvType, bytes, ref i); Utils.UIntToBytesSafepos(Flags, bytes, i); i += 4; - bytes[i++] = SaleType; + Utils.ByteToBytes( SaleType, bytes, ref i); Utils.IntToBytesSafepos(SalePrice, bytes, i); i += 4; - bytes[i++] = (byte)Name.Length; + Utils.ByteToBytes((byte)Name.Length, bytes, ref i); Buffer.BlockCopy(Name, 0, bytes, i, Name.Length); i += Name.Length; - bytes[i++] = (byte)Description.Length; + Utils.ByteToBytes((byte)Description.Length, bytes, ref i); Buffer.BlockCopy(Description, 0, bytes, i, Description.Length); i += Description.Length; Utils.IntToBytesSafepos(CreationDate, bytes, i); i += 4; Utils.UIntToBytesSafepos(CRC, bytes, i); i += 4; @@ -46893,9 +46920,9 @@ public override byte[] ToBytes() int i = 0; Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); - bytes[i++] = (byte)FolderData.Length; + Utils.ByteToBytes((byte)FolderData.Length, bytes, ref i); for (int j = 0; j < FolderData.Length; j++) { FolderData[j].ToBytes(bytes, ref i); } - bytes[i++] = (byte)ItemData.Length; + Utils.ByteToBytes((byte)ItemData.Length, bytes, ref i); for (int j = 0; j < ItemData.Length; j++) { ItemData[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -47145,7 +47172,7 @@ public override byte[] ToBytes() int i = 0; Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); - bytes[i++] = (byte)InventoryData.Length; + Utils.ByteToBytes((byte)InventoryData.Length, bytes, ref i); for (int j = 0; j < InventoryData.Length; j++) { InventoryData[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -47308,17 +47335,17 @@ public override void FromBytes(byte[] bytes, ref int i) GroupMask = Utils.BytesToUIntSafepos(bytes, i); i += 4; EveryoneMask = Utils.BytesToUIntSafepos(bytes, i); i += 4; NextOwnerMask = Utils.BytesToUIntSafepos(bytes, i); i += 4; - GroupOwned = (bytes[i++] != 0) ? (bool)true : (bool)false; + GroupOwned = (Utils.BytesToByte(bytes, ref i) != 0); AssetID.FromBytes(bytes, i); i += 16; - Type = (sbyte)bytes[i++]; - InvType = (sbyte)bytes[i++]; + Type = (sbyte)Utils.BytesToByte(bytes, ref i); + InvType = (sbyte)Utils.BytesToByte(bytes, ref i); Flags = Utils.BytesToUIntSafepos(bytes, i); i += 4; - SaleType = (byte)bytes[i++]; + SaleType = Utils.BytesToByte(bytes, ref i); SalePrice = Utils.BytesToIntSafepos(bytes, i); i +=4; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Name = new byte[length]; Buffer.BlockCopy(bytes, i, Name, 0, length); i += length; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Description = new byte[length]; Buffer.BlockCopy(bytes, i, Description, 0, length); i += length; CreationDate = Utils.BytesToIntSafepos(bytes, i); i +=4; @@ -47342,16 +47369,16 @@ public override void ToBytes(byte[] bytes, ref int i) Utils.UIntToBytesSafepos(GroupMask, bytes, i); i += 4; Utils.UIntToBytesSafepos(EveryoneMask, bytes, i); i += 4; Utils.UIntToBytesSafepos(NextOwnerMask, bytes, i); i += 4; - bytes[i++] = (byte)((GroupOwned) ? 1 : 0); + Utils.ByteToBytes((byte)((GroupOwned) ? 1 : 0), bytes, ref i); AssetID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)Type; - bytes[i++] = (byte)InvType; + Utils.ByteToBytes( (byte)Type, bytes, ref i); + Utils.ByteToBytes( (byte)InvType, bytes, ref i); Utils.UIntToBytesSafepos(Flags, bytes, i); i += 4; - bytes[i++] = SaleType; + Utils.ByteToBytes( SaleType, bytes, ref i); Utils.IntToBytesSafepos(SalePrice, bytes, i); i += 4; - bytes[i++] = (byte)Name.Length; + Utils.ByteToBytes((byte)Name.Length, bytes, ref i); Buffer.BlockCopy(Name, 0, bytes, i, Name.Length); i += Name.Length; - bytes[i++] = (byte)Description.Length; + Utils.ByteToBytes((byte)Description.Length, bytes, ref i); Buffer.BlockCopy(Description, 0, bytes, i, Description.Length); i += Description.Length; Utils.IntToBytesSafepos(CreationDate, bytes, i); i += 4; Utils.UIntToBytesSafepos(CRC, bytes, i); i += 4; @@ -47441,7 +47468,7 @@ public override byte[] ToBytes() int i = 0; Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); - bytes[i++] = (byte)InventoryData.Length; + Utils.ByteToBytes((byte)InventoryData.Length, bytes, ref i); for (int j = 0; j < InventoryData.Length; j++) { InventoryData[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -47581,8 +47608,8 @@ public override void FromBytes(byte[] bytes, ref int i) { FolderID.FromBytes(bytes, i); i += 16; ParentID.FromBytes(bytes, i); i += 16; - Type = (sbyte)bytes[i++]; - length = bytes[i++]; + Type = (sbyte)Utils.BytesToByte(bytes, ref i); + length = Utils.BytesToByte(bytes, ref i); Name = new byte[length]; Buffer.BlockCopy(bytes, i, Name, 0, length); i += length; } @@ -47596,8 +47623,8 @@ public override void ToBytes(byte[] bytes, ref int i) { FolderID.ToBytes(bytes, i); i += 16; ParentID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)Type; - bytes[i++] = (byte)Name.Length; + Utils.ByteToBytes( (byte)Type, bytes, ref i); + Utils.ByteToBytes((byte)Name.Length, bytes, ref i); Buffer.BlockCopy(Name, 0, bytes, i, Name.Length); i += Name.Length; } @@ -47662,17 +47689,17 @@ public override void FromBytes(byte[] bytes, ref int i) GroupMask = Utils.BytesToUIntSafepos(bytes, i); i += 4; EveryoneMask = Utils.BytesToUIntSafepos(bytes, i); i += 4; NextOwnerMask = Utils.BytesToUIntSafepos(bytes, i); i += 4; - GroupOwned = (bytes[i++] != 0) ? (bool)true : (bool)false; + GroupOwned = (Utils.BytesToByte(bytes, ref i) != 0); AssetID.FromBytes(bytes, i); i += 16; - Type = (sbyte)bytes[i++]; - InvType = (sbyte)bytes[i++]; + Type = (sbyte)Utils.BytesToByte(bytes, ref i); + InvType = (sbyte)Utils.BytesToByte(bytes, ref i); Flags = Utils.BytesToUIntSafepos(bytes, i); i += 4; - SaleType = (byte)bytes[i++]; + SaleType = Utils.BytesToByte(bytes, ref i); SalePrice = Utils.BytesToIntSafepos(bytes, i); i +=4; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Name = new byte[length]; Buffer.BlockCopy(bytes, i, Name, 0, length); i += length; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Description = new byte[length]; Buffer.BlockCopy(bytes, i, Description, 0, length); i += length; CreationDate = Utils.BytesToIntSafepos(bytes, i); i +=4; @@ -47697,16 +47724,16 @@ public override void ToBytes(byte[] bytes, ref int i) Utils.UIntToBytesSafepos(GroupMask, bytes, i); i += 4; Utils.UIntToBytesSafepos(EveryoneMask, bytes, i); i += 4; Utils.UIntToBytesSafepos(NextOwnerMask, bytes, i); i += 4; - bytes[i++] = (byte)((GroupOwned) ? 1 : 0); + Utils.ByteToBytes((byte)((GroupOwned) ? 1 : 0), bytes, ref i); AssetID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)Type; - bytes[i++] = (byte)InvType; + Utils.ByteToBytes( (byte)Type, bytes, ref i); + Utils.ByteToBytes( (byte)InvType, bytes, ref i); Utils.UIntToBytesSafepos(Flags, bytes, i); i += 4; - bytes[i++] = SaleType; + Utils.ByteToBytes( SaleType, bytes, ref i); Utils.IntToBytesSafepos(SalePrice, bytes, i); i += 4; - bytes[i++] = (byte)Name.Length; + Utils.ByteToBytes((byte)Name.Length, bytes, ref i); Buffer.BlockCopy(Name, 0, bytes, i, Name.Length); i += Name.Length; - bytes[i++] = (byte)Description.Length; + Utils.ByteToBytes((byte)Description.Length, bytes, ref i); Buffer.BlockCopy(Description, 0, bytes, i, Description.Length); i += Description.Length; Utils.IntToBytesSafepos(CreationDate, bytes, i); i += 4; Utils.UIntToBytesSafepos(CRC, bytes, i); i += 4; @@ -47818,9 +47845,9 @@ public override byte[] ToBytes() int i = 0; Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); - bytes[i++] = (byte)FolderData.Length; + Utils.ByteToBytes((byte)FolderData.Length, bytes, ref i); for (int j = 0; j < FolderData.Length; j++) { FolderData[j].ToBytes(bytes, ref i); } - bytes[i++] = (byte)ItemData.Length; + Utils.ByteToBytes((byte)ItemData.Length, bytes, ref i); for (int j = 0; j < ItemData.Length; j++) { ItemData[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -48126,9 +48153,9 @@ public override byte[] ToBytes() int i = 0; Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); - bytes[i++] = (byte)FolderData.Length; + Utils.ByteToBytes((byte)FolderData.Length, bytes, ref i); for (int j = 0; j < FolderData.Length; j++) { FolderData[j].ToBytes(bytes, ref i); } - bytes[i++] = (byte)ItemData.Length; + Utils.ByteToBytes((byte)ItemData.Length, bytes, ref i); for (int j = 0; j < ItemData.Length; j++) { ItemData[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -48439,7 +48466,7 @@ public override void FromBytes(byte[] bytes, ref int i) try { LocalID = Utils.BytesToUIntSafepos(bytes, i); i += 4; - Key = (byte)bytes[i++]; + Key = Utils.BytesToByte(bytes, ref i); } catch (Exception) { @@ -48450,7 +48477,7 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { Utils.UIntToBytesSafepos(LocalID, bytes, i); i += 4; - bytes[i++] = Key; + Utils.ByteToBytes( Key, bytes, ref i); } } @@ -48512,17 +48539,17 @@ public override void FromBytes(byte[] bytes, ref int i) GroupMask = Utils.BytesToUIntSafepos(bytes, i); i += 4; EveryoneMask = Utils.BytesToUIntSafepos(bytes, i); i += 4; NextOwnerMask = Utils.BytesToUIntSafepos(bytes, i); i += 4; - GroupOwned = (bytes[i++] != 0) ? (bool)true : (bool)false; + GroupOwned = (Utils.BytesToByte(bytes, ref i) != 0); TransactionID.FromBytes(bytes, i); i += 16; - Type = (sbyte)bytes[i++]; - InvType = (sbyte)bytes[i++]; + Type = (sbyte)Utils.BytesToByte(bytes, ref i); + InvType = (sbyte)Utils.BytesToByte(bytes, ref i); Flags = Utils.BytesToUIntSafepos(bytes, i); i += 4; - SaleType = (byte)bytes[i++]; + SaleType = Utils.BytesToByte(bytes, ref i); SalePrice = Utils.BytesToIntSafepos(bytes, i); i +=4; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Name = new byte[length]; Buffer.BlockCopy(bytes, i, Name, 0, length); i += length; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Description = new byte[length]; Buffer.BlockCopy(bytes, i, Description, 0, length); i += length; CreationDate = Utils.BytesToIntSafepos(bytes, i); i +=4; @@ -48546,16 +48573,16 @@ public override void ToBytes(byte[] bytes, ref int i) Utils.UIntToBytesSafepos(GroupMask, bytes, i); i += 4; Utils.UIntToBytesSafepos(EveryoneMask, bytes, i); i += 4; Utils.UIntToBytesSafepos(NextOwnerMask, bytes, i); i += 4; - bytes[i++] = (byte)((GroupOwned) ? 1 : 0); + Utils.ByteToBytes((byte)((GroupOwned) ? 1 : 0), bytes, ref i); TransactionID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)Type; - bytes[i++] = (byte)InvType; + Utils.ByteToBytes( (byte)Type, bytes, ref i); + Utils.ByteToBytes( (byte)InvType, bytes, ref i); Utils.UIntToBytesSafepos(Flags, bytes, i); i += 4; - bytes[i++] = SaleType; + Utils.ByteToBytes( SaleType, bytes, ref i); Utils.IntToBytesSafepos(SalePrice, bytes, i); i += 4; - bytes[i++] = (byte)Name.Length; + Utils.ByteToBytes((byte)Name.Length, bytes, ref i); Buffer.BlockCopy(Name, 0, bytes, i, Name.Length); i += Name.Length; - bytes[i++] = (byte)Description.Length; + Utils.ByteToBytes((byte)Description.Length, bytes, ref i); Buffer.BlockCopy(Description, 0, bytes, i, Description.Length); i += Description.Length; Utils.IntToBytesSafepos(CreationDate, bytes, i); i += 4; Utils.UIntToBytesSafepos(CRC, bytes, i); i += 4; @@ -49164,7 +49191,7 @@ public override void FromBytes(byte[] bytes, ref int i) { TaskID.FromBytes(bytes, i); i += 16; Serial = Utils.BytesToInt16(bytes, i); i+=2; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Filename = new byte[length]; Buffer.BlockCopy(bytes, i, Filename, 0, length); i += length; } @@ -49178,7 +49205,7 @@ public override void ToBytes(byte[] bytes, ref int i) { TaskID.ToBytes(bytes, i); i += 16; Utils.Int16ToBytes(Serial, bytes, i); i += 2; - bytes[i++] = (byte)Filename.Length; + Utils.ByteToBytes((byte)Filename.Length, bytes, ref i); Buffer.BlockCopy(Filename, 0, bytes, i, Filename.Length); i += Filename.Length; } @@ -49327,11 +49354,11 @@ public override void FromBytes(byte[] bytes, ref int i) try { GroupID.FromBytes(bytes, i); i += 16; - Destination = (byte)bytes[i++]; + Destination = Utils.BytesToByte(bytes, ref i); DestinationID.FromBytes(bytes, i); i += 16; TransactionID.FromBytes(bytes, i); i += 16; - PacketCount = (byte)bytes[i++]; - PacketNumber = (byte)bytes[i++]; + PacketCount = Utils.BytesToByte(bytes, ref i); + PacketNumber = Utils.BytesToByte(bytes, ref i); } catch (Exception) { @@ -49342,11 +49369,11 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { GroupID.ToBytes(bytes, i); i += 16; - bytes[i++] = Destination; + Utils.ByteToBytes( Destination, bytes, ref i); DestinationID.ToBytes(bytes, i); i += 16; TransactionID.ToBytes(bytes, i); i += 16; - bytes[i++] = PacketCount; - bytes[i++] = PacketNumber; + Utils.ByteToBytes( PacketCount, bytes, ref i); + Utils.ByteToBytes( PacketNumber, bytes, ref i); } } @@ -49478,7 +49505,7 @@ public override byte[] ToBytes() Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); AgentBlock.ToBytes(bytes, ref i); - bytes[i++] = (byte)ObjectData.Length; + Utils.ByteToBytes((byte)ObjectData.Length, bytes, ref i); for (int j = 0; j < ObjectData.Length; j++) { ObjectData[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -49573,7 +49600,7 @@ public override void FromBytes(byte[] bytes, ref int i) try { TransactionID.FromBytes(bytes, i); i += 16; - Success = (bytes[i++] != 0) ? (bool)true : (bool)false; + Success = (Utils.BytesToByte(bytes, ref i) != 0); } catch (Exception) { @@ -49584,7 +49611,7 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { TransactionID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)((Success) ? 1 : 0); + Utils.ByteToBytes((byte)((Success) ? 1 : 0), bytes, ref i); } } @@ -49740,13 +49767,13 @@ public override void FromBytes(byte[] bytes, ref int i) try { FromTaskID.FromBytes(bytes, i); i += 16; - BypassRaycast = (byte)bytes[i++]; + BypassRaycast = Utils.BytesToByte(bytes, ref i); RayStart.FromBytes(bytes, i); i += 12; RayEnd.FromBytes(bytes, i); i += 12; RayTargetID.FromBytes(bytes, i); i += 16; - RayEndIsIntersection = (bytes[i++] != 0) ? (bool)true : (bool)false; - RezSelected = (bytes[i++] != 0) ? (bool)true : (bool)false; - RemoveItem = (bytes[i++] != 0) ? (bool)true : (bool)false; + RayEndIsIntersection = (Utils.BytesToByte(bytes, ref i) != 0); + RezSelected = (Utils.BytesToByte(bytes, ref i) != 0); + RemoveItem = (Utils.BytesToByte(bytes, ref i) != 0); ItemFlags = Utils.BytesToUIntSafepos(bytes, i); i += 4; GroupMask = Utils.BytesToUIntSafepos(bytes, i); i += 4; EveryoneMask = Utils.BytesToUIntSafepos(bytes, i); i += 4; @@ -49761,13 +49788,13 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { FromTaskID.ToBytes(bytes, i); i += 16; - bytes[i++] = BypassRaycast; + Utils.ByteToBytes( BypassRaycast, bytes, ref i); RayStart.ToBytes(bytes, i); i += 12; RayEnd.ToBytes(bytes, i); i += 12; RayTargetID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)((RayEndIsIntersection) ? 1 : 0); - bytes[i++] = (byte)((RezSelected) ? 1 : 0); - bytes[i++] = (byte)((RemoveItem) ? 1 : 0); + Utils.ByteToBytes((byte)((RayEndIsIntersection) ? 1 : 0), bytes, ref i); + Utils.ByteToBytes((byte)((RezSelected) ? 1 : 0), bytes, ref i); + Utils.ByteToBytes((byte)((RemoveItem) ? 1 : 0), bytes, ref i); Utils.UIntToBytesSafepos(ItemFlags, bytes, i); i += 4; Utils.UIntToBytesSafepos(GroupMask, bytes, i); i += 4; Utils.UIntToBytesSafepos(EveryoneMask, bytes, i); i += 4; @@ -49833,17 +49860,17 @@ public override void FromBytes(byte[] bytes, ref int i) GroupMask = Utils.BytesToUIntSafepos(bytes, i); i += 4; EveryoneMask = Utils.BytesToUIntSafepos(bytes, i); i += 4; NextOwnerMask = Utils.BytesToUIntSafepos(bytes, i); i += 4; - GroupOwned = (bytes[i++] != 0) ? (bool)true : (bool)false; + GroupOwned = (Utils.BytesToByte(bytes, ref i) != 0); TransactionID.FromBytes(bytes, i); i += 16; - Type = (sbyte)bytes[i++]; - InvType = (sbyte)bytes[i++]; + Type = (sbyte)Utils.BytesToByte(bytes, ref i); + InvType = (sbyte)Utils.BytesToByte(bytes, ref i); Flags = Utils.BytesToUIntSafepos(bytes, i); i += 4; - SaleType = (byte)bytes[i++]; + SaleType = Utils.BytesToByte(bytes, ref i); SalePrice = Utils.BytesToIntSafepos(bytes, i); i +=4; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Name = new byte[length]; Buffer.BlockCopy(bytes, i, Name, 0, length); i += length; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Description = new byte[length]; Buffer.BlockCopy(bytes, i, Description, 0, length); i += length; CreationDate = Utils.BytesToIntSafepos(bytes, i); i +=4; @@ -49867,16 +49894,16 @@ public override void ToBytes(byte[] bytes, ref int i) Utils.UIntToBytesSafepos(GroupMask, bytes, i); i += 4; Utils.UIntToBytesSafepos(EveryoneMask, bytes, i); i += 4; Utils.UIntToBytesSafepos(NextOwnerMask, bytes, i); i += 4; - bytes[i++] = (byte)((GroupOwned) ? 1 : 0); + Utils.ByteToBytes((byte)((GroupOwned) ? 1 : 0), bytes, ref i); TransactionID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)Type; - bytes[i++] = (byte)InvType; + Utils.ByteToBytes( (byte)Type, bytes, ref i); + Utils.ByteToBytes( (byte)InvType, bytes, ref i); Utils.UIntToBytesSafepos(Flags, bytes, i); i += 4; - bytes[i++] = SaleType; + Utils.ByteToBytes( SaleType, bytes, ref i); Utils.IntToBytesSafepos(SalePrice, bytes, i); i += 4; - bytes[i++] = (byte)Name.Length; + Utils.ByteToBytes((byte)Name.Length, bytes, ref i); Buffer.BlockCopy(Name, 0, bytes, i, Name.Length); i += Name.Length; - bytes[i++] = (byte)Description.Length; + Utils.ByteToBytes((byte)Description.Length, bytes, ref i); Buffer.BlockCopy(Description, 0, bytes, i, Description.Length); i += Description.Length; Utils.IntToBytesSafepos(CreationDate, bytes, i); i += 4; Utils.UIntToBytesSafepos(CRC, bytes, i); i += 4; @@ -50050,13 +50077,13 @@ public override void FromBytes(byte[] bytes, ref int i) try { FromTaskID.FromBytes(bytes, i); i += 16; - BypassRaycast = (byte)bytes[i++]; + BypassRaycast = Utils.BytesToByte(bytes, ref i); RayStart.FromBytes(bytes, i); i += 12; RayEnd.FromBytes(bytes, i); i += 12; RayTargetID.FromBytes(bytes, i); i += 16; - RayEndIsIntersection = (bytes[i++] != 0) ? (bool)true : (bool)false; - RezSelected = (bytes[i++] != 0) ? (bool)true : (bool)false; - RemoveItem = (bytes[i++] != 0) ? (bool)true : (bool)false; + RayEndIsIntersection = (Utils.BytesToByte(bytes, ref i) != 0); + RezSelected = (Utils.BytesToByte(bytes, ref i) != 0); + RemoveItem = (Utils.BytesToByte(bytes, ref i) != 0); ItemFlags = Utils.BytesToUIntSafepos(bytes, i); i += 4; GroupMask = Utils.BytesToUIntSafepos(bytes, i); i += 4; EveryoneMask = Utils.BytesToUIntSafepos(bytes, i); i += 4; @@ -50071,13 +50098,13 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { FromTaskID.ToBytes(bytes, i); i += 16; - bytes[i++] = BypassRaycast; + Utils.ByteToBytes( BypassRaycast, bytes, ref i); RayStart.ToBytes(bytes, i); i += 12; RayEnd.ToBytes(bytes, i); i += 12; RayTargetID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)((RayEndIsIntersection) ? 1 : 0); - bytes[i++] = (byte)((RezSelected) ? 1 : 0); - bytes[i++] = (byte)((RemoveItem) ? 1 : 0); + Utils.ByteToBytes((byte)((RayEndIsIntersection) ? 1 : 0), bytes, ref i); + Utils.ByteToBytes((byte)((RezSelected) ? 1 : 0), bytes, ref i); + Utils.ByteToBytes((byte)((RemoveItem) ? 1 : 0), bytes, ref i); Utils.UIntToBytesSafepos(ItemFlags, bytes, i); i += 4; Utils.UIntToBytesSafepos(GroupMask, bytes, i); i += 4; Utils.UIntToBytesSafepos(EveryoneMask, bytes, i); i += 4; @@ -50261,7 +50288,7 @@ public override byte[] ToBytes() AgentData.ToBytes(bytes, ref i); RezData.ToBytes(bytes, ref i); NotecardData.ToBytes(bytes, ref i); - bytes[i++] = (byte)InventoryData.Length; + Utils.ByteToBytes((byte)InventoryData.Length, bytes, ref i); for (int j = 0; j < InventoryData.Length; j++) { InventoryData[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -50538,7 +50565,7 @@ public override byte[] ToBytes() Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); TransactionBlock.ToBytes(bytes, ref i); - bytes[i++] = (byte)FolderData.Length; + Utils.ByteToBytes((byte)FolderData.Length, bytes, ref i); for (int j = 0; j < FolderData.Length; j++) { FolderData[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -51290,7 +51317,7 @@ public override byte[] ToBytes() Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); TransactionBlock.ToBytes(bytes, ref i); - bytes[i++] = (byte)FolderData.Length; + Utils.ByteToBytes((byte)FolderData.Length, bytes, ref i); for (int j = 0; j < FolderData.Length; j++) { FolderData[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -51587,7 +51614,7 @@ public override void FromBytes(byte[] bytes, ref int i) try { ObjectLocalID = Utils.BytesToUIntSafepos(bytes, i); i += 4; - Enabled = (bytes[i++] != 0) ? (bool)true : (bool)false; + Enabled = (Utils.BytesToByte(bytes, ref i) != 0); } catch (Exception) { @@ -51598,7 +51625,7 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { Utils.UIntToBytesSafepos(ObjectLocalID, bytes, i); i += 4; - bytes[i++] = (byte)((Enabled) ? 1 : 0); + Utils.ByteToBytes((byte)((Enabled) ? 1 : 0), bytes, ref i); } } @@ -51660,17 +51687,17 @@ public override void FromBytes(byte[] bytes, ref int i) GroupMask = Utils.BytesToUIntSafepos(bytes, i); i += 4; EveryoneMask = Utils.BytesToUIntSafepos(bytes, i); i += 4; NextOwnerMask = Utils.BytesToUIntSafepos(bytes, i); i += 4; - GroupOwned = (bytes[i++] != 0) ? (bool)true : (bool)false; + GroupOwned = (Utils.BytesToByte(bytes, ref i) != 0); TransactionID.FromBytes(bytes, i); i += 16; - Type = (sbyte)bytes[i++]; - InvType = (sbyte)bytes[i++]; + Type = (sbyte)Utils.BytesToByte(bytes, ref i); + InvType = (sbyte)Utils.BytesToByte(bytes, ref i); Flags = Utils.BytesToUIntSafepos(bytes, i); i += 4; - SaleType = (byte)bytes[i++]; + SaleType = Utils.BytesToByte(bytes, ref i); SalePrice = Utils.BytesToIntSafepos(bytes, i); i +=4; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Name = new byte[length]; Buffer.BlockCopy(bytes, i, Name, 0, length); i += length; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Description = new byte[length]; Buffer.BlockCopy(bytes, i, Description, 0, length); i += length; CreationDate = Utils.BytesToIntSafepos(bytes, i); i +=4; @@ -51694,16 +51721,16 @@ public override void ToBytes(byte[] bytes, ref int i) Utils.UIntToBytesSafepos(GroupMask, bytes, i); i += 4; Utils.UIntToBytesSafepos(EveryoneMask, bytes, i); i += 4; Utils.UIntToBytesSafepos(NextOwnerMask, bytes, i); i += 4; - bytes[i++] = (byte)((GroupOwned) ? 1 : 0); + Utils.ByteToBytes((byte)((GroupOwned) ? 1 : 0), bytes, ref i); TransactionID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)Type; - bytes[i++] = (byte)InvType; + Utils.ByteToBytes( (byte)Type, bytes, ref i); + Utils.ByteToBytes( (byte)InvType, bytes, ref i); Utils.UIntToBytesSafepos(Flags, bytes, i); i += 4; - bytes[i++] = SaleType; + Utils.ByteToBytes( SaleType, bytes, ref i); Utils.IntToBytesSafepos(SalePrice, bytes, i); i += 4; - bytes[i++] = (byte)Name.Length; + Utils.ByteToBytes((byte)Name.Length, bytes, ref i); Buffer.BlockCopy(Name, 0, bytes, i, Name.Length); i += Name.Length; - bytes[i++] = (byte)Description.Length; + Utils.ByteToBytes((byte)Description.Length, bytes, ref i); Buffer.BlockCopy(Description, 0, bytes, i, Description.Length); i += Description.Length; Utils.IntToBytesSafepos(CreationDate, bytes, i); i += 4; Utils.UIntToBytesSafepos(CRC, bytes, i); i += 4; @@ -51878,13 +51905,13 @@ public override void FromBytes(byte[] bytes, ref int i) FolderID.FromBytes(bytes, i); i += 16; TransactionID.FromBytes(bytes, i); i += 16; NextOwnerMask = Utils.BytesToUIntSafepos(bytes, i); i += 4; - Type = (sbyte)bytes[i++]; - InvType = (sbyte)bytes[i++]; - WearableType = (byte)bytes[i++]; - length = bytes[i++]; + Type = (sbyte)Utils.BytesToByte(bytes, ref i); + InvType = (sbyte)Utils.BytesToByte(bytes, ref i); + WearableType = Utils.BytesToByte(bytes, ref i); + length = Utils.BytesToByte(bytes, ref i); Name = new byte[length]; Buffer.BlockCopy(bytes, i, Name, 0, length); i += length; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Description = new byte[length]; Buffer.BlockCopy(bytes, i, Description, 0, length); i += length; } @@ -51900,12 +51927,12 @@ public override void ToBytes(byte[] bytes, ref int i) FolderID.ToBytes(bytes, i); i += 16; TransactionID.ToBytes(bytes, i); i += 16; Utils.UIntToBytesSafepos(NextOwnerMask, bytes, i); i += 4; - bytes[i++] = (byte)Type; - bytes[i++] = (byte)InvType; - bytes[i++] = WearableType; - bytes[i++] = (byte)Name.Length; + Utils.ByteToBytes( (byte)Type, bytes, ref i); + Utils.ByteToBytes( (byte)InvType, bytes, ref i); + Utils.ByteToBytes( WearableType, bytes, ref i); + Utils.ByteToBytes((byte)Name.Length, bytes, ref i); Buffer.BlockCopy(Name, 0, bytes, i, Name.Length); i += Name.Length; - bytes[i++] = (byte)Description.Length; + Utils.ByteToBytes((byte)Description.Length, bytes, ref i); Buffer.BlockCopy(Description, 0, bytes, i, Description.Length); i += Description.Length; } @@ -52098,7 +52125,7 @@ public override void FromBytes(byte[] bytes, ref int i) try { FolderID.FromBytes(bytes, i); i += 16; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Name = new byte[length]; Buffer.BlockCopy(bytes, i, Name, 0, length); i += length; } @@ -52111,7 +52138,7 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { FolderID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)Name.Length; + Utils.ByteToBytes((byte)Name.Length, bytes, ref i); Buffer.BlockCopy(Name, 0, bytes, i, Name.Length); i += Name.Length; } @@ -52503,12 +52530,12 @@ public override void FromBytes(byte[] bytes, ref int i) { SourceID.FromBytes(bytes, i); i += 16; DestID.FromBytes(bytes, i); i += 16; - Flags = (byte)bytes[i++]; + Flags = Utils.BytesToByte(bytes, ref i); Amount = Utils.BytesToIntSafepos(bytes, i); i +=4; - AggregatePermNextOwner = (byte)bytes[i++]; - AggregatePermInventory = (byte)bytes[i++]; + AggregatePermNextOwner = Utils.BytesToByte(bytes, ref i); + AggregatePermInventory = Utils.BytesToByte(bytes, ref i); TransactionType = Utils.BytesToIntSafepos(bytes, i); i +=4; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Description = new byte[length]; Buffer.BlockCopy(bytes, i, Description, 0, length); i += length; } @@ -52522,12 +52549,12 @@ public override void ToBytes(byte[] bytes, ref int i) { SourceID.ToBytes(bytes, i); i += 16; DestID.ToBytes(bytes, i); i += 16; - bytes[i++] = Flags; + Utils.ByteToBytes( Flags, bytes, ref i); Utils.IntToBytesSafepos(Amount, bytes, i); i += 4; - bytes[i++] = AggregatePermNextOwner; - bytes[i++] = AggregatePermInventory; + Utils.ByteToBytes( AggregatePermNextOwner, bytes, ref i); + Utils.ByteToBytes( AggregatePermInventory, bytes, ref i); Utils.IntToBytesSafepos(TransactionType, bytes, i); i += 4; - bytes[i++] = (byte)Description.Length; + Utils.ByteToBytes((byte)Description.Length, bytes, ref i); Buffer.BlockCopy(Description, 0, bytes, i, Description.Length); i += Description.Length; } @@ -52806,11 +52833,11 @@ public override void FromBytes(byte[] bytes, ref int i) { AgentID.FromBytes(bytes, i); i += 16; TransactionID.FromBytes(bytes, i); i += 16; - TransactionSuccess = (bytes[i++] != 0) ? (bool)true : (bool)false; + TransactionSuccess = (Utils.BytesToByte(bytes, ref i) != 0); MoneyBalance = Utils.BytesToIntSafepos(bytes, i); i +=4; SquareMetersCredit = Utils.BytesToIntSafepos(bytes, i); i +=4; SquareMetersCommitted = Utils.BytesToIntSafepos(bytes, i); i +=4; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Description = new byte[length]; Buffer.BlockCopy(bytes, i, Description, 0, length); i += length; } @@ -52824,11 +52851,11 @@ public override void ToBytes(byte[] bytes, ref int i) { AgentID.ToBytes(bytes, i); i += 16; TransactionID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)((TransactionSuccess) ? 1 : 0); + Utils.ByteToBytes((byte)((TransactionSuccess) ? 1 : 0), bytes, ref i); Utils.IntToBytesSafepos(MoneyBalance, bytes, i); i += 4; Utils.IntToBytesSafepos(SquareMetersCredit, bytes, i); i += 4; Utils.IntToBytesSafepos(SquareMetersCommitted, bytes, i); i += 4; - bytes[i++] = (byte)Description.Length; + Utils.ByteToBytes((byte)Description.Length, bytes, ref i); Buffer.BlockCopy(Description, 0, bytes, i, Description.Length); i += Description.Length; } @@ -52868,11 +52895,11 @@ public override void FromBytes(byte[] bytes, ref int i) { TransactionType = Utils.BytesToIntSafepos(bytes, i); i +=4; SourceID.FromBytes(bytes, i); i += 16; - IsSourceGroup = (bytes[i++] != 0) ? (bool)true : (bool)false; + IsSourceGroup = (Utils.BytesToByte(bytes, ref i) != 0); DestID.FromBytes(bytes, i); i += 16; - IsDestGroup = (bytes[i++] != 0) ? (bool)true : (bool)false; + IsDestGroup = (Utils.BytesToByte(bytes, ref i) != 0); Amount = Utils.BytesToIntSafepos(bytes, i); i +=4; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); ItemDescription = new byte[length]; Buffer.BlockCopy(bytes, i, ItemDescription, 0, length); i += length; } @@ -52886,11 +52913,11 @@ public override void ToBytes(byte[] bytes, ref int i) { Utils.IntToBytesSafepos(TransactionType, bytes, i); i += 4; SourceID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)((IsSourceGroup) ? 1 : 0); + Utils.ByteToBytes((byte)((IsSourceGroup) ? 1 : 0), bytes, ref i); DestID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)((IsDestGroup) ? 1 : 0); + Utils.ByteToBytes((byte)((IsDestGroup) ? 1 : 0), bytes, ref i); Utils.IntToBytesSafepos(Amount, bytes, i); i += 4; - bytes[i++] = (byte)ItemDescription.Length; + Utils.ByteToBytes((byte)ItemDescription.Length, bytes, ref i); Buffer.BlockCopy(ItemDescription, 0, bytes, i, ItemDescription.Length); i += ItemDescription.Length; } @@ -53012,8 +53039,7 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { Utils.UIntToBytesSafepos(TargetIP, bytes, i); i += 4; - bytes[i++] = (byte)((TargetPort >> 8) % 256); - bytes[i++] = (byte)(TargetPort % 256); + Utils.UInt16ToBytesBig(TargetPort, bytes, i); i += 2; } } @@ -53052,11 +53078,11 @@ public override void FromBytes(byte[] bytes, ref int i) { AgentID.FromBytes(bytes, i); i += 16; TransactionID.FromBytes(bytes, i); i += 16; - TransactionSuccess = (bytes[i++] != 0) ? (bool)true : (bool)false; + TransactionSuccess = (Utils.BytesToByte(bytes, ref i) != 0); MoneyBalance = Utils.BytesToIntSafepos(bytes, i); i +=4; SquareMetersCredit = Utils.BytesToIntSafepos(bytes, i); i +=4; SquareMetersCommitted = Utils.BytesToIntSafepos(bytes, i); i +=4; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Description = new byte[length]; Buffer.BlockCopy(bytes, i, Description, 0, length); i += length; } @@ -53070,11 +53096,11 @@ public override void ToBytes(byte[] bytes, ref int i) { AgentID.ToBytes(bytes, i); i += 16; TransactionID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)((TransactionSuccess) ? 1 : 0); + Utils.ByteToBytes((byte)((TransactionSuccess) ? 1 : 0), bytes, ref i); Utils.IntToBytesSafepos(MoneyBalance, bytes, i); i += 4; Utils.IntToBytesSafepos(SquareMetersCredit, bytes, i); i += 4; Utils.IntToBytesSafepos(SquareMetersCommitted, bytes, i); i += 4; - bytes[i++] = (byte)Description.Length; + Utils.ByteToBytes((byte)Description.Length, bytes, ref i); Buffer.BlockCopy(Description, 0, bytes, i, Description.Length); i += Description.Length; } @@ -53114,11 +53140,11 @@ public override void FromBytes(byte[] bytes, ref int i) { TransactionType = Utils.BytesToIntSafepos(bytes, i); i +=4; SourceID.FromBytes(bytes, i); i += 16; - IsSourceGroup = (bytes[i++] != 0) ? (bool)true : (bool)false; + IsSourceGroup = (Utils.BytesToByte(bytes, ref i) != 0); DestID.FromBytes(bytes, i); i += 16; - IsDestGroup = (bytes[i++] != 0) ? (bool)true : (bool)false; + IsDestGroup = (Utils.BytesToByte(bytes, ref i) != 0); Amount = Utils.BytesToIntSafepos(bytes, i); i +=4; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); ItemDescription = new byte[length]; Buffer.BlockCopy(bytes, i, ItemDescription, 0, length); i += length; } @@ -53132,11 +53158,11 @@ public override void ToBytes(byte[] bytes, ref int i) { Utils.IntToBytesSafepos(TransactionType, bytes, i); i += 4; SourceID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)((IsSourceGroup) ? 1 : 0); + Utils.ByteToBytes((byte)((IsSourceGroup) ? 1 : 0), bytes, ref i); DestID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)((IsDestGroup) ? 1 : 0); + Utils.ByteToBytes((byte)((IsDestGroup) ? 1 : 0), bytes, ref i); Utils.IntToBytesSafepos(Amount, bytes, i); i += 4; - bytes[i++] = (byte)ItemDescription.Length; + Utils.ByteToBytes((byte)ItemDescription.Length, bytes, ref i); Buffer.BlockCopy(ItemDescription, 0, bytes, i, ItemDescription.Length); i += ItemDescription.Length; } @@ -53398,7 +53424,7 @@ public override byte[] ToBytes() int i = 0; Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); - bytes[i++] = (byte)Data.Length; + Utils.ByteToBytes((byte)Data.Length, bytes, ref i); for (int j = 0; j < Data.Length; j++) { Data[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -53632,7 +53658,7 @@ public override byte[] ToBytes() int i = 0; Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); - bytes[i++] = (byte)Data.Length; + Utils.ByteToBytes((byte)Data.Length, bytes, ref i); for (int j = 0; j < Data.Length; j++) { Data[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -53728,7 +53754,7 @@ public override void FromBytes(byte[] bytes, ref int i) try { AgentID.FromBytes(bytes, i); i += 16; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Filename = new byte[length]; Buffer.BlockCopy(bytes, i, Filename, 0, length); i += length; } @@ -53741,7 +53767,7 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { AgentID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)Filename.Length; + Utils.ByteToBytes((byte)Filename.Length, bytes, ref i); Buffer.BlockCopy(Filename, 0, bytes, i, Filename.Length); i += Filename.Length; } @@ -54092,7 +54118,7 @@ public override byte[] ToBytes() int i = 0; Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); - bytes[i++] = (byte)Rights.Length; + Utils.ByteToBytes((byte)Rights.Length, bytes, ref i); for (int j = 0; j < Rights.Length; j++) { Rights[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -54320,7 +54346,7 @@ public override byte[] ToBytes() int i = 0; Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); - bytes[i++] = (byte)Rights.Length; + Utils.ByteToBytes((byte)Rights.Length, bytes, ref i); for (int j = 0; j < Rights.Length; j++) { Rights[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -54500,7 +54526,7 @@ public override byte[] ToBytes() byte[] bytes = new byte[length]; int i = 0; Header.ToBytes(bytes, ref i); - bytes[i++] = (byte)AgentBlock.Length; + Utils.ByteToBytes((byte)AgentBlock.Length, bytes, ref i); for (int j = 0; j < AgentBlock.Length; j++) { AgentBlock[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -54678,7 +54704,7 @@ public override byte[] ToBytes() byte[] bytes = new byte[length]; int i = 0; Header.ToBytes(bytes, ref i); - bytes[i++] = (byte)AgentBlock.Length; + Utils.ByteToBytes((byte)AgentBlock.Length, bytes, ref i); for (int j = 0; j < AgentBlock.Length; j++) { AgentBlock[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -54814,7 +54840,7 @@ public override void FromBytes(byte[] bytes, ref int i) int length; try { - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); SimName = new byte[length]; Buffer.BlockCopy(bytes, i, SimName, 0, length); i += length; LocationID = Utils.BytesToUIntSafepos(bytes, i); i += 4; @@ -54829,7 +54855,7 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { - bytes[i++] = (byte)SimName.Length; + Utils.ByteToBytes((byte)SimName.Length, bytes, ref i); Buffer.BlockCopy(SimName, 0, bytes, i, SimName.Length); i += SimName.Length; Utils.UIntToBytesSafepos(LocationID, bytes, i); i += 4; LocationPos.ToBytes(bytes, i); i += 12; @@ -54949,10 +54975,10 @@ public override void FromBytes(byte[] bytes, ref int i) try { TransactionID.FromBytes(bytes, i); i += 16; - Type = (sbyte)bytes[i++]; - Tempfile = (bytes[i++] != 0) ? (bool)true : (bool)false; - StoreLocal = (bytes[i++] != 0) ? (bool)true : (bool)false; - length = (bytes[i++] + (bytes[i++] << 8)); + Type = (sbyte)Utils.BytesToByte(bytes, ref i); + Tempfile = (Utils.BytesToByte(bytes, ref i) != 0); + StoreLocal = (Utils.BytesToByte(bytes, ref i) != 0); + length = Utils.BytesToUInt16(bytes, i); i+=2; AssetData = new byte[length]; Buffer.BlockCopy(bytes, i, AssetData, 0, length); i += length; } @@ -54965,11 +54991,10 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { TransactionID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)Type; - bytes[i++] = (byte)((Tempfile) ? 1 : 0); - bytes[i++] = (byte)((StoreLocal) ? 1 : 0); - bytes[i++] = (byte)(AssetData.Length % 256); - bytes[i++] = (byte)((AssetData.Length >> 8) % 256); + Utils.ByteToBytes( (byte)Type, bytes, ref i); + Utils.ByteToBytes((byte)((Tempfile) ? 1 : 0), bytes, ref i); + Utils.ByteToBytes((byte)((StoreLocal) ? 1 : 0), bytes, ref i); + Utils.UInt16ToBytes((ushort)AssetData.Length, bytes, i); i += 2; Buffer.BlockCopy(AssetData, 0, bytes, i, AssetData.Length); i += AssetData.Length; } @@ -55073,8 +55098,8 @@ public override void FromBytes(byte[] bytes, ref int i) try { UUID.FromBytes(bytes, i); i += 16; - Type = (sbyte)bytes[i++]; - Success = (bytes[i++] != 0) ? (bool)true : (bool)false; + Type = (sbyte)Utils.BytesToByte(bytes, ref i); + Success = (Utils.BytesToByte(bytes, ref i) != 0); } catch (Exception) { @@ -55085,8 +55110,8 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { UUID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)Type; - bytes[i++] = (byte)((Success) ? 1 : 0); + Utils.ByteToBytes( (byte)Type, bytes, ref i); + Utils.ByteToBytes((byte)((Success) ? 1 : 0), bytes, ref i); } } @@ -55238,18 +55263,18 @@ public override void FromBytes(byte[] bytes, ref int i) int length; try { - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Name = new byte[length]; Buffer.BlockCopy(bytes, i, Name, 0, length); i += length; - length = (bytes[i++] + (bytes[i++] << 8)); + length = Utils.BytesToUInt16(bytes, i); i+=2; Charter = new byte[length]; Buffer.BlockCopy(bytes, i, Charter, 0, length); i += length; - ShowInList = (bytes[i++] != 0) ? (bool)true : (bool)false; + ShowInList = (Utils.BytesToByte(bytes, ref i) != 0); InsigniaID.FromBytes(bytes, i); i += 16; MembershipFee = Utils.BytesToIntSafepos(bytes, i); i +=4; - OpenEnrollment = (bytes[i++] != 0) ? (bool)true : (bool)false; - AllowPublish = (bytes[i++] != 0) ? (bool)true : (bool)false; - MaturePublish = (bytes[i++] != 0) ? (bool)true : (bool)false; + OpenEnrollment = (Utils.BytesToByte(bytes, ref i) != 0); + AllowPublish = (Utils.BytesToByte(bytes, ref i) != 0); + MaturePublish = (Utils.BytesToByte(bytes, ref i) != 0); } catch (Exception) { @@ -55259,17 +55284,16 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { - bytes[i++] = (byte)Name.Length; + Utils.ByteToBytes((byte)Name.Length, bytes, ref i); Buffer.BlockCopy(Name, 0, bytes, i, Name.Length); i += Name.Length; - bytes[i++] = (byte)(Charter.Length % 256); - bytes[i++] = (byte)((Charter.Length >> 8) % 256); + Utils.UInt16ToBytes((ushort)Charter.Length, bytes, i); i += 2; Buffer.BlockCopy(Charter, 0, bytes, i, Charter.Length); i += Charter.Length; - bytes[i++] = (byte)((ShowInList) ? 1 : 0); + Utils.ByteToBytes((byte)((ShowInList) ? 1 : 0), bytes, ref i); InsigniaID.ToBytes(bytes, i); i += 16; Utils.IntToBytesSafepos(MembershipFee, bytes, i); i += 4; - bytes[i++] = (byte)((OpenEnrollment) ? 1 : 0); - bytes[i++] = (byte)((AllowPublish) ? 1 : 0); - bytes[i++] = (byte)((MaturePublish) ? 1 : 0); + Utils.ByteToBytes((byte)((OpenEnrollment) ? 1 : 0), bytes, ref i); + Utils.ByteToBytes((byte)((AllowPublish) ? 1 : 0), bytes, ref i); + Utils.ByteToBytes((byte)((MaturePublish) ? 1 : 0), bytes, ref i); } } @@ -55421,8 +55445,8 @@ public override void FromBytes(byte[] bytes, ref int i) try { GroupID.FromBytes(bytes, i); i += 16; - Success = (bytes[i++] != 0) ? (bool)true : (bool)false; - length = bytes[i++]; + Success = (Utils.BytesToByte(bytes, ref i) != 0); + length = Utils.BytesToByte(bytes, ref i); Message = new byte[length]; Buffer.BlockCopy(bytes, i, Message, 0, length); i += length; } @@ -55435,8 +55459,8 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { GroupID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)((Success) ? 1 : 0); - bytes[i++] = (byte)Message.Length; + Utils.ByteToBytes((byte)((Success) ? 1 : 0), bytes, ref i); + Utils.ByteToBytes((byte)Message.Length, bytes, ref i); Buffer.BlockCopy(Message, 0, bytes, i, Message.Length); i += Message.Length; } @@ -55596,15 +55620,15 @@ public override void FromBytes(byte[] bytes, ref int i) try { GroupID.FromBytes(bytes, i); i += 16; - length = (bytes[i++] + (bytes[i++] << 8)); + length = Utils.BytesToUInt16(bytes, i); i+=2; Charter = new byte[length]; Buffer.BlockCopy(bytes, i, Charter, 0, length); i += length; - ShowInList = (bytes[i++] != 0) ? (bool)true : (bool)false; + ShowInList = (Utils.BytesToByte(bytes, ref i) != 0); InsigniaID.FromBytes(bytes, i); i += 16; MembershipFee = Utils.BytesToIntSafepos(bytes, i); i +=4; - OpenEnrollment = (bytes[i++] != 0) ? (bool)true : (bool)false; - AllowPublish = (bytes[i++] != 0) ? (bool)true : (bool)false; - MaturePublish = (bytes[i++] != 0) ? (bool)true : (bool)false; + OpenEnrollment = (Utils.BytesToByte(bytes, ref i) != 0); + AllowPublish = (Utils.BytesToByte(bytes, ref i) != 0); + MaturePublish = (Utils.BytesToByte(bytes, ref i) != 0); } catch (Exception) { @@ -55615,15 +55639,14 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { GroupID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)(Charter.Length % 256); - bytes[i++] = (byte)((Charter.Length >> 8) % 256); + Utils.UInt16ToBytes((ushort)Charter.Length, bytes, i); i += 2; Buffer.BlockCopy(Charter, 0, bytes, i, Charter.Length); i += Charter.Length; - bytes[i++] = (byte)((ShowInList) ? 1 : 0); + Utils.ByteToBytes((byte)((ShowInList) ? 1 : 0), bytes, ref i); InsigniaID.ToBytes(bytes, i); i += 16; Utils.IntToBytesSafepos(MembershipFee, bytes, i); i += 4; - bytes[i++] = (byte)((OpenEnrollment) ? 1 : 0); - bytes[i++] = (byte)((AllowPublish) ? 1 : 0); - bytes[i++] = (byte)((MaturePublish) ? 1 : 0); + Utils.ByteToBytes((byte)((OpenEnrollment) ? 1 : 0), bytes, ref i); + Utils.ByteToBytes((byte)((AllowPublish) ? 1 : 0), bytes, ref i); + Utils.ByteToBytes((byte)((MaturePublish) ? 1 : 0), bytes, ref i); } } @@ -55877,7 +55900,7 @@ public override byte[] ToBytes() int i = 0; Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); - bytes[i++] = (byte)RoleChange.Length; + Utils.ByteToBytes((byte)RoleChange.Length, bytes, ref i); for (int j = 0; j < RoleChange.Length; j++) { RoleChange[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -56167,7 +56190,7 @@ public override void FromBytes(byte[] bytes, ref int i) try { GroupID.FromBytes(bytes, i); i += 16; - Success = (bytes[i++] != 0) ? (bool)true : (bool)false; + Success = (Utils.BytesToByte(bytes, ref i) != 0); } catch (Exception) { @@ -56178,7 +56201,7 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { GroupID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)((Success) ? 1 : 0); + Utils.ByteToBytes((byte)((Success) ? 1 : 0), bytes, ref i); } } @@ -56467,7 +56490,7 @@ public override byte[] ToBytes() Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); GroupData.ToBytes(bytes, ref i); - bytes[i++] = (byte)EjectData.Length; + Utils.ByteToBytes((byte)EjectData.Length, bytes, ref i); for (int j = 0; j < EjectData.Length; j++) { EjectData[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -56636,7 +56659,7 @@ public override void FromBytes(byte[] bytes, ref int i) { try { - Success = (bytes[i++] != 0) ? (bool)true : (bool)false; + Success = (Utils.BytesToByte(bytes, ref i) != 0); } catch (Exception) { @@ -56646,7 +56669,7 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { - bytes[i++] = (byte)((Success) ? 1 : 0); + Utils.ByteToBytes((byte)((Success) ? 1 : 0), bytes, ref i); } } @@ -56958,7 +56981,7 @@ public override void FromBytes(byte[] bytes, ref int i) try { GroupID.FromBytes(bytes, i); i += 16; - Success = (bytes[i++] != 0) ? (bool)true : (bool)false; + Success = (Utils.BytesToByte(bytes, ref i) != 0); } catch (Exception) { @@ -56969,7 +56992,7 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { GroupID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)((Success) ? 1 : 0); + Utils.ByteToBytes((byte)((Success) ? 1 : 0), bytes, ref i); } } @@ -57261,7 +57284,7 @@ public override byte[] ToBytes() Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); GroupData.ToBytes(bytes, ref i); - bytes[i++] = (byte)InviteData.Length; + Utils.ByteToBytes((byte)InviteData.Length, bytes, ref i); for (int j = 0; j < InviteData.Length; j++) { InviteData[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -57571,26 +57594,26 @@ public override void FromBytes(byte[] bytes, ref int i) try { GroupID.FromBytes(bytes, i); i += 16; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Name = new byte[length]; Buffer.BlockCopy(bytes, i, Name, 0, length); i += length; - length = (bytes[i++] + (bytes[i++] << 8)); + length = Utils.BytesToUInt16(bytes, i); i+=2; Charter = new byte[length]; Buffer.BlockCopy(bytes, i, Charter, 0, length); i += length; - ShowInList = (bytes[i++] != 0) ? (bool)true : (bool)false; - length = bytes[i++]; + ShowInList = (Utils.BytesToByte(bytes, ref i) != 0); + length = Utils.BytesToByte(bytes, ref i); MemberTitle = new byte[length]; Buffer.BlockCopy(bytes, i, MemberTitle, 0, length); i += length; PowersMask = Utils.BytesToUInt64Safepos(bytes, i); i += 8; InsigniaID.FromBytes(bytes, i); i += 16; FounderID.FromBytes(bytes, i); i += 16; MembershipFee = Utils.BytesToIntSafepos(bytes, i); i +=4; - OpenEnrollment = (bytes[i++] != 0) ? (bool)true : (bool)false; + OpenEnrollment = (Utils.BytesToByte(bytes, ref i) != 0); Money = Utils.BytesToIntSafepos(bytes, i); i +=4; GroupMembershipCount = Utils.BytesToIntSafepos(bytes, i); i +=4; GroupRolesCount = Utils.BytesToIntSafepos(bytes, i); i +=4; - AllowPublish = (bytes[i++] != 0) ? (bool)true : (bool)false; - MaturePublish = (bytes[i++] != 0) ? (bool)true : (bool)false; + AllowPublish = (Utils.BytesToByte(bytes, ref i) != 0); + MaturePublish = (Utils.BytesToByte(bytes, ref i) != 0); OwnerRole.FromBytes(bytes, i); i += 16; } catch (Exception) @@ -57602,24 +57625,23 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { GroupID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)Name.Length; + Utils.ByteToBytes((byte)Name.Length, bytes, ref i); Buffer.BlockCopy(Name, 0, bytes, i, Name.Length); i += Name.Length; - bytes[i++] = (byte)(Charter.Length % 256); - bytes[i++] = (byte)((Charter.Length >> 8) % 256); + Utils.UInt16ToBytes((ushort)Charter.Length, bytes, i); i += 2; Buffer.BlockCopy(Charter, 0, bytes, i, Charter.Length); i += Charter.Length; - bytes[i++] = (byte)((ShowInList) ? 1 : 0); - bytes[i++] = (byte)MemberTitle.Length; + Utils.ByteToBytes((byte)((ShowInList) ? 1 : 0), bytes, ref i); + Utils.ByteToBytes((byte)MemberTitle.Length, bytes, ref i); Buffer.BlockCopy(MemberTitle, 0, bytes, i, MemberTitle.Length); i += MemberTitle.Length; Utils.UInt64ToBytesSafepos(PowersMask, bytes, i); i += 8; InsigniaID.ToBytes(bytes, i); i += 16; FounderID.ToBytes(bytes, i); i += 16; Utils.IntToBytesSafepos(MembershipFee, bytes, i); i += 4; - bytes[i++] = (byte)((OpenEnrollment) ? 1 : 0); + Utils.ByteToBytes((byte)((OpenEnrollment) ? 1 : 0), bytes, ref i); Utils.IntToBytesSafepos(Money, bytes, i); i += 4; Utils.IntToBytesSafepos(GroupMembershipCount, bytes, i); i += 4; Utils.IntToBytesSafepos(GroupRolesCount, bytes, i); i += 4; - bytes[i++] = (byte)((AllowPublish) ? 1 : 0); - bytes[i++] = (byte)((MaturePublish) ? 1 : 0); + Utils.ByteToBytes((byte)((AllowPublish) ? 1 : 0), bytes, ref i); + Utils.ByteToBytes((byte)((MaturePublish) ? 1 : 0), bytes, ref i); OwnerRole.ToBytes(bytes, i); i += 16; } @@ -57964,7 +57986,7 @@ public override void FromBytes(byte[] bytes, ref int i) RequestID.FromBytes(bytes, i); i += 16; IntervalDays = Utils.BytesToIntSafepos(bytes, i); i +=4; CurrentInterval = Utils.BytesToIntSafepos(bytes, i); i +=4; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); StartDate = new byte[length]; Buffer.BlockCopy(bytes, i, StartDate, 0, length); i += length; Balance = Utils.BytesToIntSafepos(bytes, i); i +=4; @@ -57981,10 +58003,10 @@ public override void FromBytes(byte[] bytes, ref int i) GroupTaxEstimate = Utils.BytesToIntSafepos(bytes, i); i +=4; ParcelDirFeeEstimate = Utils.BytesToIntSafepos(bytes, i); i +=4; NonExemptMembers = Utils.BytesToIntSafepos(bytes, i); i +=4; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); LastTaxDate = new byte[length]; Buffer.BlockCopy(bytes, i, LastTaxDate, 0, length); i += length; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); TaxDate = new byte[length]; Buffer.BlockCopy(bytes, i, TaxDate, 0, length); i += length; } @@ -57999,7 +58021,7 @@ public override void ToBytes(byte[] bytes, ref int i) RequestID.ToBytes(bytes, i); i += 16; Utils.IntToBytesSafepos(IntervalDays, bytes, i); i += 4; Utils.IntToBytesSafepos(CurrentInterval, bytes, i); i += 4; - bytes[i++] = (byte)StartDate.Length; + Utils.ByteToBytes((byte)StartDate.Length, bytes, ref i); Buffer.BlockCopy(StartDate, 0, bytes, i, StartDate.Length); i += StartDate.Length; Utils.IntToBytesSafepos(Balance, bytes, i); i += 4; Utils.IntToBytesSafepos(TotalCredits, bytes, i); i += 4; @@ -58015,9 +58037,9 @@ public override void ToBytes(byte[] bytes, ref int i) Utils.IntToBytesSafepos(GroupTaxEstimate, bytes, i); i += 4; Utils.IntToBytesSafepos(ParcelDirFeeEstimate, bytes, i); i += 4; Utils.IntToBytesSafepos(NonExemptMembers, bytes, i); i += 4; - bytes[i++] = (byte)LastTaxDate.Length; + Utils.ByteToBytes((byte)LastTaxDate.Length, bytes, ref i); Buffer.BlockCopy(LastTaxDate, 0, bytes, i, LastTaxDate.Length); i += LastTaxDate.Length; - bytes[i++] = (byte)TaxDate.Length; + Utils.ByteToBytes((byte)TaxDate.Length, bytes, ref i); Buffer.BlockCopy(TaxDate, 0, bytes, i, TaxDate.Length); i += TaxDate.Length; } @@ -58344,7 +58366,7 @@ public override void FromBytes(byte[] bytes, ref int i) RequestID.FromBytes(bytes, i); i += 16; IntervalDays = Utils.BytesToIntSafepos(bytes, i); i +=4; CurrentInterval = Utils.BytesToIntSafepos(bytes, i); i +=4; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); StartDate = new byte[length]; Buffer.BlockCopy(bytes, i, StartDate, 0, length); i += length; } @@ -58359,7 +58381,7 @@ public override void ToBytes(byte[] bytes, ref int i) RequestID.ToBytes(bytes, i); i += 16; Utils.IntToBytesSafepos(IntervalDays, bytes, i); i += 4; Utils.IntToBytesSafepos(CurrentInterval, bytes, i); i += 4; - bytes[i++] = (byte)StartDate.Length; + Utils.ByteToBytes((byte)StartDate.Length, bytes, ref i); Buffer.BlockCopy(StartDate, 0, bytes, i, StartDate.Length); i += StartDate.Length; } @@ -58392,7 +58414,7 @@ public override void FromBytes(byte[] bytes, ref int i) int length; try { - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Description = new byte[length]; Buffer.BlockCopy(bytes, i, Description, 0, length); i += length; Amount = Utils.BytesToIntSafepos(bytes, i); i +=4; @@ -58405,7 +58427,7 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { - bytes[i++] = (byte)Description.Length; + Utils.ByteToBytes((byte)Description.Length, bytes, ref i); Buffer.BlockCopy(Description, 0, bytes, i, Description.Length); i += Description.Length; Utils.IntToBytesSafepos(Amount, bytes, i); i += 4; } @@ -58501,7 +58523,7 @@ public override byte[] ToBytes() Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); MoneyData.ToBytes(bytes, ref i); - bytes[i++] = (byte)HistoryData.Length; + Utils.ByteToBytes((byte)HistoryData.Length, bytes, ref i); for (int j = 0; j < HistoryData.Length; j++) { HistoryData[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -58812,7 +58834,7 @@ public override void FromBytes(byte[] bytes, ref int i) RequestID.FromBytes(bytes, i); i += 16; IntervalDays = Utils.BytesToIntSafepos(bytes, i); i +=4; CurrentInterval = Utils.BytesToIntSafepos(bytes, i); i +=4; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); StartDate = new byte[length]; Buffer.BlockCopy(bytes, i, StartDate, 0, length); i += length; } @@ -58827,7 +58849,7 @@ public override void ToBytes(byte[] bytes, ref int i) RequestID.ToBytes(bytes, i); i += 16; Utils.IntToBytesSafepos(IntervalDays, bytes, i); i += 4; Utils.IntToBytesSafepos(CurrentInterval, bytes, i); i += 4; - bytes[i++] = (byte)StartDate.Length; + Utils.ByteToBytes((byte)StartDate.Length, bytes, ref i); Buffer.BlockCopy(StartDate, 0, bytes, i, StartDate.Length); i += StartDate.Length; } @@ -58865,14 +58887,14 @@ public override void FromBytes(byte[] bytes, ref int i) int length; try { - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Time = new byte[length]; Buffer.BlockCopy(bytes, i, Time, 0, length); i += length; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); User = new byte[length]; Buffer.BlockCopy(bytes, i, User, 0, length); i += length; Type = Utils.BytesToIntSafepos(bytes, i); i +=4; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Item = new byte[length]; Buffer.BlockCopy(bytes, i, Item, 0, length); i += length; Amount = Utils.BytesToIntSafepos(bytes, i); i +=4; @@ -58885,12 +58907,12 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { - bytes[i++] = (byte)Time.Length; + Utils.ByteToBytes((byte)Time.Length, bytes, ref i); Buffer.BlockCopy(Time, 0, bytes, i, Time.Length); i += Time.Length; - bytes[i++] = (byte)User.Length; + Utils.ByteToBytes((byte)User.Length, bytes, ref i); Buffer.BlockCopy(User, 0, bytes, i, User.Length); i += User.Length; Utils.IntToBytesSafepos(Type, bytes, i); i += 4; - bytes[i++] = (byte)Item.Length; + Utils.ByteToBytes((byte)Item.Length, bytes, ref i); Buffer.BlockCopy(Item, 0, bytes, i, Item.Length); i += Item.Length; Utils.IntToBytesSafepos(Amount, bytes, i); i += 4; } @@ -58986,7 +59008,7 @@ public override byte[] ToBytes() Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); MoneyData.ToBytes(bytes, ref i); - bytes[i++] = (byte)HistoryData.Length; + Utils.ByteToBytes((byte)HistoryData.Length, bytes, ref i); for (int j = 0; j < HistoryData.Length; j++) { HistoryData[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -59382,22 +59404,22 @@ public override void FromBytes(byte[] bytes, ref int i) { VoteID.FromBytes(bytes, i); i += 16; VoteInitiator.FromBytes(bytes, i); i += 16; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); TerseDateID = new byte[length]; Buffer.BlockCopy(bytes, i, TerseDateID, 0, length); i += length; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); StartDateTime = new byte[length]; Buffer.BlockCopy(bytes, i, StartDateTime, 0, length); i += length; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); EndDateTime = new byte[length]; Buffer.BlockCopy(bytes, i, EndDateTime, 0, length); i += length; - AlreadyVoted = (bytes[i++] != 0) ? (bool)true : (bool)false; - length = bytes[i++]; + AlreadyVoted = (Utils.BytesToByte(bytes, ref i) != 0); + length = Utils.BytesToByte(bytes, ref i); VoteCast = new byte[length]; Buffer.BlockCopy(bytes, i, VoteCast, 0, length); i += length; Majority = Utils.BytesToFloatSafepos(bytes, i); i += 4; Quorum = Utils.BytesToIntSafepos(bytes, i); i +=4; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); ProposalText = new byte[length]; Buffer.BlockCopy(bytes, i, ProposalText, 0, length); i += length; } @@ -59411,18 +59433,18 @@ public override void ToBytes(byte[] bytes, ref int i) { VoteID.ToBytes(bytes, i); i += 16; VoteInitiator.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)TerseDateID.Length; + Utils.ByteToBytes((byte)TerseDateID.Length, bytes, ref i); Buffer.BlockCopy(TerseDateID, 0, bytes, i, TerseDateID.Length); i += TerseDateID.Length; - bytes[i++] = (byte)StartDateTime.Length; + Utils.ByteToBytes((byte)StartDateTime.Length, bytes, ref i); Buffer.BlockCopy(StartDateTime, 0, bytes, i, StartDateTime.Length); i += StartDateTime.Length; - bytes[i++] = (byte)EndDateTime.Length; + Utils.ByteToBytes((byte)EndDateTime.Length, bytes, ref i); Buffer.BlockCopy(EndDateTime, 0, bytes, i, EndDateTime.Length); i += EndDateTime.Length; - bytes[i++] = (byte)((AlreadyVoted) ? 1 : 0); - bytes[i++] = (byte)VoteCast.Length; + Utils.ByteToBytes((byte)((AlreadyVoted) ? 1 : 0), bytes, ref i); + Utils.ByteToBytes((byte)VoteCast.Length, bytes, ref i); Buffer.BlockCopy(VoteCast, 0, bytes, i, VoteCast.Length); i += VoteCast.Length; Utils.FloatToBytesSafepos(Majority, bytes, i); i += 4; Utils.IntToBytesSafepos(Quorum, bytes, i); i += 4; - bytes[i++] = (byte)ProposalText.Length; + Utils.ByteToBytes((byte)ProposalText.Length, bytes, ref i); Buffer.BlockCopy(ProposalText, 0, bytes, i, ProposalText.Length); i += ProposalText.Length; } @@ -59517,7 +59539,7 @@ public override byte[] ToBytes() Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); TransactionData.ToBytes(bytes, ref i); - bytes[i++] = (byte)ProposalData.Length; + Utils.ByteToBytes((byte)ProposalData.Length, bytes, ref i); for (int j = 0; j < ProposalData.Length; j++) { ProposalData[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -59913,25 +59935,25 @@ public override void FromBytes(byte[] bytes, ref int i) try { VoteID.FromBytes(bytes, i); i += 16; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); TerseDateID = new byte[length]; Buffer.BlockCopy(bytes, i, TerseDateID, 0, length); i += length; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); StartDateTime = new byte[length]; Buffer.BlockCopy(bytes, i, StartDateTime, 0, length); i += length; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); EndDateTime = new byte[length]; Buffer.BlockCopy(bytes, i, EndDateTime, 0, length); i += length; VoteInitiator.FromBytes(bytes, i); i += 16; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); VoteType = new byte[length]; Buffer.BlockCopy(bytes, i, VoteType, 0, length); i += length; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); VoteResult = new byte[length]; Buffer.BlockCopy(bytes, i, VoteResult, 0, length); i += length; Majority = Utils.BytesToFloatSafepos(bytes, i); i += 4; Quorum = Utils.BytesToIntSafepos(bytes, i); i +=4; - length = (bytes[i++] + (bytes[i++] << 8)); + length = Utils.BytesToUInt16(bytes, i); i+=2; ProposalText = new byte[length]; Buffer.BlockCopy(bytes, i, ProposalText, 0, length); i += length; } @@ -59944,21 +59966,20 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { VoteID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)TerseDateID.Length; + Utils.ByteToBytes((byte)TerseDateID.Length, bytes, ref i); Buffer.BlockCopy(TerseDateID, 0, bytes, i, TerseDateID.Length); i += TerseDateID.Length; - bytes[i++] = (byte)StartDateTime.Length; + Utils.ByteToBytes((byte)StartDateTime.Length, bytes, ref i); Buffer.BlockCopy(StartDateTime, 0, bytes, i, StartDateTime.Length); i += StartDateTime.Length; - bytes[i++] = (byte)EndDateTime.Length; + Utils.ByteToBytes((byte)EndDateTime.Length, bytes, ref i); Buffer.BlockCopy(EndDateTime, 0, bytes, i, EndDateTime.Length); i += EndDateTime.Length; VoteInitiator.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)VoteType.Length; + Utils.ByteToBytes((byte)VoteType.Length, bytes, ref i); Buffer.BlockCopy(VoteType, 0, bytes, i, VoteType.Length); i += VoteType.Length; - bytes[i++] = (byte)VoteResult.Length; + Utils.ByteToBytes((byte)VoteResult.Length, bytes, ref i); Buffer.BlockCopy(VoteResult, 0, bytes, i, VoteResult.Length); i += VoteResult.Length; Utils.FloatToBytesSafepos(Majority, bytes, i); i += 4; Utils.IntToBytesSafepos(Quorum, bytes, i); i += 4; - bytes[i++] = (byte)(ProposalText.Length % 256); - bytes[i++] = (byte)((ProposalText.Length >> 8) % 256); + Utils.UInt16ToBytes((ushort)ProposalText.Length, bytes, i); i += 2; Buffer.BlockCopy(ProposalText, 0, bytes, i, ProposalText.Length); i += ProposalText.Length; } @@ -59993,7 +60014,7 @@ public override void FromBytes(byte[] bytes, ref int i) try { CandidateID.FromBytes(bytes, i); i += 16; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); VoteCast = new byte[length]; Buffer.BlockCopy(bytes, i, VoteCast, 0, length); i += length; NumVotes = Utils.BytesToIntSafepos(bytes, i); i +=4; @@ -60007,7 +60028,7 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { CandidateID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)VoteCast.Length; + Utils.ByteToBytes((byte)VoteCast.Length, bytes, ref i); Buffer.BlockCopy(VoteCast, 0, bytes, i, VoteCast.Length); i += VoteCast.Length; Utils.IntToBytesSafepos(NumVotes, bytes, i); i += 4; } @@ -60110,7 +60131,7 @@ public override byte[] ToBytes() AgentData.ToBytes(bytes, ref i); TransactionData.ToBytes(bytes, ref i); HistoryItemData.ToBytes(bytes, ref i); - bytes[i++] = (byte)VoteItem.Length; + Utils.ByteToBytes((byte)VoteItem.Length, bytes, ref i); for (int j = 0; j < VoteItem.Length; j++) { VoteItem[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -60257,7 +60278,7 @@ public override void FromBytes(byte[] bytes, ref int i) Quorum = Utils.BytesToIntSafepos(bytes, i); i +=4; Majority = Utils.BytesToFloatSafepos(bytes, i); i += 4; Duration = Utils.BytesToIntSafepos(bytes, i); i +=4; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); ProposalText = new byte[length]; Buffer.BlockCopy(bytes, i, ProposalText, 0, length); i += length; } @@ -60273,7 +60294,7 @@ public override void ToBytes(byte[] bytes, ref int i) Utils.IntToBytesSafepos(Quorum, bytes, i); i += 4; Utils.FloatToBytesSafepos(Majority, bytes, i); i += 4; Utils.IntToBytesSafepos(Duration, bytes, i); i += 4; - bytes[i++] = (byte)ProposalText.Length; + Utils.ByteToBytes((byte)ProposalText.Length, bytes, ref i); Buffer.BlockCopy(ProposalText, 0, bytes, i, ProposalText.Length); i += ProposalText.Length; } @@ -60430,7 +60451,7 @@ public override void FromBytes(byte[] bytes, ref int i) { ProposalID.FromBytes(bytes, i); i += 16; GroupID.FromBytes(bytes, i); i += 16; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); VoteCast = new byte[length]; Buffer.BlockCopy(bytes, i, VoteCast, 0, length); i += length; } @@ -60444,7 +60465,7 @@ public override void ToBytes(byte[] bytes, ref int i) { ProposalID.ToBytes(bytes, i); i += 16; GroupID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)VoteCast.Length; + Utils.ByteToBytes((byte)VoteCast.Length, bytes, ref i); Buffer.BlockCopy(VoteCast, 0, bytes, i, VoteCast.Length); i += VoteCast.Length; } @@ -60806,14 +60827,14 @@ public override void FromBytes(byte[] bytes, ref int i) { AgentID.FromBytes(bytes, i); i += 16; Contribution = Utils.BytesToIntSafepos(bytes, i); i +=4; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); OnlineStatus = new byte[length]; Buffer.BlockCopy(bytes, i, OnlineStatus, 0, length); i += length; AgentPowers = Utils.BytesToUInt64Safepos(bytes, i); i += 8; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Title = new byte[length]; Buffer.BlockCopy(bytes, i, Title, 0, length); i += length; - IsOwner = (bytes[i++] != 0) ? (bool)true : (bool)false; + IsOwner = (Utils.BytesToByte(bytes, ref i) != 0); } catch (Exception) { @@ -60825,12 +60846,12 @@ public override void ToBytes(byte[] bytes, ref int i) { AgentID.ToBytes(bytes, i); i += 16; Utils.IntToBytesSafepos(Contribution, bytes, i); i += 4; - bytes[i++] = (byte)OnlineStatus.Length; + Utils.ByteToBytes((byte)OnlineStatus.Length, bytes, ref i); Buffer.BlockCopy(OnlineStatus, 0, bytes, i, OnlineStatus.Length); i += OnlineStatus.Length; Utils.UInt64ToBytesSafepos(AgentPowers, bytes, i); i += 8; - bytes[i++] = (byte)Title.Length; + Utils.ByteToBytes((byte)Title.Length, bytes, ref i); Buffer.BlockCopy(Title, 0, bytes, i, Title.Length); i += Title.Length; - bytes[i++] = (byte)((IsOwner) ? 1 : 0); + Utils.ByteToBytes((byte)((IsOwner) ? 1 : 0), bytes, ref i); } } @@ -60924,7 +60945,7 @@ public override byte[] ToBytes() Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); GroupData.ToBytes(bytes, ref i); - bytes[i++] = (byte)MemberData.Length; + Utils.ByteToBytes((byte)MemberData.Length, bytes, ref i); for (int j = 0; j < MemberData.Length; j++) { MemberData[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -61338,7 +61359,7 @@ public override void FromBytes(byte[] bytes, ref int i) try { GroupID.FromBytes(bytes, i); i += 16; - AcceptNotices = (bytes[i++] != 0) ? (bool)true : (bool)false; + AcceptNotices = (Utils.BytesToByte(bytes, ref i) != 0); } catch (Exception) { @@ -61349,7 +61370,7 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { GroupID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)((AcceptNotices) ? 1 : 0); + Utils.ByteToBytes((byte)((AcceptNotices) ? 1 : 0), bytes, ref i); } } @@ -61377,7 +61398,7 @@ public override void FromBytes(byte[] bytes, ref int i) { try { - ListInProfile = (bytes[i++] != 0) ? (bool)true : (bool)false; + ListInProfile = (Utils.BytesToByte(bytes, ref i) != 0); } catch (Exception) { @@ -61387,7 +61408,7 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { - bytes[i++] = (byte)((ListInProfile) ? 1 : 0); + Utils.ByteToBytes((byte)((ListInProfile) ? 1 : 0), bytes, ref i); } } @@ -61755,13 +61776,13 @@ public override void FromBytes(byte[] bytes, ref int i) try { RoleID.FromBytes(bytes, i); i += 16; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Name = new byte[length]; Buffer.BlockCopy(bytes, i, Name, 0, length); i += length; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Title = new byte[length]; Buffer.BlockCopy(bytes, i, Title, 0, length); i += length; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Description = new byte[length]; Buffer.BlockCopy(bytes, i, Description, 0, length); i += length; Powers = Utils.BytesToUInt64Safepos(bytes, i); i += 8; @@ -61776,11 +61797,11 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { RoleID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)Name.Length; + Utils.ByteToBytes((byte)Name.Length, bytes, ref i); Buffer.BlockCopy(Name, 0, bytes, i, Name.Length); i += Name.Length; - bytes[i++] = (byte)Title.Length; + Utils.ByteToBytes((byte)Title.Length, bytes, ref i); Buffer.BlockCopy(Title, 0, bytes, i, Title.Length); i += Title.Length; - bytes[i++] = (byte)Description.Length; + Utils.ByteToBytes((byte)Description.Length, bytes, ref i); Buffer.BlockCopy(Description, 0, bytes, i, Description.Length); i += Description.Length; Utils.UInt64ToBytesSafepos(Powers, bytes, i); i += 8; Utils.UIntToBytesSafepos(Members, bytes, i); i += 4; @@ -61876,7 +61897,7 @@ public override byte[] ToBytes() Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); GroupData.ToBytes(bytes, ref i); - bytes[i++] = (byte)RoleData.Length; + Utils.ByteToBytes((byte)RoleData.Length, bytes, ref i); for (int j = 0; j < RoleData.Length; j++) { RoleData[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -62276,7 +62297,7 @@ public override byte[] ToBytes() int i = 0; Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); - bytes[i++] = (byte)MemberData.Length; + Utils.ByteToBytes((byte)MemberData.Length, bytes, ref i); for (int j = 0; j < MemberData.Length; j++) { MemberData[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -62535,11 +62556,11 @@ public override void FromBytes(byte[] bytes, ref int i) int length; try { - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Title = new byte[length]; Buffer.BlockCopy(bytes, i, Title, 0, length); i += length; RoleID.FromBytes(bytes, i); i += 16; - Selected = (bytes[i++] != 0) ? (bool)true : (bool)false; + Selected = (Utils.BytesToByte(bytes, ref i) != 0); } catch (Exception) { @@ -62549,10 +62570,10 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { - bytes[i++] = (byte)Title.Length; + Utils.ByteToBytes((byte)Title.Length, bytes, ref i); Buffer.BlockCopy(Title, 0, bytes, i, Title.Length); i += Title.Length; RoleID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)((Selected) ? 1 : 0); + Utils.ByteToBytes((byte)((Selected) ? 1 : 0), bytes, ref i); } } @@ -62639,7 +62660,7 @@ public override byte[] ToBytes() int i = 0; Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); - bytes[i++] = (byte)GroupData.Length; + Utils.ByteToBytes((byte)GroupData.Length, bytes, ref i); for (int j = 0; j < GroupData.Length; j++) { GroupData[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -62904,17 +62925,17 @@ public override void FromBytes(byte[] bytes, ref int i) try { RoleID.FromBytes(bytes, i); i += 16; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Name = new byte[length]; Buffer.BlockCopy(bytes, i, Name, 0, length); i += length; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Description = new byte[length]; Buffer.BlockCopy(bytes, i, Description, 0, length); i += length; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Title = new byte[length]; Buffer.BlockCopy(bytes, i, Title, 0, length); i += length; Powers = Utils.BytesToUInt64Safepos(bytes, i); i += 8; - UpdateType = (byte)bytes[i++]; + UpdateType = Utils.BytesToByte(bytes, ref i); } catch (Exception) { @@ -62925,14 +62946,14 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { RoleID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)Name.Length; + Utils.ByteToBytes((byte)Name.Length, bytes, ref i); Buffer.BlockCopy(Name, 0, bytes, i, Name.Length); i += Name.Length; - bytes[i++] = (byte)Description.Length; + Utils.ByteToBytes((byte)Description.Length, bytes, ref i); Buffer.BlockCopy(Description, 0, bytes, i, Description.Length); i += Description.Length; - bytes[i++] = (byte)Title.Length; + Utils.ByteToBytes((byte)Title.Length, bytes, ref i); Buffer.BlockCopy(Title, 0, bytes, i, Title.Length); i += Title.Length; Utils.UInt64ToBytesSafepos(Powers, bytes, i); i += 8; - bytes[i++] = UpdateType; + Utils.ByteToBytes( UpdateType, bytes, ref i); } } @@ -63018,7 +63039,7 @@ public override byte[] ToBytes() int i = 0; Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); - bytes[i++] = (byte)RoleData.Length; + Utils.ByteToBytes((byte)RoleData.Length, bytes, ref i); for (int j = 0; j < RoleData.Length; j++) { RoleData[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -63229,7 +63250,7 @@ public override void FromBytes(byte[] bytes, ref int i) { RequestID.FromBytes(bytes, i); i += 16; GroupID.FromBytes(bytes, i); i += 16; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Selection = new byte[length]; Buffer.BlockCopy(bytes, i, Selection, 0, length); i += length; } @@ -63243,7 +63264,7 @@ public override void ToBytes(byte[] bytes, ref int i) { RequestID.ToBytes(bytes, i); i += 16; GroupID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)Selection.Length; + Utils.ByteToBytes((byte)Selection.Length, bytes, ref i); Buffer.BlockCopy(Selection, 0, bytes, i, Selection.Length); i += Selection.Length; } @@ -63505,7 +63526,7 @@ public override void FromBytes(byte[] bytes, ref int i) { ItemID.FromBytes(bytes, i); i += 16; AssetID.FromBytes(bytes, i); i += 16; - WearableType = (byte)bytes[i++]; + WearableType = Utils.BytesToByte(bytes, ref i); } catch (Exception) { @@ -63517,7 +63538,7 @@ public override void ToBytes(byte[] bytes, ref int i) { ItemID.ToBytes(bytes, i); i += 16; AssetID.ToBytes(bytes, i); i += 16; - bytes[i++] = WearableType; + Utils.ByteToBytes( WearableType, bytes, ref i); } } @@ -63604,7 +63625,7 @@ public override byte[] ToBytes() int i = 0; Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); - bytes[i++] = (byte)WearableData.Length; + Utils.ByteToBytes((byte)WearableData.Length, bytes, ref i); for (int j = 0; j < WearableData.Length; j++) { WearableData[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -63738,7 +63759,7 @@ public override void FromBytes(byte[] bytes, ref int i) try { ItemID.FromBytes(bytes, i); i += 16; - WearableType = (byte)bytes[i++]; + WearableType = Utils.BytesToByte(bytes, ref i); } catch (Exception) { @@ -63749,7 +63770,7 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { ItemID.ToBytes(bytes, i); i += 16; - bytes[i++] = WearableType; + Utils.ByteToBytes( WearableType, bytes, ref i); } } @@ -63836,7 +63857,7 @@ public override byte[] ToBytes() int i = 0; Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); - bytes[i++] = (byte)WearableData.Length; + Utils.ByteToBytes((byte)WearableData.Length, bytes, ref i); for (int j = 0; j < WearableData.Length; j++) { WearableData[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -63973,7 +63994,7 @@ public override void FromBytes(byte[] bytes, ref int i) try { ID.FromBytes(bytes, i); i += 16; - TextureIndex = (byte)bytes[i++]; + TextureIndex = Utils.BytesToByte(bytes, ref i); } catch (Exception) { @@ -63984,7 +64005,7 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { ID.ToBytes(bytes, i); i += 16; - bytes[i++] = TextureIndex; + Utils.ByteToBytes( TextureIndex, bytes, ref i); } } @@ -64070,7 +64091,7 @@ public override byte[] ToBytes() int i = 0; Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); - bytes[i++] = (byte)WearableData.Length; + Utils.ByteToBytes((byte)WearableData.Length, bytes, ref i); for (int j = 0; j < WearableData.Length; j++) { WearableData[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -64211,8 +64232,8 @@ public override void FromBytes(byte[] bytes, ref int i) try { TextureID.FromBytes(bytes, i); i += 16; - TextureIndex = (byte)bytes[i++]; - length = bytes[i++]; + TextureIndex = Utils.BytesToByte(bytes, ref i); + length = Utils.BytesToByte(bytes, ref i); HostName = new byte[length]; Buffer.BlockCopy(bytes, i, HostName, 0, length); i += length; } @@ -64225,8 +64246,8 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { TextureID.ToBytes(bytes, i); i += 16; - bytes[i++] = TextureIndex; - bytes[i++] = (byte)HostName.Length; + Utils.ByteToBytes( TextureIndex, bytes, ref i); + Utils.ByteToBytes((byte)HostName.Length, bytes, ref i); Buffer.BlockCopy(HostName, 0, bytes, i, HostName.Length); i += HostName.Length; } @@ -64313,7 +64334,7 @@ public override byte[] ToBytes() int i = 0; Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); - bytes[i++] = (byte)WearableData.Length; + Utils.ByteToBytes((byte)WearableData.Length, bytes, ref i); for (int j = 0; j < WearableData.Length; j++) { WearableData[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -64530,18 +64551,18 @@ public override void FromBytes(byte[] bytes, ref int i) try { AgentID.FromBytes(bytes, i); i += 16; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); FirstName = new byte[length]; Buffer.BlockCopy(bytes, i, FirstName, 0, length); i += length; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); LastName = new byte[length]; Buffer.BlockCopy(bytes, i, LastName, 0, length); i += length; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); GroupTitle = new byte[length]; Buffer.BlockCopy(bytes, i, GroupTitle, 0, length); i += length; ActiveGroupID.FromBytes(bytes, i); i += 16; GroupPowers = Utils.BytesToUInt64Safepos(bytes, i); i += 8; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); GroupName = new byte[length]; Buffer.BlockCopy(bytes, i, GroupName, 0, length); i += length; } @@ -64554,15 +64575,15 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { AgentID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)FirstName.Length; + Utils.ByteToBytes((byte)FirstName.Length, bytes, ref i); Buffer.BlockCopy(FirstName, 0, bytes, i, FirstName.Length); i += FirstName.Length; - bytes[i++] = (byte)LastName.Length; + Utils.ByteToBytes((byte)LastName.Length, bytes, ref i); Buffer.BlockCopy(LastName, 0, bytes, i, LastName.Length); i += LastName.Length; - bytes[i++] = (byte)GroupTitle.Length; + Utils.ByteToBytes((byte)GroupTitle.Length, bytes, ref i); Buffer.BlockCopy(GroupTitle, 0, bytes, i, GroupTitle.Length); i += GroupTitle.Length; ActiveGroupID.ToBytes(bytes, i); i += 16; Utils.UInt64ToBytesSafepos(GroupPowers, bytes, i); i += 8; - bytes[i++] = (byte)GroupName.Length; + Utils.ByteToBytes((byte)GroupName.Length, bytes, ref i); Buffer.BlockCopy(GroupName, 0, bytes, i, GroupName.Length); i += GroupName.Length; } @@ -64673,7 +64694,7 @@ public override void FromBytes(byte[] bytes, ref int i) AgentID.FromBytes(bytes, i); i += 16; GroupID.FromBytes(bytes, i); i += 16; AgentPowers = Utils.BytesToUInt64Safepos(bytes, i); i += 8; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); GroupTitle = new byte[length]; Buffer.BlockCopy(bytes, i, GroupTitle, 0, length); i += length; } @@ -64688,7 +64709,7 @@ public override void ToBytes(byte[] bytes, ref int i) AgentID.ToBytes(bytes, i); i += 16; GroupID.ToBytes(bytes, i); i += 16; Utils.UInt64ToBytesSafepos(AgentPowers, bytes, i); i += 8; - bytes[i++] = (byte)GroupTitle.Length; + Utils.ByteToBytes((byte)GroupTitle.Length, bytes, ref i); Buffer.BlockCopy(GroupTitle, 0, bytes, i, GroupTitle.Length); i += GroupTitle.Length; } @@ -64769,7 +64790,7 @@ public override byte[] ToBytes() byte[] bytes = new byte[length]; int i = 0; Header.ToBytes(bytes, ref i); - bytes[i++] = (byte)AgentGroupData.Length; + Utils.ByteToBytes((byte)AgentGroupData.Length, bytes, ref i); for (int j = 0; j < AgentGroupData.Length; j++) { AgentGroupData[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -64906,10 +64927,10 @@ public override void FromBytes(byte[] bytes, ref int i) { GroupID.FromBytes(bytes, i); i += 16; GroupPowers = Utils.BytesToUInt64Safepos(bytes, i); i += 8; - AcceptNotices = (bytes[i++] != 0) ? (bool)true : (bool)false; + AcceptNotices = (Utils.BytesToByte(bytes, ref i) != 0); GroupInsigniaID.FromBytes(bytes, i); i += 16; Contribution = Utils.BytesToIntSafepos(bytes, i); i +=4; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); GroupName = new byte[length]; Buffer.BlockCopy(bytes, i, GroupName, 0, length); i += length; } @@ -64923,10 +64944,10 @@ public override void ToBytes(byte[] bytes, ref int i) { GroupID.ToBytes(bytes, i); i += 16; Utils.UInt64ToBytesSafepos(GroupPowers, bytes, i); i += 8; - bytes[i++] = (byte)((AcceptNotices) ? 1 : 0); + Utils.ByteToBytes((byte)((AcceptNotices) ? 1 : 0), bytes, ref i); GroupInsigniaID.ToBytes(bytes, i); i += 16; Utils.IntToBytesSafepos(Contribution, bytes, i); i += 4; - bytes[i++] = (byte)GroupName.Length; + Utils.ByteToBytes((byte)GroupName.Length, bytes, ref i); Buffer.BlockCopy(GroupName, 0, bytes, i, GroupName.Length); i += GroupName.Length; } @@ -65014,7 +65035,7 @@ public override byte[] ToBytes() int i = 0; Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); - bytes[i++] = (byte)GroupData.Length; + Utils.ByteToBytes((byte)GroupData.Length, bytes, ref i); for (int j = 0; j < GroupData.Length; j++) { GroupData[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -65274,15 +65295,15 @@ public override void FromBytes(byte[] bytes, ref int i) { ItemID.FromBytes(bytes, i); i += 16; OwnerID.FromBytes(bytes, i); i += 16; - AttachmentPt = (byte)bytes[i++]; + AttachmentPt = Utils.BytesToByte(bytes, ref i); ItemFlags = Utils.BytesToUIntSafepos(bytes, i); i += 4; GroupMask = Utils.BytesToUIntSafepos(bytes, i); i += 4; EveryoneMask = Utils.BytesToUIntSafepos(bytes, i); i += 4; NextOwnerMask = Utils.BytesToUIntSafepos(bytes, i); i += 4; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Name = new byte[length]; Buffer.BlockCopy(bytes, i, Name, 0, length); i += length; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Description = new byte[length]; Buffer.BlockCopy(bytes, i, Description, 0, length); i += length; } @@ -65296,14 +65317,14 @@ public override void ToBytes(byte[] bytes, ref int i) { ItemID.ToBytes(bytes, i); i += 16; OwnerID.ToBytes(bytes, i); i += 16; - bytes[i++] = AttachmentPt; + Utils.ByteToBytes( AttachmentPt, bytes, ref i); Utils.UIntToBytesSafepos(ItemFlags, bytes, i); i += 4; Utils.UIntToBytesSafepos(GroupMask, bytes, i); i += 4; Utils.UIntToBytesSafepos(EveryoneMask, bytes, i); i += 4; Utils.UIntToBytesSafepos(NextOwnerMask, bytes, i); i += 4; - bytes[i++] = (byte)Name.Length; + Utils.ByteToBytes((byte)Name.Length, bytes, ref i); Buffer.BlockCopy(Name, 0, bytes, i, Name.Length); i += Name.Length; - bytes[i++] = (byte)Description.Length; + Utils.ByteToBytes((byte)Description.Length, bytes, ref i); Buffer.BlockCopy(Description, 0, bytes, i, Description.Length); i += Description.Length; } @@ -65456,8 +65477,8 @@ public override void FromBytes(byte[] bytes, ref int i) try { CompoundMsgID.FromBytes(bytes, i); i += 16; - TotalObjects = (byte)bytes[i++]; - FirstDetachAll = (bytes[i++] != 0) ? (bool)true : (bool)false; + TotalObjects = Utils.BytesToByte(bytes, ref i); + FirstDetachAll = (Utils.BytesToByte(bytes, ref i) != 0); } catch (Exception) { @@ -65468,8 +65489,8 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { CompoundMsgID.ToBytes(bytes, i); i += 16; - bytes[i++] = TotalObjects; - bytes[i++] = (byte)((FirstDetachAll) ? 1 : 0); + Utils.ByteToBytes( TotalObjects, bytes, ref i); + Utils.ByteToBytes((byte)((FirstDetachAll) ? 1 : 0), bytes, ref i); } } @@ -65511,15 +65532,15 @@ public override void FromBytes(byte[] bytes, ref int i) { ItemID.FromBytes(bytes, i); i += 16; OwnerID.FromBytes(bytes, i); i += 16; - AttachmentPt = (byte)bytes[i++]; + AttachmentPt = Utils.BytesToByte(bytes, ref i); ItemFlags = Utils.BytesToUIntSafepos(bytes, i); i += 4; GroupMask = Utils.BytesToUIntSafepos(bytes, i); i += 4; EveryoneMask = Utils.BytesToUIntSafepos(bytes, i); i += 4; NextOwnerMask = Utils.BytesToUIntSafepos(bytes, i); i += 4; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Name = new byte[length]; Buffer.BlockCopy(bytes, i, Name, 0, length); i += length; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Description = new byte[length]; Buffer.BlockCopy(bytes, i, Description, 0, length); i += length; } @@ -65533,14 +65554,14 @@ public override void ToBytes(byte[] bytes, ref int i) { ItemID.ToBytes(bytes, i); i += 16; OwnerID.ToBytes(bytes, i); i += 16; - bytes[i++] = AttachmentPt; + Utils.ByteToBytes( AttachmentPt, bytes, ref i); Utils.UIntToBytesSafepos(ItemFlags, bytes, i); i += 4; Utils.UIntToBytesSafepos(GroupMask, bytes, i); i += 4; Utils.UIntToBytesSafepos(EveryoneMask, bytes, i); i += 4; Utils.UIntToBytesSafepos(NextOwnerMask, bytes, i); i += 4; - bytes[i++] = (byte)Name.Length; + Utils.ByteToBytes((byte)Name.Length, bytes, ref i); Buffer.BlockCopy(Name, 0, bytes, i, Name.Length); i += Name.Length; - bytes[i++] = (byte)Description.Length; + Utils.ByteToBytes((byte)Description.Length, bytes, ref i); Buffer.BlockCopy(Description, 0, bytes, i, Description.Length); i += Description.Length; } @@ -65635,7 +65656,7 @@ public override byte[] ToBytes() Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); HeaderData.ToBytes(bytes, ref i); - bytes[i++] = (byte)ObjectData.Length; + Utils.ByteToBytes((byte)ObjectData.Length, bytes, ref i); for (int j = 0; j < ObjectData.Length; j++) { ObjectData[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -66026,7 +66047,7 @@ public override byte[] ToBytes() Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); HeaderData.ToBytes(bytes, ref i); - bytes[i++] = (byte)ObjectData.Length; + Utils.ByteToBytes((byte)ObjectData.Length, bytes, ref i); for (int j = 0; j < ObjectData.Length; j++) { ObjectData[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -66276,11 +66297,11 @@ public override void FromBytes(byte[] bytes, ref int i) int length; try { - IMViaEMail = (bytes[i++] != 0) ? (bool)true : (bool)false; - length = bytes[i++]; + IMViaEMail = (Utils.BytesToByte(bytes, ref i) != 0); + length = Utils.BytesToByte(bytes, ref i); DirectoryVisibility = new byte[length]; Buffer.BlockCopy(bytes, i, DirectoryVisibility, 0, length); i += length; - length = (bytes[i++] + (bytes[i++] << 8)); + length = Utils.BytesToUInt16(bytes, i); i+=2; EMail = new byte[length]; Buffer.BlockCopy(bytes, i, EMail, 0, length); i += length; } @@ -66292,11 +66313,10 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { - bytes[i++] = (byte)((IMViaEMail) ? 1 : 0); - bytes[i++] = (byte)DirectoryVisibility.Length; + Utils.ByteToBytes((byte)((IMViaEMail) ? 1 : 0), bytes, ref i); + Utils.ByteToBytes((byte)DirectoryVisibility.Length, bytes, ref i); Buffer.BlockCopy(DirectoryVisibility, 0, bytes, i, DirectoryVisibility.Length); i += DirectoryVisibility.Length; - bytes[i++] = (byte)(EMail.Length % 256); - bytes[i++] = (byte)((EMail.Length >> 8) % 256); + Utils.UInt16ToBytes((ushort)EMail.Length, bytes, i); i += 2; Buffer.BlockCopy(EMail, 0, bytes, i, EMail.Length); i += EMail.Length; } @@ -66449,8 +66469,8 @@ public override void FromBytes(byte[] bytes, ref int i) int length; try { - IMViaEMail = (bytes[i++] != 0) ? (bool)true : (bool)false; - length = bytes[i++]; + IMViaEMail = (Utils.BytesToByte(bytes, ref i) != 0); + length = Utils.BytesToByte(bytes, ref i); DirectoryVisibility = new byte[length]; Buffer.BlockCopy(bytes, i, DirectoryVisibility, 0, length); i += length; } @@ -66462,8 +66482,8 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { - bytes[i++] = (byte)((IMViaEMail) ? 1 : 0); - bytes[i++] = (byte)DirectoryVisibility.Length; + Utils.ByteToBytes((byte)((IMViaEMail) ? 1 : 0), bytes, ref i); + Utils.ByteToBytes((byte)DirectoryVisibility.Length, bytes, ref i); Buffer.BlockCopy(DirectoryVisibility, 0, bytes, i, DirectoryVisibility.Length); i += DirectoryVisibility.Length; } @@ -66614,10 +66634,10 @@ public override void FromBytes(byte[] bytes, ref int i) int length; try { - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); SimFilename = new byte[length]; Buffer.BlockCopy(bytes, i, SimFilename, 0, length); i += length; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); ViewerFilename = new byte[length]; Buffer.BlockCopy(bytes, i, ViewerFilename, 0, length); i += length; } @@ -66629,9 +66649,9 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { - bytes[i++] = (byte)SimFilename.Length; + Utils.ByteToBytes((byte)SimFilename.Length, bytes, ref i); Buffer.BlockCopy(SimFilename, 0, bytes, i, SimFilename.Length); i += SimFilename.Length; - bytes[i++] = (byte)ViewerFilename.Length; + Utils.ByteToBytes((byte)ViewerFilename.Length, bytes, ref i); Buffer.BlockCopy(ViewerFilename, 0, bytes, i, ViewerFilename.Length); i += ViewerFilename.Length; } @@ -66747,7 +66767,7 @@ public override void FromBytes(byte[] bytes, ref int i) SessionID.FromBytes(bytes, i); i += 16; Flags = Utils.BytesToUIntSafepos(bytes, i); i += 4; EstateID = Utils.BytesToUIntSafepos(bytes, i); i += 4; - Godlike = (bytes[i++] != 0) ? (bool)true : (bool)false; + Godlike = (Utils.BytesToByte(bytes, ref i) != 0); } catch (Exception) { @@ -66761,7 +66781,7 @@ public override void ToBytes(byte[] bytes, ref int i) SessionID.ToBytes(bytes, i); i += 16; Utils.UIntToBytesSafepos(Flags, bytes, i); i += 4; Utils.UIntToBytesSafepos(EstateID, bytes, i); i += 4; - bytes[i++] = (byte)((Godlike) ? 1 : 0); + Utils.ByteToBytes((byte)((Godlike) ? 1 : 0), bytes, ref i); } } @@ -67010,7 +67030,7 @@ public override byte[] ToBytes() int i = 0; Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); - bytes[i++] = (byte)LayerData.Length; + Utils.ByteToBytes((byte)LayerData.Length, bytes, ref i); for (int j = 0; j < LayerData.Length; j++) { LayerData[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -67109,7 +67129,7 @@ public override void FromBytes(byte[] bytes, ref int i) SessionID.FromBytes(bytes, i); i += 16; Flags = Utils.BytesToUIntSafepos(bytes, i); i += 4; EstateID = Utils.BytesToUIntSafepos(bytes, i); i += 4; - Godlike = (bytes[i++] != 0) ? (bool)true : (bool)false; + Godlike = (Utils.BytesToByte(bytes, ref i) != 0); } catch (Exception) { @@ -67123,7 +67143,7 @@ public override void ToBytes(byte[] bytes, ref int i) SessionID.ToBytes(bytes, i); i += 16; Utils.UIntToBytesSafepos(Flags, bytes, i); i += 4; Utils.UIntToBytesSafepos(EstateID, bytes, i); i += 4; - bytes[i++] = (byte)((Godlike) ? 1 : 0); + Utils.ByteToBytes((byte)((Godlike) ? 1 : 0), bytes, ref i); } } @@ -67285,7 +67305,7 @@ public override void FromBytes(byte[] bytes, ref int i) SessionID.FromBytes(bytes, i); i += 16; Flags = Utils.BytesToUIntSafepos(bytes, i); i += 4; EstateID = Utils.BytesToUIntSafepos(bytes, i); i += 4; - Godlike = (bytes[i++] != 0) ? (bool)true : (bool)false; + Godlike = (Utils.BytesToByte(bytes, ref i) != 0); } catch (Exception) { @@ -67299,7 +67319,7 @@ public override void ToBytes(byte[] bytes, ref int i) SessionID.ToBytes(bytes, i); i += 16; Utils.UIntToBytesSafepos(Flags, bytes, i); i += 4; Utils.UIntToBytesSafepos(EstateID, bytes, i); i += 4; - bytes[i++] = (byte)((Godlike) ? 1 : 0); + Utils.ByteToBytes((byte)((Godlike) ? 1 : 0), bytes, ref i); } } @@ -67330,7 +67350,7 @@ public override void FromBytes(byte[] bytes, ref int i) int length; try { - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Name = new byte[length]; Buffer.BlockCopy(bytes, i, Name, 0, length); i += length; } @@ -67342,7 +67362,7 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { - bytes[i++] = (byte)Name.Length; + Utils.ByteToBytes((byte)Name.Length, bytes, ref i); Buffer.BlockCopy(Name, 0, bytes, i, Name.Length); i += Name.Length; } @@ -67503,13 +67523,13 @@ public override void FromBytes(byte[] bytes, ref int i) { X = Utils.BytesToUInt16(bytes, i); i+=2; Y = Utils.BytesToUInt16(bytes, i); i+=2; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Name = new byte[length]; Buffer.BlockCopy(bytes, i, Name, 0, length); i += length; - Access = (byte)bytes[i++]; + Access = Utils.BytesToByte(bytes, ref i); RegionFlags = Utils.BytesToUIntSafepos(bytes, i); i += 4; - WaterHeight = (byte)bytes[i++]; - Agents = (byte)bytes[i++]; + WaterHeight = Utils.BytesToByte(bytes, ref i); + Agents = Utils.BytesToByte(bytes, ref i); MapImageID.FromBytes(bytes, i); i += 16; } catch (Exception) @@ -67522,12 +67542,12 @@ public override void ToBytes(byte[] bytes, ref int i) { Utils.UInt16ToBytes(X, bytes, i); i += 2; Utils.UInt16ToBytes(Y, bytes, i); i += 2; - bytes[i++] = (byte)Name.Length; + Utils.ByteToBytes((byte)Name.Length, bytes, ref i); Buffer.BlockCopy(Name, 0, bytes, i, Name.Length); i += Name.Length; - bytes[i++] = Access; + Utils.ByteToBytes( Access, bytes, ref i); Utils.UIntToBytesSafepos(RegionFlags, bytes, i); i += 4; - bytes[i++] = WaterHeight; - bytes[i++] = Agents; + Utils.ByteToBytes( WaterHeight, bytes, ref i); + Utils.ByteToBytes( Agents, bytes, ref i); MapImageID.ToBytes(bytes, i); i += 16; } @@ -67677,9 +67697,9 @@ public override byte[] ToBytes() int i = 0; Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); - bytes[i++] = (byte)Data.Length; + Utils.ByteToBytes((byte)Data.Length, bytes, ref i); for (int j = 0; j < Data.Length; j++) { Data[j].ToBytes(bytes, ref i); } - bytes[i++] = (byte)Size.Length; + Utils.ByteToBytes((byte)Size.Length, bytes, ref i); for (int j = 0; j < Size.Length; j++) { Size[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -67796,7 +67816,7 @@ public override void FromBytes(byte[] bytes, ref int i) SessionID.FromBytes(bytes, i); i += 16; Flags = Utils.BytesToUIntSafepos(bytes, i); i += 4; EstateID = Utils.BytesToUIntSafepos(bytes, i); i += 4; - Godlike = (bytes[i++] != 0) ? (bool)true : (bool)false; + Godlike = (Utils.BytesToByte(bytes, ref i) != 0); } catch (Exception) { @@ -67810,7 +67830,7 @@ public override void ToBytes(byte[] bytes, ref int i) SessionID.ToBytes(bytes, i); i += 16; Utils.UIntToBytesSafepos(Flags, bytes, i); i += 4; Utils.UIntToBytesSafepos(EstateID, bytes, i); i += 4; - bytes[i++] = (byte)((Godlike) ? 1 : 0); + Utils.ByteToBytes((byte)((Godlike) ? 1 : 0), bytes, ref i); } } @@ -68050,7 +68070,7 @@ public override void FromBytes(byte[] bytes, ref int i) ID.FromBytes(bytes, i); i += 16; Extra = Utils.BytesToIntSafepos(bytes, i); i +=4; Extra2 = Utils.BytesToIntSafepos(bytes, i); i +=4; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Name = new byte[length]; Buffer.BlockCopy(bytes, i, Name, 0, length); i += length; } @@ -68067,7 +68087,7 @@ public override void ToBytes(byte[] bytes, ref int i) ID.ToBytes(bytes, i); i += 16; Utils.IntToBytesSafepos(Extra, bytes, i); i += 4; Utils.IntToBytesSafepos(Extra2, bytes, i); i += 4; - bytes[i++] = (byte)Name.Length; + Utils.ByteToBytes((byte)Name.Length, bytes, ref i); Buffer.BlockCopy(Name, 0, bytes, i, Name.Length); i += Name.Length; } @@ -68161,7 +68181,7 @@ public override byte[] ToBytes() Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); RequestData.ToBytes(bytes, ref i); - bytes[i++] = (byte)Data.Length; + Utils.ByteToBytes((byte)Data.Length, bytes, ref i); for (int j = 0; j < Data.Length; j++) { Data[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -68275,23 +68295,23 @@ public override void FromBytes(byte[] bytes, ref int i) SessionID.FromBytes(bytes, i); i += 16; AssetID.FromBytes(bytes, i); i += 16; PosGlobal.FromBytes(bytes, i); i += 24; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); To = new byte[length]; Buffer.BlockCopy(bytes, i, To, 0, length); i += length; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); From = new byte[length]; Buffer.BlockCopy(bytes, i, From, 0, length); i += length; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Name = new byte[length]; Buffer.BlockCopy(bytes, i, Name, 0, length); i += length; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Subject = new byte[length]; Buffer.BlockCopy(bytes, i, Subject, 0, length); i += length; - length = (bytes[i++] + (bytes[i++] << 8)); + length = Utils.BytesToUInt16(bytes, i); i+=2; Msg = new byte[length]; Buffer.BlockCopy(bytes, i, Msg, 0, length); i += length; - AllowPublish = (bytes[i++] != 0) ? (bool)true : (bool)false; - MaturePublish = (bytes[i++] != 0) ? (bool)true : (bool)false; + AllowPublish = (Utils.BytesToByte(bytes, ref i) != 0); + MaturePublish = (Utils.BytesToByte(bytes, ref i) != 0); } catch (Exception) { @@ -68305,19 +68325,18 @@ public override void ToBytes(byte[] bytes, ref int i) SessionID.ToBytes(bytes, i); i += 16; AssetID.ToBytes(bytes, i); i += 16; PosGlobal.ToBytes(bytes, i); i += 24; - bytes[i++] = (byte)To.Length; + Utils.ByteToBytes((byte)To.Length, bytes, ref i); Buffer.BlockCopy(To, 0, bytes, i, To.Length); i += To.Length; - bytes[i++] = (byte)From.Length; + Utils.ByteToBytes((byte)From.Length, bytes, ref i); Buffer.BlockCopy(From, 0, bytes, i, From.Length); i += From.Length; - bytes[i++] = (byte)Name.Length; + Utils.ByteToBytes((byte)Name.Length, bytes, ref i); Buffer.BlockCopy(Name, 0, bytes, i, Name.Length); i += Name.Length; - bytes[i++] = (byte)Subject.Length; + Utils.ByteToBytes((byte)Subject.Length, bytes, ref i); Buffer.BlockCopy(Subject, 0, bytes, i, Subject.Length); i += Subject.Length; - bytes[i++] = (byte)(Msg.Length % 256); - bytes[i++] = (byte)((Msg.Length >> 8) % 256); + Utils.UInt16ToBytes((ushort)Msg.Length, bytes, i); i += 2; Buffer.BlockCopy(Msg, 0, bytes, i, Msg.Length); i += Msg.Length; - bytes[i++] = (byte)((AllowPublish) ? 1 : 0); - bytes[i++] = (byte)((MaturePublish) ? 1 : 0); + Utils.ByteToBytes((byte)((AllowPublish) ? 1 : 0), bytes, ref i); + Utils.ByteToBytes((byte)((MaturePublish) ? 1 : 0), bytes, ref i); } } @@ -68538,11 +68557,11 @@ public override void FromBytes(byte[] bytes, ref int i) int length; try { - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); MediaURL = new byte[length]; Buffer.BlockCopy(bytes, i, MediaURL, 0, length); i += length; MediaID.FromBytes(bytes, i); i += 16; - MediaAutoScale = (byte)bytes[i++]; + MediaAutoScale = Utils.BytesToByte(bytes, ref i); } catch (Exception) { @@ -68552,10 +68571,10 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { - bytes[i++] = (byte)MediaURL.Length; + Utils.ByteToBytes((byte)MediaURL.Length, bytes, ref i); Buffer.BlockCopy(MediaURL, 0, bytes, i, MediaURL.Length); i += MediaURL.Length; MediaID.ToBytes(bytes, i); i += 16; - bytes[i++] = MediaAutoScale; + Utils.ByteToBytes( MediaAutoScale, bytes, ref i); } } @@ -68591,15 +68610,15 @@ public override void FromBytes(byte[] bytes, ref int i) int length; try { - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); MediaType = new byte[length]; Buffer.BlockCopy(bytes, i, MediaType, 0, length); i += length; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); MediaDesc = new byte[length]; Buffer.BlockCopy(bytes, i, MediaDesc, 0, length); i += length; MediaWidth = Utils.BytesToIntSafepos(bytes, i); i +=4; MediaHeight = Utils.BytesToIntSafepos(bytes, i); i +=4; - MediaLoop = (byte)bytes[i++]; + MediaLoop = Utils.BytesToByte(bytes, ref i); } catch (Exception) { @@ -68609,13 +68628,13 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { - bytes[i++] = (byte)MediaType.Length; + Utils.ByteToBytes((byte)MediaType.Length, bytes, ref i); Buffer.BlockCopy(MediaType, 0, bytes, i, MediaType.Length); i += MediaType.Length; - bytes[i++] = (byte)MediaDesc.Length; + Utils.ByteToBytes((byte)MediaDesc.Length, bytes, ref i); Buffer.BlockCopy(MediaDesc, 0, bytes, i, MediaDesc.Length); i += MediaDesc.Length; Utils.IntToBytesSafepos(MediaWidth, bytes, i); i += 4; Utils.IntToBytesSafepos(MediaHeight, bytes, i); i += 4; - bytes[i++] = MediaLoop; + Utils.ByteToBytes( MediaLoop, bytes, ref i); } } @@ -68771,7 +68790,7 @@ public override void FromBytes(byte[] bytes, ref int i) { ReportType = Utils.BytesToUIntSafepos(bytes, i); i += 4; RequestFlags = Utils.BytesToUIntSafepos(bytes, i); i += 4; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Filter = new byte[length]; Buffer.BlockCopy(bytes, i, Filter, 0, length); i += length; ParcelLocalID = Utils.BytesToIntSafepos(bytes, i); i +=4; @@ -68786,7 +68805,7 @@ public override void ToBytes(byte[] bytes, ref int i) { Utils.UIntToBytesSafepos(ReportType, bytes, i); i += 4; Utils.UIntToBytesSafepos(RequestFlags, bytes, i); i += 4; - bytes[i++] = (byte)Filter.Length; + Utils.ByteToBytes((byte)Filter.Length, bytes, ref i); Buffer.BlockCopy(Filter, 0, bytes, i, Filter.Length); i += Filter.Length; Utils.IntToBytesSafepos(ParcelLocalID, bytes, i); i += 4; } @@ -68956,10 +68975,10 @@ public override void FromBytes(byte[] bytes, ref int i) LocationY = Utils.BytesToFloatSafepos(bytes, i); i += 4; LocationZ = Utils.BytesToFloatSafepos(bytes, i); i += 4; Score = Utils.BytesToFloatSafepos(bytes, i); i += 4; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); TaskName = new byte[length]; Buffer.BlockCopy(bytes, i, TaskName, 0, length); i += length; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); OwnerName = new byte[length]; Buffer.BlockCopy(bytes, i, OwnerName, 0, length); i += length; } @@ -68977,9 +68996,9 @@ public override void ToBytes(byte[] bytes, ref int i) Utils.FloatToBytesSafepos(LocationY, bytes, i); i += 4; Utils.FloatToBytesSafepos(LocationZ, bytes, i); i += 4; Utils.FloatToBytesSafepos(Score, bytes, i); i += 4; - bytes[i++] = (byte)TaskName.Length; + Utils.ByteToBytes((byte)TaskName.Length, bytes, ref i); Buffer.BlockCopy(TaskName, 0, bytes, i, TaskName.Length); i += TaskName.Length; - bytes[i++] = (byte)OwnerName.Length; + Utils.ByteToBytes((byte)OwnerName.Length, bytes, ref i); Buffer.BlockCopy(OwnerName, 0, bytes, i, OwnerName.Length); i += OwnerName.Length; } @@ -69066,7 +69085,7 @@ public override byte[] ToBytes() int i = 0; Header.ToBytes(bytes, ref i); RequestData.ToBytes(bytes, ref i); - bytes[i++] = (byte)ReportData.Length; + Utils.ByteToBytes((byte)ReportData.Length, bytes, ref i); for (int j = 0; j < ReportData.Length; j++) { ReportData[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -69207,17 +69226,17 @@ public override void FromBytes(byte[] bytes, ref int i) try { Code = Utils.BytesToIntSafepos(bytes, i); i +=4; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Token = new byte[length]; Buffer.BlockCopy(bytes, i, Token, 0, length); i += length; ID.FromBytes(bytes, i); i += 16; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); System = new byte[length]; Buffer.BlockCopy(bytes, i, System, 0, length); i += length; - length = (bytes[i++] + (bytes[i++] << 8)); + length = Utils.BytesToUInt16(bytes, i); i+=2; Message = new byte[length]; Buffer.BlockCopy(bytes, i, Message, 0, length); i += length; - length = (bytes[i++] + (bytes[i++] << 8)); + length = Utils.BytesToUInt16(bytes, i); i+=2; Data = new byte[length]; Buffer.BlockCopy(bytes, i, Data, 0, length); i += length; } @@ -69230,16 +69249,14 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { Utils.IntToBytesSafepos(Code, bytes, i); i += 4; - bytes[i++] = (byte)Token.Length; + Utils.ByteToBytes((byte)Token.Length, bytes, ref i); Buffer.BlockCopy(Token, 0, bytes, i, Token.Length); i += Token.Length; ID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)System.Length; + Utils.ByteToBytes((byte)System.Length, bytes, ref i); Buffer.BlockCopy(System, 0, bytes, i, System.Length); i += System.Length; - bytes[i++] = (byte)(Message.Length % 256); - bytes[i++] = (byte)((Message.Length >> 8) % 256); + Utils.UInt16ToBytes((ushort)Message.Length, bytes, i); i += 2; Buffer.BlockCopy(Message, 0, bytes, i, Message.Length); i += Message.Length; - bytes[i++] = (byte)(Data.Length % 256); - bytes[i++] = (byte)((Data.Length >> 8) % 256); + Utils.UInt16ToBytes((ushort)Data.Length, bytes, i); i += 2; Buffer.BlockCopy(Data, 0, bytes, i, Data.Length); i += Data.Length; } @@ -69391,7 +69408,7 @@ public override void FromBytes(byte[] bytes, ref int i) try { ObjectLocalID = Utils.BytesToUIntSafepos(bytes, i); i += 4; - IncludeInSearch = (bytes[i++] != 0) ? (bool)true : (bool)false; + IncludeInSearch = (Utils.BytesToByte(bytes, ref i) != 0); } catch (Exception) { @@ -69402,7 +69419,7 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { Utils.UIntToBytesSafepos(ObjectLocalID, bytes, i); i += 4; - bytes[i++] = (byte)((IncludeInSearch) ? 1 : 0); + Utils.ByteToBytes((byte)((IncludeInSearch) ? 1 : 0), bytes, ref i); } } @@ -69488,7 +69505,7 @@ public override byte[] ToBytes() int i = 0; Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); - bytes[i++] = (byte)ObjectData.Length; + Utils.ByteToBytes((byte)ObjectData.Length, bytes, ref i); for (int j = 0; j < ObjectData.Length; j++) { ObjectData[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -69654,17 +69671,17 @@ public override void FromBytes(byte[] bytes, ref int i) GroupMask = Utils.BytesToUIntSafepos(bytes, i); i += 4; EveryoneMask = Utils.BytesToUIntSafepos(bytes, i); i += 4; NextOwnerMask = Utils.BytesToUIntSafepos(bytes, i); i += 4; - GroupOwned = (bytes[i++] != 0) ? (bool)true : (bool)false; + GroupOwned = (Utils.BytesToByte(bytes, ref i) != 0); TransactionID.FromBytes(bytes, i); i += 16; - Type = (sbyte)bytes[i++]; - InvType = (sbyte)bytes[i++]; + Type = (sbyte)Utils.BytesToByte(bytes, ref i); + InvType = (sbyte)Utils.BytesToByte(bytes, ref i); Flags = Utils.BytesToUIntSafepos(bytes, i); i += 4; - SaleType = (byte)bytes[i++]; + SaleType = Utils.BytesToByte(bytes, ref i); SalePrice = Utils.BytesToIntSafepos(bytes, i); i +=4; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Name = new byte[length]; Buffer.BlockCopy(bytes, i, Name, 0, length); i += length; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Description = new byte[length]; Buffer.BlockCopy(bytes, i, Description, 0, length); i += length; CreationDate = Utils.BytesToIntSafepos(bytes, i); i +=4; @@ -69688,16 +69705,16 @@ public override void ToBytes(byte[] bytes, ref int i) Utils.UIntToBytesSafepos(GroupMask, bytes, i); i += 4; Utils.UIntToBytesSafepos(EveryoneMask, bytes, i); i += 4; Utils.UIntToBytesSafepos(NextOwnerMask, bytes, i); i += 4; - bytes[i++] = (byte)((GroupOwned) ? 1 : 0); + Utils.ByteToBytes((byte)((GroupOwned) ? 1 : 0), bytes, ref i); TransactionID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)Type; - bytes[i++] = (byte)InvType; + Utils.ByteToBytes( (byte)Type, bytes, ref i); + Utils.ByteToBytes( (byte)InvType, bytes, ref i); Utils.UIntToBytesSafepos(Flags, bytes, i); i += 4; - bytes[i++] = SaleType; + Utils.ByteToBytes( SaleType, bytes, ref i); Utils.IntToBytesSafepos(SalePrice, bytes, i); i += 4; - bytes[i++] = (byte)Name.Length; + Utils.ByteToBytes((byte)Name.Length, bytes, ref i); Buffer.BlockCopy(Name, 0, bytes, i, Name.Length); i += Name.Length; - bytes[i++] = (byte)Description.Length; + Utils.ByteToBytes((byte)Description.Length, bytes, ref i); Buffer.BlockCopy(Description, 0, bytes, i, Description.Length); i += Description.Length; Utils.IntToBytesSafepos(CreationDate, bytes, i); i += 4; Utils.UIntToBytesSafepos(CRC, bytes, i); i += 4; @@ -69863,12 +69880,12 @@ public override void FromBytes(byte[] bytes, ref int i) FolderID.FromBytes(bytes, i); i += 16; TransactionID.FromBytes(bytes, i); i += 16; OldItemID.FromBytes(bytes, i); i += 16; - Type = (sbyte)bytes[i++]; - InvType = (sbyte)bytes[i++]; - length = bytes[i++]; + Type = (sbyte)Utils.BytesToByte(bytes, ref i); + InvType = (sbyte)Utils.BytesToByte(bytes, ref i); + length = Utils.BytesToByte(bytes, ref i); Name = new byte[length]; Buffer.BlockCopy(bytes, i, Name, 0, length); i += length; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Description = new byte[length]; Buffer.BlockCopy(bytes, i, Description, 0, length); i += length; } @@ -69884,11 +69901,11 @@ public override void ToBytes(byte[] bytes, ref int i) FolderID.ToBytes(bytes, i); i += 16; TransactionID.ToBytes(bytes, i); i += 16; OldItemID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)Type; - bytes[i++] = (byte)InvType; - bytes[i++] = (byte)Name.Length; + Utils.ByteToBytes( (byte)Type, bytes, ref i); + Utils.ByteToBytes( (byte)InvType, bytes, ref i); + Utils.ByteToBytes((byte)Name.Length, bytes, ref i); Buffer.BlockCopy(Name, 0, bytes, i, Name.Length); i += Name.Length; - bytes[i++] = (byte)Description.Length; + Utils.ByteToBytes((byte)Description.Length, bytes, ref i); Buffer.BlockCopy(Description, 0, bytes, i, Description.Length); i += Description.Length; } @@ -70045,7 +70062,7 @@ public override void FromBytes(byte[] bytes, ref int i) int length; try { - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Method = new byte[length]; Buffer.BlockCopy(bytes, i, Method, 0, length); i += length; Invoice.FromBytes(bytes, i); i += 16; @@ -70058,7 +70075,7 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { - bytes[i++] = (byte)Method.Length; + Utils.ByteToBytes((byte)Method.Length, bytes, ref i); Buffer.BlockCopy(Method, 0, bytes, i, Method.Length); i += Method.Length; Invoice.ToBytes(bytes, i); i += 16; } @@ -70091,7 +70108,7 @@ public override void FromBytes(byte[] bytes, ref int i) int length; try { - length = (bytes[i++] + (bytes[i++] << 8)); + length = Utils.BytesToUInt16(bytes, i); i+=2; Parameter = new byte[length]; Buffer.BlockCopy(bytes, i, Parameter, 0, length); i += length; } @@ -70103,8 +70120,7 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { - bytes[i++] = (byte)(Parameter.Length % 256); - bytes[i++] = (byte)((Parameter.Length >> 8) % 256); + Utils.UInt16ToBytes((ushort)Parameter.Length, bytes, i); i += 2; Buffer.BlockCopy(Parameter, 0, bytes, i, Parameter.Length); i += Parameter.Length; } @@ -70198,7 +70214,7 @@ public override byte[] ToBytes() Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); MethodData.ToBytes(bytes, ref i); - bytes[i++] = (byte)ParamList.Length; + Utils.ByteToBytes((byte)ParamList.Length, bytes, ref i); for (int j = 0; j < ParamList.Length; j++) { ParamList[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -70380,7 +70396,7 @@ public override byte[] ToBytes() byte[] bytes = new byte[length]; int i = 0; Header.ToBytes(bytes, ref i); - bytes[i++] = (byte)Packets.Length; + Utils.ByteToBytes((byte)Packets.Length, bytes, ref i); for (int j = 0; j < Packets.Length; j++) { Packets[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -70482,8 +70498,7 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { Utils.UIntToBytesSafepos(IP, bytes, i); i += 4; - bytes[i++] = (byte)((Port >> 8) % 256); - bytes[i++] = (byte)(Port % 256); + Utils.UInt16ToBytesBig(Port, bytes, i); i += 2; } } @@ -70720,35 +70735,35 @@ public override void FromBytes(byte[] bytes, ref int i) { try { - PCode = (byte)bytes[i++]; - Material = (byte)bytes[i++]; + PCode = Utils.BytesToByte(bytes, ref i); + Material = Utils.BytesToByte(bytes, ref i); AddFlags = Utils.BytesToUIntSafepos(bytes, i); i += 4; - PathCurve = (byte)bytes[i++]; - ProfileCurve = (byte)bytes[i++]; + PathCurve = Utils.BytesToByte(bytes, ref i); + ProfileCurve = Utils.BytesToByte(bytes, ref i); PathBegin = Utils.BytesToUInt16(bytes, i); i+=2; PathEnd = Utils.BytesToUInt16(bytes, i); i+=2; - PathScaleX = (byte)bytes[i++]; - PathScaleY = (byte)bytes[i++]; - PathShearX = (byte)bytes[i++]; - PathShearY = (byte)bytes[i++]; - PathTwist = (sbyte)bytes[i++]; - PathTwistBegin = (sbyte)bytes[i++]; - PathRadiusOffset = (sbyte)bytes[i++]; - PathTaperX = (sbyte)bytes[i++]; - PathTaperY = (sbyte)bytes[i++]; - PathRevolutions = (byte)bytes[i++]; - PathSkew = (sbyte)bytes[i++]; + PathScaleX = Utils.BytesToByte(bytes, ref i); + PathScaleY = Utils.BytesToByte(bytes, ref i); + PathShearX = Utils.BytesToByte(bytes, ref i); + PathShearY = Utils.BytesToByte(bytes, ref i); + PathTwist = (sbyte)Utils.BytesToByte(bytes, ref i); + PathTwistBegin = (sbyte)Utils.BytesToByte(bytes, ref i); + PathRadiusOffset = (sbyte)Utils.BytesToByte(bytes, ref i); + PathTaperX = (sbyte)Utils.BytesToByte(bytes, ref i); + PathTaperY = (sbyte)Utils.BytesToByte(bytes, ref i); + PathRevolutions = Utils.BytesToByte(bytes, ref i); + PathSkew = (sbyte)Utils.BytesToByte(bytes, ref i); ProfileBegin = Utils.BytesToUInt16(bytes, i); i+=2; ProfileEnd = Utils.BytesToUInt16(bytes, i); i+=2; ProfileHollow = Utils.BytesToUInt16(bytes, i); i+=2; - BypassRaycast = (byte)bytes[i++]; + BypassRaycast = Utils.BytesToByte(bytes, ref i); RayStart.FromBytes(bytes, i); i += 12; RayEnd.FromBytes(bytes, i); i += 12; RayTargetID.FromBytes(bytes, i); i += 16; - RayEndIsIntersection = (byte)bytes[i++]; + RayEndIsIntersection = Utils.BytesToByte(bytes, ref i); Scale.FromBytes(bytes, i); i += 12; Rotation.FromBytes(bytes, i, true); i += 12; - State = (byte)bytes[i++]; + State = Utils.BytesToByte(bytes, ref i); } catch (Exception) { @@ -70758,35 +70773,35 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { - bytes[i++] = PCode; - bytes[i++] = Material; + Utils.ByteToBytes( PCode, bytes, ref i); + Utils.ByteToBytes( Material, bytes, ref i); Utils.UIntToBytesSafepos(AddFlags, bytes, i); i += 4; - bytes[i++] = PathCurve; - bytes[i++] = ProfileCurve; + Utils.ByteToBytes( PathCurve, bytes, ref i); + Utils.ByteToBytes( ProfileCurve, bytes, ref i); Utils.UInt16ToBytes(PathBegin, bytes, i); i += 2; Utils.UInt16ToBytes(PathEnd, bytes, i); i += 2; - bytes[i++] = PathScaleX; - bytes[i++] = PathScaleY; - bytes[i++] = PathShearX; - bytes[i++] = PathShearY; - bytes[i++] = (byte)PathTwist; - bytes[i++] = (byte)PathTwistBegin; - bytes[i++] = (byte)PathRadiusOffset; - bytes[i++] = (byte)PathTaperX; - bytes[i++] = (byte)PathTaperY; - bytes[i++] = PathRevolutions; - bytes[i++] = (byte)PathSkew; + Utils.ByteToBytes( PathScaleX, bytes, ref i); + Utils.ByteToBytes( PathScaleY, bytes, ref i); + Utils.ByteToBytes( PathShearX, bytes, ref i); + Utils.ByteToBytes( PathShearY, bytes, ref i); + Utils.ByteToBytes( (byte)PathTwist, bytes, ref i); + Utils.ByteToBytes( (byte)PathTwistBegin, bytes, ref i); + Utils.ByteToBytes( (byte)PathRadiusOffset, bytes, ref i); + Utils.ByteToBytes( (byte)PathTaperX, bytes, ref i); + Utils.ByteToBytes( (byte)PathTaperY, bytes, ref i); + Utils.ByteToBytes( PathRevolutions, bytes, ref i); + Utils.ByteToBytes( (byte)PathSkew, bytes, ref i); Utils.UInt16ToBytes(ProfileBegin, bytes, i); i += 2; Utils.UInt16ToBytes(ProfileEnd, bytes, i); i += 2; Utils.UInt16ToBytes(ProfileHollow, bytes, i); i += 2; - bytes[i++] = BypassRaycast; + Utils.ByteToBytes( BypassRaycast, bytes, ref i); RayStart.ToBytes(bytes, i); i += 12; RayEnd.ToBytes(bytes, i); i += 12; RayTargetID.ToBytes(bytes, i); i += 16; - bytes[i++] = RayEndIsIntersection; + Utils.ByteToBytes( RayEndIsIntersection, bytes, ref i); Scale.ToBytes(bytes, i); i += 12; Rotation.ToBytes(bytes, i); i += 12; - bytes[i++] = State; + Utils.ByteToBytes( State, bytes, ref i); } } @@ -70941,8 +70956,8 @@ public override void FromBytes(byte[] bytes, ref int i) try { ObjectLocalID = Utils.BytesToUIntSafepos(bytes, i); i += 4; - Type = (byte)bytes[i++]; - length = bytes[i++]; + Type = Utils.BytesToByte(bytes, ref i); + length = Utils.BytesToByte(bytes, ref i); Data = new byte[length]; Buffer.BlockCopy(bytes, i, Data, 0, length); i += length; } @@ -70955,8 +70970,8 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { Utils.UIntToBytesSafepos(ObjectLocalID, bytes, i); i += 4; - bytes[i++] = Type; - bytes[i++] = (byte)Data.Length; + Utils.ByteToBytes( Type, bytes, ref i); + Utils.ByteToBytes((byte)Data.Length, bytes, ref i); Buffer.BlockCopy(Data, 0, bytes, i, Data.Length); i += Data.Length; } @@ -71044,7 +71059,7 @@ public override byte[] ToBytes() int i = 0; Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); - bytes[i++] = (byte)ObjectData.Length; + Utils.ByteToBytes((byte)ObjectData.Length, bytes, ref i); for (int j = 0; j < ObjectData.Length; j++) { ObjectData[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -71177,7 +71192,7 @@ public override void FromBytes(byte[] bytes, ref int i) { try { - CacheMissType = (byte)bytes[i++]; + CacheMissType = Utils.BytesToByte(bytes, ref i); ID = Utils.BytesToUIntSafepos(bytes, i); i += 4; } catch (Exception) @@ -71188,7 +71203,7 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { - bytes[i++] = CacheMissType; + Utils.ByteToBytes( CacheMissType, bytes, ref i); Utils.UIntToBytesSafepos(ID, bytes, i); i += 4; } @@ -71276,7 +71291,7 @@ public override byte[] ToBytes() int i = 0; Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); - bytes[i++] = (byte)ObjectData.Length; + Utils.ByteToBytes((byte)ObjectData.Length, bytes, ref i); for (int j = 0; j < ObjectData.Length; j++) { ObjectData[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -71508,7 +71523,7 @@ public override byte[] ToBytes() int i = 0; Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); - bytes[i++] = (byte)ObjectData.Length; + Utils.ByteToBytes((byte)ObjectData.Length, bytes, ref i); for (int j = 0; j < ObjectData.Length; j++) { ObjectData[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -71763,9 +71778,9 @@ public override void FromBytes(byte[] bytes, ref int i) { try { - X = (byte)bytes[i++]; - Y = (byte)bytes[i++]; - Z = (byte)bytes[i++]; + X = Utils.BytesToByte(bytes, ref i); + Y = Utils.BytesToByte(bytes, ref i); + Z = Utils.BytesToByte(bytes, ref i); } catch (Exception) { @@ -71775,9 +71790,9 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { - bytes[i++] = X; - bytes[i++] = Y; - bytes[i++] = Z; + Utils.ByteToBytes( X, bytes, ref i); + Utils.ByteToBytes( Y, bytes, ref i); + Utils.ByteToBytes( Z, bytes, ref i); } } @@ -71963,10 +71978,10 @@ public override byte[] ToBytes() byte[] bytes = new byte[length]; int i = 0; Header.ToBytes(bytes, ref i); - bytes[i++] = (byte)Location.Length; + Utils.ByteToBytes((byte)Location.Length, bytes, ref i); for (int j = 0; j < Location.Length; j++) { Location[j].ToBytes(bytes, ref i); } Index.ToBytes(bytes, ref i); - bytes[i++] = (byte)AgentData.Length; + Utils.ByteToBytes((byte)AgentData.Length, bytes, ref i); for (int j = 0; j < AgentData.Length; j++) { AgentData[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -72054,7 +72069,7 @@ public override void FromBytes(byte[] bytes, ref int i) SimIP = Utils.BytesToUIntSafepos(bytes, i); i += 4; SimPort = (ushort)((bytes[i++] << 8) + bytes[i++]); RegionHandle = Utils.BytesToUInt64Safepos(bytes, i); i += 8; - length = (bytes[i++] + (bytes[i++] << 8)); + length = Utils.BytesToUInt16(bytes, i); i+=2; SeedCapability = new byte[length]; Buffer.BlockCopy(bytes, i, SeedCapability, 0, length); i += length; } @@ -72067,11 +72082,9 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { Utils.UIntToBytesSafepos(SimIP, bytes, i); i += 4; - bytes[i++] = (byte)((SimPort >> 8) % 256); - bytes[i++] = (byte)(SimPort % 256); + Utils.UInt16ToBytesBig(SimPort, bytes, i); i += 2; Utils.UInt64ToBytesSafepos(RegionHandle, bytes, i); i += 8; - bytes[i++] = (byte)(SeedCapability.Length % 256); - bytes[i++] = (byte)((SeedCapability.Length >> 8) % 256); + Utils.UInt16ToBytes((ushort)SeedCapability.Length, bytes, i); i += 2; Buffer.BlockCopy(SeedCapability, 0, bytes, i, SeedCapability.Length); i += SeedCapability.Length; } @@ -72384,30 +72397,30 @@ public override void FromBytes(byte[] bytes, ref int i) EveryoneMask = Utils.BytesToUIntSafepos(bytes, i); i += 4; NextOwnerMask = Utils.BytesToUIntSafepos(bytes, i); i += 4; OwnershipCost = Utils.BytesToIntSafepos(bytes, i); i +=4; - SaleType = (byte)bytes[i++]; + SaleType = Utils.BytesToByte(bytes, ref i); SalePrice = Utils.BytesToIntSafepos(bytes, i); i +=4; - AggregatePerms = (byte)bytes[i++]; - AggregatePermTextures = (byte)bytes[i++]; - AggregatePermTexturesOwner = (byte)bytes[i++]; + AggregatePerms = Utils.BytesToByte(bytes, ref i); + AggregatePermTextures = Utils.BytesToByte(bytes, ref i); + AggregatePermTexturesOwner = Utils.BytesToByte(bytes, ref i); Category = Utils.BytesToUIntSafepos(bytes, i); i += 4; InventorySerial = Utils.BytesToInt16(bytes, i); i+=2; ItemID.FromBytes(bytes, i); i += 16; FolderID.FromBytes(bytes, i); i += 16; FromTaskID.FromBytes(bytes, i); i += 16; LastOwnerID.FromBytes(bytes, i); i += 16; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Name = new byte[length]; Buffer.BlockCopy(bytes, i, Name, 0, length); i += length; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Description = new byte[length]; Buffer.BlockCopy(bytes, i, Description, 0, length); i += length; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); TouchName = new byte[length]; Buffer.BlockCopy(bytes, i, TouchName, 0, length); i += length; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); SitName = new byte[length]; Buffer.BlockCopy(bytes, i, SitName, 0, length); i += length; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); TextureID = new byte[length]; Buffer.BlockCopy(bytes, i, TextureID, 0, length); i += length; } @@ -72430,26 +72443,26 @@ public override void ToBytes(byte[] bytes, ref int i) Utils.UIntToBytesSafepos(EveryoneMask, bytes, i); i += 4; Utils.UIntToBytesSafepos(NextOwnerMask, bytes, i); i += 4; Utils.IntToBytesSafepos(OwnershipCost, bytes, i); i += 4; - bytes[i++] = SaleType; + Utils.ByteToBytes( SaleType, bytes, ref i); Utils.IntToBytesSafepos(SalePrice, bytes, i); i += 4; - bytes[i++] = AggregatePerms; - bytes[i++] = AggregatePermTextures; - bytes[i++] = AggregatePermTexturesOwner; + Utils.ByteToBytes( AggregatePerms, bytes, ref i); + Utils.ByteToBytes( AggregatePermTextures, bytes, ref i); + Utils.ByteToBytes( AggregatePermTexturesOwner, bytes, ref i); Utils.UIntToBytesSafepos(Category, bytes, i); i += 4; Utils.Int16ToBytes(InventorySerial, bytes, i); i += 2; ItemID.ToBytes(bytes, i); i += 16; FolderID.ToBytes(bytes, i); i += 16; FromTaskID.ToBytes(bytes, i); i += 16; LastOwnerID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)Name.Length; + Utils.ByteToBytes((byte)Name.Length, bytes, ref i); Buffer.BlockCopy(Name, 0, bytes, i, Name.Length); i += Name.Length; - bytes[i++] = (byte)Description.Length; + Utils.ByteToBytes((byte)Description.Length, bytes, ref i); Buffer.BlockCopy(Description, 0, bytes, i, Description.Length); i += Description.Length; - bytes[i++] = (byte)TouchName.Length; + Utils.ByteToBytes((byte)TouchName.Length, bytes, ref i); Buffer.BlockCopy(TouchName, 0, bytes, i, TouchName.Length); i += TouchName.Length; - bytes[i++] = (byte)SitName.Length; + Utils.ByteToBytes((byte)SitName.Length, bytes, ref i); Buffer.BlockCopy(SitName, 0, bytes, i, SitName.Length); i += SitName.Length; - bytes[i++] = (byte)TextureID.Length; + Utils.ByteToBytes((byte)TextureID.Length, bytes, ref i); Buffer.BlockCopy(TextureID, 0, bytes, i, TextureID.Length); i += TextureID.Length; } @@ -72530,7 +72543,7 @@ public override byte[] ToBytes() byte[] bytes = new byte[length]; int i = 0; Header.ToBytes(bytes, ref i); - bytes[i++] = (byte)ObjectData.Length; + Utils.ByteToBytes((byte)ObjectData.Length, bytes, ref i); for (int j = 0; j < ObjectData.Length; j++) { ObjectData[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -72648,14 +72661,14 @@ public override void FromBytes(byte[] bytes, ref int i) EveryoneMask = Utils.BytesToUIntSafepos(bytes, i); i += 4; NextOwnerMask = Utils.BytesToUIntSafepos(bytes, i); i += 4; OwnershipCost = Utils.BytesToIntSafepos(bytes, i); i +=4; - SaleType = (byte)bytes[i++]; + SaleType = Utils.BytesToByte(bytes, ref i); SalePrice = Utils.BytesToIntSafepos(bytes, i); i +=4; Category = Utils.BytesToUIntSafepos(bytes, i); i += 4; LastOwnerID.FromBytes(bytes, i); i += 16; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Name = new byte[length]; Buffer.BlockCopy(bytes, i, Name, 0, length); i += length; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Description = new byte[length]; Buffer.BlockCopy(bytes, i, Description, 0, length); i += length; } @@ -72677,13 +72690,13 @@ public override void ToBytes(byte[] bytes, ref int i) Utils.UIntToBytesSafepos(EveryoneMask, bytes, i); i += 4; Utils.UIntToBytesSafepos(NextOwnerMask, bytes, i); i += 4; Utils.IntToBytesSafepos(OwnershipCost, bytes, i); i += 4; - bytes[i++] = SaleType; + Utils.ByteToBytes( SaleType, bytes, ref i); Utils.IntToBytesSafepos(SalePrice, bytes, i); i += 4; Utils.UIntToBytesSafepos(Category, bytes, i); i += 4; LastOwnerID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)Name.Length; + Utils.ByteToBytes((byte)Name.Length, bytes, ref i); Buffer.BlockCopy(Name, 0, bytes, i, Name.Length); i += Name.Length; - bytes[i++] = (byte)Description.Length; + Utils.ByteToBytes((byte)Description.Length, bytes, ref i); Buffer.BlockCopy(Description, 0, bytes, i, Description.Length); i += Description.Length; } @@ -72836,7 +72849,7 @@ public override void FromBytes(byte[] bytes, ref int i) South = Utils.BytesToFloatSafepos(bytes, i); i += 4; East = Utils.BytesToFloatSafepos(bytes, i); i += 4; North = Utils.BytesToFloatSafepos(bytes, i); i += 4; - SnapSelection = (bytes[i++] != 0) ? (bool)true : (bool)false; + SnapSelection = (Utils.BytesToByte(bytes, ref i) != 0); } catch (Exception) { @@ -72851,7 +72864,7 @@ public override void ToBytes(byte[] bytes, ref int i) Utils.FloatToBytesSafepos(South, bytes, i); i += 4; Utils.FloatToBytesSafepos(East, bytes, i); i += 4; Utils.FloatToBytesSafepos(North, bytes, i); i += 4; - bytes[i++] = (byte)((SnapSelection) ? 1 : 0); + Utils.ByteToBytes((byte)((SnapSelection) ? 1 : 0), bytes, ref i); } } @@ -72967,7 +72980,7 @@ public override void FromBytes(byte[] bytes, ref int i) ObjectID.FromBytes(bytes, i); i += 16; OwnerID.FromBytes(bytes, i); i += 16; Gain = Utils.BytesToFloatSafepos(bytes, i); i += 4; - Flags = (byte)bytes[i++]; + Flags = Utils.BytesToByte(bytes, ref i); } catch (Exception) { @@ -72981,7 +72994,7 @@ public override void ToBytes(byte[] bytes, ref int i) ObjectID.ToBytes(bytes, i); i += 16; OwnerID.ToBytes(bytes, i); i += 16; Utils.FloatToBytesSafepos(Gain, bytes, i); i += 4; - bytes[i++] = Flags; + Utils.ByteToBytes( Flags, bytes, ref i); } } @@ -73289,7 +73302,7 @@ public override byte[] ToBytes() byte[] bytes = new byte[length]; int i = 0; Header.ToBytes(bytes, ref i); - bytes[i++] = (byte)DataBlock.Length; + Utils.ByteToBytes((byte)DataBlock.Length, bytes, ref i); for (int j = 0; j < DataBlock.Length; j++) { DataBlock[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -73429,11 +73442,11 @@ public override void FromBytes(byte[] bytes, ref int i) { ID.FromBytes(bytes, i); i += 16; AgentID.FromBytes(bytes, i); i += 16; - Type = (byte)bytes[i++]; + Type = Utils.BytesToByte(bytes, ref i); Duration = Utils.BytesToFloatSafepos(bytes, i); i += 4; Color = new byte[4]; Buffer.BlockCopy(bytes, i, Color, 0, 4); i += 4; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); TypeData = new byte[length]; Buffer.BlockCopy(bytes, i, TypeData, 0, length); i += length; } @@ -73447,10 +73460,10 @@ public override void ToBytes(byte[] bytes, ref int i) { ID.ToBytes(bytes, i); i += 16; AgentID.ToBytes(bytes, i); i += 16; - bytes[i++] = Type; + Utils.ByteToBytes( Type, bytes, ref i); Utils.FloatToBytesSafepos(Duration, bytes, i); i += 4; Buffer.BlockCopy(Color, 0, bytes, i, 4);i += 4; - bytes[i++] = (byte)TypeData.Length; + Utils.ByteToBytes((byte)TypeData.Length, bytes, ref i); Buffer.BlockCopy(TypeData, 0, bytes, i, TypeData.Length); i += TypeData.Length; } @@ -73538,7 +73551,7 @@ public override byte[] ToBytes() int i = 0; Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); - bytes[i++] = (byte)Effect.Length; + Utils.ByteToBytes((byte)Effect.Length, bytes, ref i); for (int j = 0; j < Effect.Length; j++) { Effect[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -73630,7 +73643,7 @@ public override void FromBytes(byte[] bytes, ref int i) { try { - PingID = (byte)bytes[i++]; + PingID = Utils.BytesToByte(bytes, ref i); OldestUnacked = Utils.BytesToUIntSafepos(bytes, i); i += 4; } catch (Exception) @@ -73641,7 +73654,7 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { - bytes[i++] = PingID; + Utils.ByteToBytes( PingID, bytes, ref i); Utils.UIntToBytesSafepos(OldestUnacked, bytes, i); i += 4; } @@ -73742,7 +73755,7 @@ public override void FromBytes(byte[] bytes, ref int i) { try { - PingID = (byte)bytes[i++]; + PingID = Utils.BytesToByte(bytes, ref i); } catch (Exception) { @@ -73752,7 +73765,7 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { - bytes[i++] = PingID; + Utils.ByteToBytes( PingID, bytes, ref i); } } @@ -73867,14 +73880,14 @@ public override void FromBytes(byte[] bytes, ref int i) SessionID.FromBytes(bytes, i); i += 16; BodyRotation.FromBytes(bytes, i, true); i += 12; HeadRotation.FromBytes(bytes, i, true); i += 12; - State = (byte)bytes[i++]; + State = Utils.BytesToByte(bytes, ref i); CameraCenter.FromBytes(bytes, i); i += 12; CameraAtAxis.FromBytes(bytes, i); i += 12; CameraLeftAxis.FromBytes(bytes, i); i += 12; CameraUpAxis.FromBytes(bytes, i); i += 12; Far = Utils.BytesToFloatSafepos(bytes, i); i += 4; ControlFlags = Utils.BytesToUIntSafepos(bytes, i); i += 4; - Flags = (byte)bytes[i++]; + Flags = Utils.BytesToByte(bytes, ref i); } catch (Exception) { @@ -73888,14 +73901,14 @@ public override void ToBytes(byte[] bytes, ref int i) SessionID.ToBytes(bytes, i); i += 16; BodyRotation.ToBytes(bytes, i); i += 12; HeadRotation.ToBytes(bytes, i); i += 12; - bytes[i++] = State; + Utils.ByteToBytes( State, bytes, ref i); CameraCenter.ToBytes(bytes, i); i += 12; CameraAtAxis.ToBytes(bytes, i); i += 12; CameraLeftAxis.ToBytes(bytes, i); i += 12; CameraUpAxis.ToBytes(bytes, i); i += 12; Utils.FloatToBytesSafepos(Far, bytes, i); i += 4; Utils.UIntToBytesSafepos(ControlFlags, bytes, i); i += 4; - bytes[i++] = Flags; + Utils.ByteToBytes( Flags, bytes, ref i); } } @@ -74039,7 +74052,7 @@ public override void FromBytes(byte[] bytes, ref int i) try { AnimID.FromBytes(bytes, i); i += 16; - StartAnim = (bytes[i++] != 0) ? (bool)true : (bool)false; + StartAnim = (Utils.BytesToByte(bytes, ref i) != 0); } catch (Exception) { @@ -74050,7 +74063,7 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { AnimID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)((StartAnim) ? 1 : 0); + Utils.ByteToBytes((byte)((StartAnim) ? 1 : 0), bytes, ref i); } } @@ -74081,7 +74094,7 @@ public override void FromBytes(byte[] bytes, ref int i) int length; try { - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); TypeData = new byte[length]; Buffer.BlockCopy(bytes, i, TypeData, 0, length); i += length; } @@ -74093,7 +74106,7 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { - bytes[i++] = (byte)TypeData.Length; + Utils.ByteToBytes((byte)TypeData.Length, bytes, ref i); Buffer.BlockCopy(TypeData, 0, bytes, i, TypeData.Length); i += TypeData.Length; } @@ -74202,9 +74215,9 @@ public override byte[] ToBytes() int i = 0; Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); - bytes[i++] = (byte)AnimationList.Length; + Utils.ByteToBytes((byte)AnimationList.Length, bytes, ref i); for (int j = 0; j < AnimationList.Length; j++) { AnimationList[j].ToBytes(bytes, ref i); } - bytes[i++] = (byte)PhysicalAvatarEventList.Length; + Utils.ByteToBytes((byte)PhysicalAvatarEventList.Length, bytes, ref i); for (int j = 0; j < PhysicalAvatarEventList.Length; j++) { PhysicalAvatarEventList[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -74634,10 +74647,10 @@ public override void FromBytes(byte[] bytes, ref int i) try { Image.FromBytes(bytes, i); i += 16; - DiscardLevel = (sbyte)bytes[i++]; + DiscardLevel = (sbyte)Utils.BytesToByte(bytes, ref i); DownloadPriority = Utils.BytesToFloatSafepos(bytes, i); i += 4; Packet = Utils.BytesToUIntSafepos(bytes, i); i += 4; - Type = (byte)bytes[i++]; + Type = Utils.BytesToByte(bytes, ref i); } catch (Exception) { @@ -74648,10 +74661,10 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { Image.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)DiscardLevel; + Utils.ByteToBytes( (byte)DiscardLevel, bytes, ref i); Utils.FloatToBytesSafepos(DownloadPriority, bytes, i); i += 4; Utils.UIntToBytesSafepos(Packet, bytes, i); i += 4; - bytes[i++] = Type; + Utils.ByteToBytes( Type, bytes, ref i); } } @@ -74737,7 +74750,7 @@ public override byte[] ToBytes() int i = 0; Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); - bytes[i++] = (byte)RequestImage.Length; + Utils.ByteToBytes((byte)RequestImage.Length, bytes, ref i); for (int j = 0; j < RequestImage.Length; j++) { RequestImage[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -74832,7 +74845,7 @@ public override void FromBytes(byte[] bytes, ref int i) try { ID.FromBytes(bytes, i); i += 16; - Codec = (byte)bytes[i++]; + Codec = Utils.BytesToByte(bytes, ref i); Size = Utils.BytesToUIntSafepos(bytes, i); i += 4; Packets = Utils.BytesToUInt16(bytes, i); i+=2; } @@ -74845,7 +74858,7 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { ID.ToBytes(bytes, i); i += 16; - bytes[i++] = Codec; + Utils.ByteToBytes( Codec, bytes, ref i); Utils.UIntToBytesSafepos(Size, bytes, i); i += 4; Utils.UInt16ToBytes(Packets, bytes, i); i += 2; } @@ -74878,7 +74891,7 @@ public override void FromBytes(byte[] bytes, ref int i) int length; try { - length = (bytes[i++] + (bytes[i++] << 8)); + length = Utils.BytesToUInt16(bytes, i); i+=2; Data = new byte[length]; Buffer.BlockCopy(bytes, i, Data, 0, length); i += length; } @@ -74890,8 +74903,7 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { - bytes[i++] = (byte)(Data.Length % 256); - bytes[i++] = (byte)((Data.Length >> 8) % 256); + Utils.UInt16ToBytes((ushort)Data.Length, bytes, i); i += 2; Buffer.BlockCopy(Data, 0, bytes, i, Data.Length); i += Data.Length; } @@ -75043,7 +75055,7 @@ public override void FromBytes(byte[] bytes, ref int i) int length; try { - length = (bytes[i++] + (bytes[i++] << 8)); + length = Utils.BytesToUInt16(bytes, i); i+=2; Data = new byte[length]; Buffer.BlockCopy(bytes, i, Data, 0, length); i += length; } @@ -75055,8 +75067,7 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { - bytes[i++] = (byte)(Data.Length % 256); - bytes[i++] = (byte)((Data.Length >> 8) % 256); + Utils.UInt16ToBytes((ushort)Data.Length, bytes, i); i += 2; Buffer.BlockCopy(Data, 0, bytes, i, Data.Length); i += Data.Length; } @@ -75164,7 +75175,7 @@ public override void FromBytes(byte[] bytes, ref int i) { try { - Type = (byte)bytes[i++]; + Type = Utils.BytesToByte(bytes, ref i); } catch (Exception) { @@ -75174,7 +75185,7 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { - bytes[i++] = Type; + Utils.ByteToBytes( Type, bytes, ref i); } } @@ -75205,7 +75216,7 @@ public override void FromBytes(byte[] bytes, ref int i) int length; try { - length = (bytes[i++] + (bytes[i++] << 8)); + length = Utils.BytesToUInt16(bytes, i); i+=2; Data = new byte[length]; Buffer.BlockCopy(bytes, i, Data, 0, length); i += length; } @@ -75217,8 +75228,7 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { - bytes[i++] = (byte)(Data.Length % 256); - bytes[i++] = (byte)((Data.Length >> 8) % 256); + Utils.UInt16ToBytes((ushort)Data.Length, bytes, i); i += 2; Buffer.BlockCopy(Data, 0, bytes, i, Data.Length); i += Data.Length; } @@ -75424,68 +75434,68 @@ public override void FromBytes(byte[] bytes, ref int i) try { ID = Utils.BytesToUIntSafepos(bytes, i); i += 4; - State = (byte)bytes[i++]; + State = Utils.BytesToByte(bytes, ref i); FullID.FromBytes(bytes, i); i += 16; CRC = Utils.BytesToUIntSafepos(bytes, i); i += 4; - PCode = (byte)bytes[i++]; - Material = (byte)bytes[i++]; - ClickAction = (byte)bytes[i++]; + PCode = Utils.BytesToByte(bytes, ref i); + Material = Utils.BytesToByte(bytes, ref i); + ClickAction = Utils.BytesToByte(bytes, ref i); Scale.FromBytes(bytes, i); i += 12; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); ObjectData = new byte[length]; Buffer.BlockCopy(bytes, i, ObjectData, 0, length); i += length; ParentID = Utils.BytesToUIntSafepos(bytes, i); i += 4; UpdateFlags = Utils.BytesToUIntSafepos(bytes, i); i += 4; - PathCurve = (byte)bytes[i++]; - ProfileCurve = (byte)bytes[i++]; + PathCurve = Utils.BytesToByte(bytes, ref i); + ProfileCurve = Utils.BytesToByte(bytes, ref i); PathBegin = Utils.BytesToUInt16(bytes, i); i+=2; PathEnd = Utils.BytesToUInt16(bytes, i); i+=2; - PathScaleX = (byte)bytes[i++]; - PathScaleY = (byte)bytes[i++]; - PathShearX = (byte)bytes[i++]; - PathShearY = (byte)bytes[i++]; - PathTwist = (sbyte)bytes[i++]; - PathTwistBegin = (sbyte)bytes[i++]; - PathRadiusOffset = (sbyte)bytes[i++]; - PathTaperX = (sbyte)bytes[i++]; - PathTaperY = (sbyte)bytes[i++]; - PathRevolutions = (byte)bytes[i++]; - PathSkew = (sbyte)bytes[i++]; + PathScaleX = Utils.BytesToByte(bytes, ref i); + PathScaleY = Utils.BytesToByte(bytes, ref i); + PathShearX = Utils.BytesToByte(bytes, ref i); + PathShearY = Utils.BytesToByte(bytes, ref i); + PathTwist = (sbyte)Utils.BytesToByte(bytes, ref i); + PathTwistBegin = (sbyte)Utils.BytesToByte(bytes, ref i); + PathRadiusOffset = (sbyte)Utils.BytesToByte(bytes, ref i); + PathTaperX = (sbyte)Utils.BytesToByte(bytes, ref i); + PathTaperY = (sbyte)Utils.BytesToByte(bytes, ref i); + PathRevolutions = Utils.BytesToByte(bytes, ref i); + PathSkew = (sbyte)Utils.BytesToByte(bytes, ref i); ProfileBegin = Utils.BytesToUInt16(bytes, i); i+=2; ProfileEnd = Utils.BytesToUInt16(bytes, i); i+=2; ProfileHollow = Utils.BytesToUInt16(bytes, i); i+=2; - length = (bytes[i++] + (bytes[i++] << 8)); + length = Utils.BytesToUInt16(bytes, i); i+=2; TextureEntry = new byte[length]; Buffer.BlockCopy(bytes, i, TextureEntry, 0, length); i += length; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); TextureAnim = new byte[length]; Buffer.BlockCopy(bytes, i, TextureAnim, 0, length); i += length; - length = (bytes[i++] + (bytes[i++] << 8)); + length = Utils.BytesToUInt16(bytes, i); i+=2; NameValue = new byte[length]; Buffer.BlockCopy(bytes, i, NameValue, 0, length); i += length; - length = (bytes[i++] + (bytes[i++] << 8)); + length = Utils.BytesToUInt16(bytes, i); i+=2; Data = new byte[length]; Buffer.BlockCopy(bytes, i, Data, 0, length); i += length; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Text = new byte[length]; Buffer.BlockCopy(bytes, i, Text, 0, length); i += length; TextColor = new byte[4]; Buffer.BlockCopy(bytes, i, TextColor, 0, 4); i += 4; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); MediaURL = new byte[length]; Buffer.BlockCopy(bytes, i, MediaURL, 0, length); i += length; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); PSBlock = new byte[length]; Buffer.BlockCopy(bytes, i, PSBlock, 0, length); i += length; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); ExtraParams = new byte[length]; Buffer.BlockCopy(bytes, i, ExtraParams, 0, length); i += length; Sound.FromBytes(bytes, i); i += 16; OwnerID.FromBytes(bytes, i); i += 16; Gain = Utils.BytesToFloatSafepos(bytes, i); i += 4; - Flags = (byte)bytes[i++]; + Flags = Utils.BytesToByte(bytes, ref i); Radius = Utils.BytesToFloatSafepos(bytes, i); i += 4; - JointType = (byte)bytes[i++]; + JointType = Utils.BytesToByte(bytes, ref i); JointPivot.FromBytes(bytes, i); i += 12; JointAxisOrAnchor.FromBytes(bytes, i); i += 12; } @@ -75498,61 +75508,58 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { Utils.UIntToBytesSafepos(ID, bytes, i); i += 4; - bytes[i++] = State; + Utils.ByteToBytes( State, bytes, ref i); FullID.ToBytes(bytes, i); i += 16; Utils.UIntToBytesSafepos(CRC, bytes, i); i += 4; - bytes[i++] = PCode; - bytes[i++] = Material; - bytes[i++] = ClickAction; + Utils.ByteToBytes( PCode, bytes, ref i); + Utils.ByteToBytes( Material, bytes, ref i); + Utils.ByteToBytes( ClickAction, bytes, ref i); Scale.ToBytes(bytes, i); i += 12; - bytes[i++] = (byte)ObjectData.Length; + Utils.ByteToBytes((byte)ObjectData.Length, bytes, ref i); Buffer.BlockCopy(ObjectData, 0, bytes, i, ObjectData.Length); i += ObjectData.Length; Utils.UIntToBytesSafepos(ParentID, bytes, i); i += 4; Utils.UIntToBytesSafepos(UpdateFlags, bytes, i); i += 4; - bytes[i++] = PathCurve; - bytes[i++] = ProfileCurve; + Utils.ByteToBytes( PathCurve, bytes, ref i); + Utils.ByteToBytes( ProfileCurve, bytes, ref i); Utils.UInt16ToBytes(PathBegin, bytes, i); i += 2; Utils.UInt16ToBytes(PathEnd, bytes, i); i += 2; - bytes[i++] = PathScaleX; - bytes[i++] = PathScaleY; - bytes[i++] = PathShearX; - bytes[i++] = PathShearY; - bytes[i++] = (byte)PathTwist; - bytes[i++] = (byte)PathTwistBegin; - bytes[i++] = (byte)PathRadiusOffset; - bytes[i++] = (byte)PathTaperX; - bytes[i++] = (byte)PathTaperY; - bytes[i++] = PathRevolutions; - bytes[i++] = (byte)PathSkew; + Utils.ByteToBytes( PathScaleX, bytes, ref i); + Utils.ByteToBytes( PathScaleY, bytes, ref i); + Utils.ByteToBytes( PathShearX, bytes, ref i); + Utils.ByteToBytes( PathShearY, bytes, ref i); + Utils.ByteToBytes( (byte)PathTwist, bytes, ref i); + Utils.ByteToBytes( (byte)PathTwistBegin, bytes, ref i); + Utils.ByteToBytes( (byte)PathRadiusOffset, bytes, ref i); + Utils.ByteToBytes( (byte)PathTaperX, bytes, ref i); + Utils.ByteToBytes( (byte)PathTaperY, bytes, ref i); + Utils.ByteToBytes( PathRevolutions, bytes, ref i); + Utils.ByteToBytes( (byte)PathSkew, bytes, ref i); Utils.UInt16ToBytes(ProfileBegin, bytes, i); i += 2; Utils.UInt16ToBytes(ProfileEnd, bytes, i); i += 2; Utils.UInt16ToBytes(ProfileHollow, bytes, i); i += 2; - bytes[i++] = (byte)(TextureEntry.Length % 256); - bytes[i++] = (byte)((TextureEntry.Length >> 8) % 256); + Utils.UInt16ToBytes((ushort)TextureEntry.Length, bytes, i); i += 2; Buffer.BlockCopy(TextureEntry, 0, bytes, i, TextureEntry.Length); i += TextureEntry.Length; - bytes[i++] = (byte)TextureAnim.Length; + Utils.ByteToBytes((byte)TextureAnim.Length, bytes, ref i); Buffer.BlockCopy(TextureAnim, 0, bytes, i, TextureAnim.Length); i += TextureAnim.Length; - bytes[i++] = (byte)(NameValue.Length % 256); - bytes[i++] = (byte)((NameValue.Length >> 8) % 256); + Utils.UInt16ToBytes((ushort)NameValue.Length, bytes, i); i += 2; Buffer.BlockCopy(NameValue, 0, bytes, i, NameValue.Length); i += NameValue.Length; - bytes[i++] = (byte)(Data.Length % 256); - bytes[i++] = (byte)((Data.Length >> 8) % 256); + Utils.UInt16ToBytes((ushort)Data.Length, bytes, i); i += 2; Buffer.BlockCopy(Data, 0, bytes, i, Data.Length); i += Data.Length; - bytes[i++] = (byte)Text.Length; + Utils.ByteToBytes((byte)Text.Length, bytes, ref i); Buffer.BlockCopy(Text, 0, bytes, i, Text.Length); i += Text.Length; Buffer.BlockCopy(TextColor, 0, bytes, i, 4);i += 4; - bytes[i++] = (byte)MediaURL.Length; + Utils.ByteToBytes((byte)MediaURL.Length, bytes, ref i); Buffer.BlockCopy(MediaURL, 0, bytes, i, MediaURL.Length); i += MediaURL.Length; - bytes[i++] = (byte)PSBlock.Length; + Utils.ByteToBytes((byte)PSBlock.Length, bytes, ref i); Buffer.BlockCopy(PSBlock, 0, bytes, i, PSBlock.Length); i += PSBlock.Length; - bytes[i++] = (byte)ExtraParams.Length; + Utils.ByteToBytes((byte)ExtraParams.Length, bytes, ref i); Buffer.BlockCopy(ExtraParams, 0, bytes, i, ExtraParams.Length); i += ExtraParams.Length; Sound.ToBytes(bytes, i); i += 16; OwnerID.ToBytes(bytes, i); i += 16; Utils.FloatToBytesSafepos(Gain, bytes, i); i += 4; - bytes[i++] = Flags; + Utils.ByteToBytes( Flags, bytes, ref i); Utils.FloatToBytesSafepos(Radius, bytes, i); i += 4; - bytes[i++] = JointType; + Utils.ByteToBytes( JointType, bytes, ref i); JointPivot.ToBytes(bytes, i); i += 12; JointAxisOrAnchor.ToBytes(bytes, i); i += 12; } @@ -75641,7 +75648,7 @@ public override byte[] ToBytes() int i = 0; Header.ToBytes(bytes, ref i); RegionData.ToBytes(bytes, ref i); - bytes[i++] = (byte)ObjectData.Length; + Utils.ByteToBytes((byte)ObjectData.Length, bytes, ref i); for (int j = 0; j < ObjectData.Length; j++) { ObjectData[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -75778,7 +75785,7 @@ public override void FromBytes(byte[] bytes, ref int i) try { UpdateFlags = Utils.BytesToUIntSafepos(bytes, i); i += 4; - length = (bytes[i++] + (bytes[i++] << 8)); + length = Utils.BytesToUInt16(bytes, i); i+=2; Data = new byte[length]; Buffer.BlockCopy(bytes, i, Data, 0, length); i += length; } @@ -75791,8 +75798,7 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { Utils.UIntToBytesSafepos(UpdateFlags, bytes, i); i += 4; - bytes[i++] = (byte)(Data.Length % 256); - bytes[i++] = (byte)((Data.Length >> 8) % 256); + Utils.UInt16ToBytes((ushort)Data.Length, bytes, i); i += 2; Buffer.BlockCopy(Data, 0, bytes, i, Data.Length); i += Data.Length; } @@ -75879,7 +75885,7 @@ public override byte[] ToBytes() int i = 0; Header.ToBytes(bytes, ref i); RegionData.ToBytes(bytes, ref i); - bytes[i++] = (byte)ObjectData.Length; + Utils.ByteToBytes((byte)ObjectData.Length, bytes, ref i); for (int j = 0; j < ObjectData.Length; j++) { ObjectData[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -76113,7 +76119,7 @@ public override byte[] ToBytes() int i = 0; Header.ToBytes(bytes, ref i); RegionData.ToBytes(bytes, ref i); - bytes[i++] = (byte)ObjectData.Length; + Utils.ByteToBytes((byte)ObjectData.Length, bytes, ref i); for (int j = 0; j < ObjectData.Length; j++) { ObjectData[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -76250,10 +76256,10 @@ public override void FromBytes(byte[] bytes, ref int i) int length; try { - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Data = new byte[length]; Buffer.BlockCopy(bytes, i, Data, 0, length); i += length; - length = (bytes[i++] + (bytes[i++] << 8)); + length = Utils.BytesToUInt16(bytes, i); i+=2; TextureEntry = new byte[length]; Buffer.BlockCopy(bytes, i, TextureEntry, 0, length); i += length; } @@ -76265,10 +76271,9 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { - bytes[i++] = (byte)Data.Length; + Utils.ByteToBytes((byte)Data.Length, bytes, ref i); Buffer.BlockCopy(Data, 0, bytes, i, Data.Length); i += Data.Length; - bytes[i++] = (byte)(TextureEntry.Length % 256); - bytes[i++] = (byte)((TextureEntry.Length >> 8) % 256); + Utils.UInt16ToBytes((ushort)TextureEntry.Length, bytes, i); i += 2; Buffer.BlockCopy(TextureEntry, 0, bytes, i, TextureEntry.Length); i += TextureEntry.Length; } @@ -76355,7 +76360,7 @@ public override byte[] ToBytes() int i = 0; Header.ToBytes(bytes, ref i); RegionData.ToBytes(bytes, ref i); - bytes[i++] = (byte)ObjectData.Length; + Utils.ByteToBytes((byte)ObjectData.Length, bytes, ref i); for (int j = 0; j < ObjectData.Length; j++) { ObjectData[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -76535,7 +76540,7 @@ public override byte[] ToBytes() byte[] bytes = new byte[length]; int i = 0; Header.ToBytes(bytes, ref i); - bytes[i++] = (byte)ObjectData.Length; + Utils.ByteToBytes((byte)ObjectData.Length, bytes, ref i); for (int j = 0; j < ObjectData.Length; j++) { ObjectData[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -76635,7 +76640,7 @@ public override void FromBytes(byte[] bytes, ref int i) ChannelType = Utils.BytesToIntSafepos(bytes, i); i +=4; Packet = Utils.BytesToIntSafepos(bytes, i); i +=4; Status = Utils.BytesToIntSafepos(bytes, i); i +=4; - length = (bytes[i++] + (bytes[i++] << 8)); + length = Utils.BytesToUInt16(bytes, i); i+=2; Data = new byte[length]; Buffer.BlockCopy(bytes, i, Data, 0, length); i += length; } @@ -76651,8 +76656,7 @@ public override void ToBytes(byte[] bytes, ref int i) Utils.IntToBytesSafepos(ChannelType, bytes, i); i += 4; Utils.IntToBytesSafepos(Packet, bytes, i); i += 4; Utils.IntToBytesSafepos(Status, bytes, i); i += 4; - bytes[i++] = (byte)(Data.Length % 256); - bytes[i++] = (byte)((Data.Length >> 8) % 256); + Utils.UInt16ToBytes((ushort)Data.Length, bytes, i); i += 2; Buffer.BlockCopy(Data, 0, bytes, i, Data.Length); i += Data.Length; } @@ -76797,7 +76801,7 @@ public override void FromBytes(byte[] bytes, ref int i) int length; try { - length = (bytes[i++] + (bytes[i++] << 8)); + length = Utils.BytesToUInt16(bytes, i); i+=2; Data = new byte[length]; Buffer.BlockCopy(bytes, i, Data, 0, length); i += length; } @@ -76809,8 +76813,7 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { - bytes[i++] = (byte)(Data.Length % 256); - bytes[i++] = (byte)((Data.Length >> 8) % 256); + Utils.UInt16ToBytes((ushort)Data.Length, bytes, i); i += 2; Buffer.BlockCopy(Data, 0, bytes, i, Data.Length); i += Data.Length; } @@ -77151,7 +77154,7 @@ public override void FromBytes(byte[] bytes, ref int i) int length; try { - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); TypeData = new byte[length]; Buffer.BlockCopy(bytes, i, TypeData, 0, length); i += length; } @@ -77163,7 +77166,7 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { - bytes[i++] = (byte)TypeData.Length; + Utils.ByteToBytes((byte)TypeData.Length, bytes, ref i); Buffer.BlockCopy(TypeData, 0, bytes, i, TypeData.Length); i += TypeData.Length; } @@ -77294,11 +77297,11 @@ public override byte[] ToBytes() int i = 0; Header.ToBytes(bytes, ref i); Sender.ToBytes(bytes, ref i); - bytes[i++] = (byte)AnimationList.Length; + Utils.ByteToBytes((byte)AnimationList.Length, bytes, ref i); for (int j = 0; j < AnimationList.Length; j++) { AnimationList[j].ToBytes(bytes, ref i); } - bytes[i++] = (byte)AnimationSourceList.Length; + Utils.ByteToBytes((byte)AnimationSourceList.Length, bytes, ref i); for (int j = 0; j < AnimationSourceList.Length; j++) { AnimationSourceList[j].ToBytes(bytes, ref i); } - bytes[i++] = (byte)PhysicalAvatarEventList.Length; + Utils.ByteToBytes((byte)PhysicalAvatarEventList.Length, bytes, ref i); for (int j = 0; j < PhysicalAvatarEventList.Length; j++) { PhysicalAvatarEventList[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -77468,12 +77471,12 @@ public override void FromBytes(byte[] bytes, ref int i) { try { - AutoPilot = (bytes[i++] != 0) ? (bool)true : (bool)false; + AutoPilot = (Utils.BytesToByte(bytes, ref i) != 0); SitPosition.FromBytes(bytes, i); i += 12; SitRotation.FromBytes(bytes, i, true); i += 12; CameraEyeOffset.FromBytes(bytes, i); i += 12; CameraAtOffset.FromBytes(bytes, i); i += 12; - ForceMouselook = (bytes[i++] != 0) ? (bool)true : (bool)false; + ForceMouselook = (Utils.BytesToByte(bytes, ref i) != 0); } catch (Exception) { @@ -77483,12 +77486,12 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { - bytes[i++] = (byte)((AutoPilot) ? 1 : 0); + Utils.ByteToBytes((byte)((AutoPilot) ? 1 : 0), bytes, ref i); SitPosition.ToBytes(bytes, i); i += 12; SitRotation.ToBytes(bytes, i); i += 12; CameraEyeOffset.ToBytes(bytes, i); i += 12; CameraAtOffset.ToBytes(bytes, i); i += 12; - bytes[i++] = (byte)((ForceMouselook) ? 1 : 0); + Utils.ByteToBytes((byte)((ForceMouselook) ? 1 : 0), bytes, ref i); } } @@ -77764,24 +77767,24 @@ public override void FromBytes(byte[] bytes, ref int i) { RequestResult = Utils.BytesToIntSafepos(bytes, i); i +=4; SequenceID = Utils.BytesToIntSafepos(bytes, i); i +=4; - SnapSelection = (bytes[i++] != 0) ? (bool)true : (bool)false; + SnapSelection = (Utils.BytesToByte(bytes, ref i) != 0); SelfCount = Utils.BytesToIntSafepos(bytes, i); i +=4; OtherCount = Utils.BytesToIntSafepos(bytes, i); i +=4; PublicCount = Utils.BytesToIntSafepos(bytes, i); i +=4; LocalID = Utils.BytesToIntSafepos(bytes, i); i +=4; OwnerID.FromBytes(bytes, i); i += 16; - IsGroupOwned = (bytes[i++] != 0) ? (bool)true : (bool)false; + IsGroupOwned = (Utils.BytesToByte(bytes, ref i) != 0); AuctionID = Utils.BytesToUIntSafepos(bytes, i); i += 4; ClaimDate = Utils.BytesToIntSafepos(bytes, i); i +=4; ClaimPrice = Utils.BytesToIntSafepos(bytes, i); i +=4; RentPrice = Utils.BytesToIntSafepos(bytes, i); i +=4; AABBMin.FromBytes(bytes, i); i += 12; AABBMax.FromBytes(bytes, i); i += 12; - length = (bytes[i++] + (bytes[i++] << 8)); + length = Utils.BytesToUInt16(bytes, i); i+=2; Bitmap = new byte[length]; Buffer.BlockCopy(bytes, i, Bitmap, 0, length); i += length; Area = Utils.BytesToIntSafepos(bytes, i); i +=4; - Status = (byte)bytes[i++]; + Status = Utils.BytesToByte(bytes, ref i); SimWideMaxPrims = Utils.BytesToIntSafepos(bytes, i); i +=4; SimWideTotalPrims = Utils.BytesToIntSafepos(bytes, i); i +=4; MaxPrims = Utils.BytesToIntSafepos(bytes, i); i +=4; @@ -77794,33 +77797,33 @@ public override void FromBytes(byte[] bytes, ref int i) OtherCleanTime = Utils.BytesToIntSafepos(bytes, i); i +=4; ParcelFlags = Utils.BytesToUIntSafepos(bytes, i); i += 4; SalePrice = Utils.BytesToIntSafepos(bytes, i); i +=4; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Name = new byte[length]; Buffer.BlockCopy(bytes, i, Name, 0, length); i += length; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Desc = new byte[length]; Buffer.BlockCopy(bytes, i, Desc, 0, length); i += length; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); MusicURL = new byte[length]; Buffer.BlockCopy(bytes, i, MusicURL, 0, length); i += length; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); MediaURL = new byte[length]; Buffer.BlockCopy(bytes, i, MediaURL, 0, length); i += length; MediaID.FromBytes(bytes, i); i += 16; - MediaAutoScale = (byte)bytes[i++]; + MediaAutoScale = Utils.BytesToByte(bytes, ref i); GroupID.FromBytes(bytes, i); i += 16; PassPrice = Utils.BytesToIntSafepos(bytes, i); i +=4; PassHours = Utils.BytesToFloatSafepos(bytes, i); i += 4; - Category = (byte)bytes[i++]; + Category = Utils.BytesToByte(bytes, ref i); AuthBuyerID.FromBytes(bytes, i); i += 16; SnapshotID.FromBytes(bytes, i); i += 16; UserLocation.FromBytes(bytes, i); i += 12; UserLookAt.FromBytes(bytes, i); i += 12; - LandingType = (byte)bytes[i++]; - RegionPushOverride = (bytes[i++] != 0) ? (bool)true : (bool)false; - RegionDenyAnonymous = (bytes[i++] != 0) ? (bool)true : (bool)false; - RegionDenyIdentified = (bytes[i++] != 0) ? (bool)true : (bool)false; - RegionDenyTransacted = (bytes[i++] != 0) ? (bool)true : (bool)false; + LandingType = Utils.BytesToByte(bytes, ref i); + RegionPushOverride = (Utils.BytesToByte(bytes, ref i) != 0); + RegionDenyAnonymous = (Utils.BytesToByte(bytes, ref i) != 0); + RegionDenyIdentified = (Utils.BytesToByte(bytes, ref i) != 0); + RegionDenyTransacted = (Utils.BytesToByte(bytes, ref i) != 0); } catch (Exception) { @@ -77832,24 +77835,23 @@ public override void ToBytes(byte[] bytes, ref int i) { Utils.IntToBytesSafepos(RequestResult, bytes, i); i += 4; Utils.IntToBytesSafepos(SequenceID, bytes, i); i += 4; - bytes[i++] = (byte)((SnapSelection) ? 1 : 0); + Utils.ByteToBytes((byte)((SnapSelection) ? 1 : 0), bytes, ref i); Utils.IntToBytesSafepos(SelfCount, bytes, i); i += 4; Utils.IntToBytesSafepos(OtherCount, bytes, i); i += 4; Utils.IntToBytesSafepos(PublicCount, bytes, i); i += 4; Utils.IntToBytesSafepos(LocalID, bytes, i); i += 4; OwnerID.ToBytes(bytes, i); i += 16; - bytes[i++] = (byte)((IsGroupOwned) ? 1 : 0); + Utils.ByteToBytes((byte)((IsGroupOwned) ? 1 : 0), bytes, ref i); Utils.UIntToBytesSafepos(AuctionID, bytes, i); i += 4; Utils.IntToBytesSafepos(ClaimDate, bytes, i); i += 4; Utils.IntToBytesSafepos(ClaimPrice, bytes, i); i += 4; Utils.IntToBytesSafepos(RentPrice, bytes, i); i += 4; AABBMin.ToBytes(bytes, i); i += 12; AABBMax.ToBytes(bytes, i); i += 12; - bytes[i++] = (byte)(Bitmap.Length % 256); - bytes[i++] = (byte)((Bitmap.Length >> 8) % 256); + Utils.UInt16ToBytes((ushort)Bitmap.Length, bytes, i); i += 2; Buffer.BlockCopy(Bitmap, 0, bytes, i, Bitmap.Length); i += Bitmap.Length; Utils.IntToBytesSafepos(Area, bytes, i); i += 4; - bytes[i++] = Status; + Utils.ByteToBytes( Status, bytes, ref i); Utils.IntToBytesSafepos(SimWideMaxPrims, bytes, i); i += 4; Utils.IntToBytesSafepos(SimWideTotalPrims, bytes, i); i += 4; Utils.IntToBytesSafepos(MaxPrims, bytes, i); i += 4; @@ -77862,29 +77864,29 @@ public override void ToBytes(byte[] bytes, ref int i) Utils.IntToBytesSafepos(OtherCleanTime, bytes, i); i += 4; Utils.UIntToBytesSafepos(ParcelFlags, bytes, i); i += 4; Utils.IntToBytesSafepos(SalePrice, bytes, i); i += 4; - bytes[i++] = (byte)Name.Length; + Utils.ByteToBytes((byte)Name.Length, bytes, ref i); Buffer.BlockCopy(Name, 0, bytes, i, Name.Length); i += Name.Length; - bytes[i++] = (byte)Desc.Length; + Utils.ByteToBytes((byte)Desc.Length, bytes, ref i); Buffer.BlockCopy(Desc, 0, bytes, i, Desc.Length); i += Desc.Length; - bytes[i++] = (byte)MusicURL.Length; + Utils.ByteToBytes((byte)MusicURL.Length, bytes, ref i); Buffer.BlockCopy(MusicURL, 0, bytes, i, MusicURL.Length); i += MusicURL.Length; - bytes[i++] = (byte)MediaURL.Length; + Utils.ByteToBytes((byte)MediaURL.Length, bytes, ref i); Buffer.BlockCopy(MediaURL, 0, bytes, i, MediaURL.Length); i += MediaURL.Length; MediaID.ToBytes(bytes, i); i += 16; - bytes[i++] = MediaAutoScale; + Utils.ByteToBytes( MediaAutoScale, bytes, ref i); GroupID.ToBytes(bytes, i); i += 16; Utils.IntToBytesSafepos(PassPrice, bytes, i); i += 4; Utils.FloatToBytesSafepos(PassHours, bytes, i); i += 4; - bytes[i++] = Category; + Utils.ByteToBytes( Category, bytes, ref i); AuthBuyerID.ToBytes(bytes, i); i += 16; SnapshotID.ToBytes(bytes, i); i += 16; UserLocation.ToBytes(bytes, i); i += 12; UserLookAt.ToBytes(bytes, i); i += 12; - bytes[i++] = LandingType; - bytes[i++] = (byte)((RegionPushOverride) ? 1 : 0); - bytes[i++] = (byte)((RegionDenyAnonymous) ? 1 : 0); - bytes[i++] = (byte)((RegionDenyIdentified) ? 1 : 0); - bytes[i++] = (byte)((RegionDenyTransacted) ? 1 : 0); + Utils.ByteToBytes( LandingType, bytes, ref i); + Utils.ByteToBytes((byte)((RegionPushOverride) ? 1 : 0), bytes, ref i); + Utils.ByteToBytes((byte)((RegionDenyAnonymous) ? 1 : 0), bytes, ref i); + Utils.ByteToBytes((byte)((RegionDenyIdentified) ? 1 : 0), bytes, ref i); + Utils.ByteToBytes((byte)((RegionDenyTransacted) ? 1 : 0), bytes, ref i); } } @@ -77912,7 +77914,7 @@ public override void FromBytes(byte[] bytes, ref int i) { try { - RegionDenyAgeUnverified = (bytes[i++] != 0) ? (bool)true : (bool)false; + RegionDenyAgeUnverified = (Utils.BytesToByte(bytes, ref i) != 0); } catch (Exception) { @@ -77922,7 +77924,7 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { - bytes[i++] = (byte)((RegionDenyAgeUnverified) ? 1 : 0); + Utils.ByteToBytes((byte)((RegionDenyAgeUnverified) ? 1 : 0), bytes, ref i); } } @@ -77950,7 +77952,7 @@ public override void FromBytes(byte[] bytes, ref int i) { try { - RegionAllowAccessOverride = (bytes[i++] != 0) ? (bool)true : (bool)false; + RegionAllowAccessOverride = (Utils.BytesToByte(bytes, ref i) != 0); } catch (Exception) { @@ -77960,7 +77962,7 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { - bytes[i++] = (byte)((RegionAllowAccessOverride) ? 1 : 0); + Utils.ByteToBytes((byte)((RegionAllowAccessOverride) ? 1 : 0), bytes, ref i); } } @@ -77990,7 +77992,7 @@ public override void FromBytes(byte[] bytes, ref int i) try { ParcelEnvironmentVersion = Utils.BytesToIntSafepos(bytes, i); i +=4; - RegionAllowEnvironmentOverride = (bytes[i++] != 0) ? (bool)true : (bool)false; + RegionAllowEnvironmentOverride = (Utils.BytesToByte(bytes, ref i) != 0); } catch (Exception) { @@ -78001,7 +78003,7 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { Utils.IntToBytesSafepos(ParcelEnvironmentVersion, bytes, i); i += 4; - bytes[i++] = (byte)((RegionAllowEnvironmentOverride) ? 1 : 0); + Utils.ByteToBytes((byte)((RegionAllowEnvironmentOverride) ? 1 : 0), bytes, ref i); } } @@ -78163,10 +78165,10 @@ public override void FromBytes(byte[] bytes, ref int i) AtAxis.FromBytes(bytes, i); i += 12; LeftAxis.FromBytes(bytes, i); i += 12; UpAxis.FromBytes(bytes, i); i += 12; - ChangedGrid = (bytes[i++] != 0) ? (bool)true : (bool)false; + ChangedGrid = (Utils.BytesToByte(bytes, ref i) != 0); Far = Utils.BytesToFloatSafepos(bytes, i); i += 4; Aspect = Utils.BytesToFloatSafepos(bytes, i); i += 4; - length = bytes[i++]; + length = Utils.BytesToByte(bytes, ref i); Throttles = new byte[length]; Buffer.BlockCopy(bytes, i, Throttles, 0, length); i += length; LocomotionState = Utils.BytesToUIntSafepos(bytes, i); i += 4; @@ -78174,11 +78176,11 @@ public override void FromBytes(byte[] bytes, ref int i) BodyRotation.FromBytes(bytes, i, true); i += 12; ControlFlags = Utils.BytesToUIntSafepos(bytes, i); i += 4; EnergyLevel = Utils.BytesToFloatSafepos(bytes, i); i += 4; - GodLevel = (byte)bytes[i++]; - AlwaysRun = (bytes[i++] != 0) ? (bool)true : (bool)false; + GodLevel = Utils.BytesToByte(bytes, ref i); + AlwaysRun = (Utils.BytesToByte(bytes, ref i) != 0); PreyAgent.FromBytes(bytes, i); i += 16; - AgentAccess = (byte)bytes[i++]; - length = (bytes[i++] + (bytes[i++] << 8)); + AgentAccess = Utils.BytesToByte(bytes, ref i); + length = Utils.BytesToUInt16(bytes, i); i+=2; AgentTextures = new byte[length]; Buffer.BlockCopy(bytes, i, AgentTextures, 0, length); i += length; ActiveGroupID.FromBytes(bytes, i); i += 16; @@ -78202,22 +78204,21 @@ public override void ToBytes(byte[] bytes, ref int i) AtAxis.ToBytes(bytes, i); i += 12; LeftAxis.ToBytes(bytes, i); i += 12; UpAxis.ToBytes(bytes, i); i += 12; - bytes[i++] = (byte)((ChangedGrid) ? 1 : 0); + Utils.ByteToBytes((byte)((ChangedGrid) ? 1 : 0), bytes, ref i); Utils.FloatToBytesSafepos(Far, bytes, i); i += 4; Utils.FloatToBytesSafepos(Aspect, bytes, i); i += 4; - bytes[i++] = (byte)Throttles.Length; + Utils.ByteToBytes((byte)Throttles.Length, bytes, ref i); Buffer.BlockCopy(Throttles, 0, bytes, i, Throttles.Length); i += Throttles.Length; Utils.UIntToBytesSafepos(LocomotionState, bytes, i); i += 4; HeadRotation.ToBytes(bytes, i); i += 12; BodyRotation.ToBytes(bytes, i); i += 12; Utils.UIntToBytesSafepos(ControlFlags, bytes, i); i += 4; Utils.FloatToBytesSafepos(EnergyLevel, bytes, i); i += 4; - bytes[i++] = GodLevel; - bytes[i++] = (byte)((AlwaysRun) ? 1 : 0); + Utils.ByteToBytes( GodLevel, bytes, ref i); + Utils.ByteToBytes((byte)((AlwaysRun) ? 1 : 0), bytes, ref i); PreyAgent.ToBytes(bytes, i); i += 16; - bytes[i++] = AgentAccess; - bytes[i++] = (byte)(AgentTextures.Length % 256); - bytes[i++] = (byte)((AgentTextures.Length >> 8) % 256); + Utils.ByteToBytes( AgentAccess, bytes, ref i); + Utils.UInt16ToBytes((ushort)AgentTextures.Length, bytes, i); i += 2; Buffer.BlockCopy(AgentTextures, 0, bytes, i, AgentTextures.Length); i += AgentTextures.Length; ActiveGroupID.ToBytes(bytes, i); i += 16; } @@ -78251,7 +78252,7 @@ public override void FromBytes(byte[] bytes, ref int i) { GroupID.FromBytes(bytes, i); i += 16; GroupPowers = Utils.BytesToUInt64Safepos(bytes, i); i += 8; - AcceptNotices = (bytes[i++] != 0) ? (bool)true : (bool)false; + AcceptNotices = (Utils.BytesToByte(bytes, ref i) != 0); } catch (Exception) { @@ -78263,7 +78264,7 @@ public override void ToBytes(byte[] bytes, ref int i) { GroupID.ToBytes(bytes, i); i += 16; Utils.UInt64ToBytesSafepos(GroupPowers, bytes, i); i += 8; - bytes[i++] = (byte)((AcceptNotices) ? 1 : 0); + Utils.ByteToBytes((byte)((AcceptNotices) ? 1 : 0), bytes, ref i); } } @@ -78373,7 +78374,7 @@ public override void FromBytes(byte[] bytes, ref int i) int length; try { - length = (bytes[i++] + (bytes[i++] << 8)); + length = Utils.BytesToUInt16(bytes, i); i+=2; NVPairs = new byte[length]; Buffer.BlockCopy(bytes, i, NVPairs, 0, length); i += length; } @@ -78385,8 +78386,7 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { - bytes[i++] = (byte)(NVPairs.Length % 256); - bytes[i++] = (byte)((NVPairs.Length >> 8) % 256); + Utils.UInt16ToBytes((ushort)NVPairs.Length, bytes, i); i += 2; Buffer.BlockCopy(NVPairs, 0, bytes, i, NVPairs.Length); i += NVPairs.Length; } @@ -78415,7 +78415,7 @@ public override void FromBytes(byte[] bytes, ref int i) { try { - ParamValue = (byte)bytes[i++]; + ParamValue = Utils.BytesToByte(bytes, ref i); } catch (Exception) { @@ -78425,7 +78425,7 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { - bytes[i++] = ParamValue; + Utils.ByteToBytes( ParamValue, bytes, ref i); } } @@ -78454,8 +78454,8 @@ public override void FromBytes(byte[] bytes, ref int i) { try { - AgentLegacyAccess = (byte)bytes[i++]; - AgentMaxAccess = (byte)bytes[i++]; + AgentLegacyAccess = Utils.BytesToByte(bytes, ref i); + AgentMaxAccess = Utils.BytesToByte(bytes, ref i); } catch (Exception) { @@ -78465,8 +78465,8 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { - bytes[i++] = AgentLegacyAccess; - bytes[i++] = AgentMaxAccess; + Utils.ByteToBytes( AgentLegacyAccess, bytes, ref i); + Utils.ByteToBytes( AgentMaxAccess, bytes, ref i); } } @@ -78723,19 +78723,19 @@ public override byte[] ToBytes() int i = 0; Header.ToBytes(bytes, ref i); AgentData.ToBytes(bytes, ref i); - bytes[i++] = (byte)GroupData.Length; + Utils.ByteToBytes((byte)GroupData.Length, bytes, ref i); for (int j = 0; j < GroupData.Length; j++) { GroupData[j].ToBytes(bytes, ref i); } - bytes[i++] = (byte)AnimationData.Length; + Utils.ByteToBytes((byte)AnimationData.Length, bytes, ref i); for (int j = 0; j < AnimationData.Length; j++) { AnimationData[j].ToBytes(bytes, ref i); } - bytes[i++] = (byte)GranterBlock.Length; + Utils.ByteToBytes((byte)GranterBlock.Length, bytes, ref i); for (int j = 0; j < GranterBlock.Length; j++) { GranterBlock[j].ToBytes(bytes, ref i); } - bytes[i++] = (byte)NVPairData.Length; + Utils.ByteToBytes((byte)NVPairData.Length, bytes, ref i); for (int j = 0; j < NVPairData.Length; j++) { NVPairData[j].ToBytes(bytes, ref i); } - bytes[i++] = (byte)VisualParam.Length; + Utils.ByteToBytes((byte)VisualParam.Length, bytes, ref i); for (int j = 0; j < VisualParam.Length; j++) { VisualParam[j].ToBytes(bytes, ref i); } - bytes[i++] = (byte)AgentAccess.Length; + Utils.ByteToBytes((byte)AgentAccess.Length, bytes, ref i); for (int j = 0; j < AgentAccess.Length; j++) { AgentAccess[j].ToBytes(bytes, ref i); } - bytes[i++] = (byte)AgentInfo.Length; + Utils.ByteToBytes((byte)AgentInfo.Length, bytes, ref i); for (int j = 0; j < AgentInfo.Length; j++) { AgentInfo[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -79075,7 +79075,7 @@ public override void FromBytes(byte[] bytes, ref int i) AtAxis.FromBytes(bytes, i); i += 12; LeftAxis.FromBytes(bytes, i); i += 12; UpAxis.FromBytes(bytes, i); i += 12; - ChangedGrid = (bytes[i++] != 0) ? (bool)true : (bool)false; + ChangedGrid = (Utils.BytesToByte(bytes, ref i) != 0); } catch (Exception) { @@ -79096,7 +79096,7 @@ public override void ToBytes(byte[] bytes, ref int i) AtAxis.ToBytes(bytes, i); i += 12; LeftAxis.ToBytes(bytes, i); i += 12; UpAxis.ToBytes(bytes, i); i += 12; - bytes[i++] = (byte)((ChangedGrid) ? 1 : 0); + Utils.ByteToBytes((byte)((ChangedGrid) ? 1 : 0), bytes, ref i); } } @@ -79461,7 +79461,7 @@ public override byte[] ToBytes() int i = 0; Header.ToBytes(bytes, ref i); Sender.ToBytes(bytes, ref i); - bytes[i++] = (byte)AnimationList.Length; + Utils.ByteToBytes((byte)AnimationList.Length, bytes, ref i); for (int j = 0; j < AnimationList.Length; j++) { AnimationList[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; @@ -79593,7 +79593,7 @@ public override void FromBytes(byte[] bytes, ref int i) int length; try { - length = (bytes[i++] + (bytes[i++] << 8)); + length = Utils.BytesToUInt16(bytes, i); i+=2; Data = new byte[length]; Buffer.BlockCopy(bytes, i, Data, 0, length); i += length; } @@ -79605,8 +79605,7 @@ public override void FromBytes(byte[] bytes, ref int i) public override void ToBytes(byte[] bytes, ref int i) { - bytes[i++] = (byte)(Data.Length % 256); - bytes[i++] = (byte)((Data.Length >> 8) % 256); + Utils.UInt16ToBytes((ushort)Data.Length, bytes, i); i += 2; Buffer.BlockCopy(Data, 0, bytes, i, Data.Length); i += Data.Length; } diff --git a/Programs/mapgenerator/mapgenerator.cs b/Programs/mapgenerator/mapgenerator.cs index 50408329..1275f290 100644 --- a/Programs/mapgenerator/mapgenerator.cs +++ b/Programs/mapgenerator/mapgenerator.cs @@ -175,7 +175,7 @@ static void WriteFieldToBytes(TextWriter writer, MapField field) switch (field.Type) { case FieldType.BOOL: - writer.WriteLine("Utils.ByteToBytes((byte)((" + field.Name + ") ? 1 : 0), bytes, i);"); + writer.WriteLine("Utils.ByteToBytes((byte)((" + field.Name + ") ? 1 : 0), bytes, ref i);"); break; case FieldType.F32: writer.WriteLine("Utils.FloatToBytesSafepos(" + field.Name + ", bytes, i); i += 4;"); From d94c9e103ada195d0ad3ac17437f2292a1195d2a Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Sun, 21 Apr 2024 02:13:38 +0100 Subject: [PATCH 125/149] typo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 071d4027..cc148e7e 100644 --- a/README.md +++ b/README.md @@ -74,4 +74,4 @@ Or load the generated OpenMetaverse.sln into Visual Studio and build the solutio several projects will only compile and run on windows many of those project also need fixes on their project files to set the framework to netxxx-windows and allow windows forms -For now, runprebuild.(bat/sh) will only create projects for the dlls needed for OpenSimular. +For now, runprebuild.(bat/sh) will only create projects for the dlls needed for OpenSimulator. From f555499111c7b2f884de6e30c1d43085c51a7662 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Sun, 21 Apr 2024 10:51:03 +0100 Subject: [PATCH 126/149] fix runprebuild comment --- runprebuild.bat | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/runprebuild.bat b/runprebuild.bat index 06c1501a..80bc05ff 100644 --- a/runprebuild.bat +++ b/runprebuild.bat @@ -4,9 +4,9 @@ copy bin\System.Drawing.Common.dll.win bin\System.Drawing.Common.dll dotnet bin\prebuild.dll /target vs2022 /targetframework net8_0 /excludedir = "obj | bin" /file prebuildCoreLib.xml @echo Creating compile.bat -rem To compile in debug mode +rem To compile in release mode @echo dotnet build --configuration Release OpenMetaverse.sln > compile.bat -rem To compile in release mode comment line (add rem to start) above and uncomment next (remove rem) +rem To compile in debug mode comment line (add rem to start) above and uncomment next (remove rem) rem @echo %ValueValue% /p:Configuration=Release opensim.sln > compile.bat :done if exist "bin\addin-db-002" ( From 0391cbc628e3ac721dde0bce711c4383266dfcff Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Fri, 2 May 2025 18:57:55 +0100 Subject: [PATCH 127/149] update to code currently in use --- .../LLSD/LLSDxmlEncode.cs | 2 +- OpenMetaverse.StructuredData/LLSD/XmlLLSD.cs | 2 +- OpenMetaverse/BitPack.cs | 97 +- OpenMetaverse/PacketDecoder.cs | 4 +- OpenMetaverse/_Packets_.cs | 1621 +++++++++++++---- OpenMetaverseTypes/Enums.cs | 12 +- OpenMetaverseTypes/Matrix3x3.cs | 1 - OpenMetaverseTypes/OSUTF8.cs | 30 +- OpenMetaverseTypes/OSUTF8Constants.cs | 203 +-- OpenMetaverseTypes/Quaternion.cs | 2 +- Programs/GridProxy/GridProxy.cs | 4 +- Programs/WinGridProxy/ProxyManager.cs | 1 + Programs/WinGridProxy/SessionTypes.cs | 10 +- Programs/mapgenerator/mapgenerator.cs | 37 +- 14 files changed, 1480 insertions(+), 546 deletions(-) diff --git a/OpenMetaverse.StructuredData/LLSD/LLSDxmlEncode.cs b/OpenMetaverse.StructuredData/LLSD/LLSDxmlEncode.cs index d46bce14..5bfac35c 100644 --- a/OpenMetaverse.StructuredData/LLSD/LLSDxmlEncode.cs +++ b/OpenMetaverse.StructuredData/LLSD/LLSDxmlEncode.cs @@ -128,7 +128,7 @@ public static void AddEndArrayAndMap(osUTF8 sb) // undefined or null public static void AddUnknownElem(osUTF8 sb) { - sb.Append(osUTF8Const.XMLundef); + sb.Append(""u8); } public static void AddElem(bool e, osUTF8 sb) diff --git a/OpenMetaverse.StructuredData/LLSD/XmlLLSD.cs b/OpenMetaverse.StructuredData/LLSD/XmlLLSD.cs index 83ca9a12..6cdeb4bb 100644 --- a/OpenMetaverse.StructuredData/LLSD/XmlLLSD.cs +++ b/OpenMetaverse.StructuredData/LLSD/XmlLLSD.cs @@ -370,7 +370,7 @@ public static void SerializeLLSDXmlElement(osUTF8 mb, OSD data, bool formal) switch (data.Type) { case OSDType.Unknown: - mb.Append(osUTF8Const.XMLundef); + mb.Append(""u8); break; case OSDType.Boolean: if(data.AsBoolean()) diff --git a/OpenMetaverse/BitPack.cs b/OpenMetaverse/BitPack.cs index ac32f73b..0254043c 100644 --- a/OpenMetaverse/BitPack.cs +++ b/OpenMetaverse/BitPack.cs @@ -25,6 +25,8 @@ */ using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; namespace OpenMetaverse { @@ -36,7 +38,6 @@ namespace OpenMetaverse public class BitPack { private const int MAX_BITS = 8; - private readonly bool weAreBigEndian = !BitConverter.IsLittleEndian; /// public byte[] Data; @@ -85,6 +86,25 @@ public BitPack(byte[] data, int pos, int? bitp = null) bitPos = 0; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private byte READBYTE() + { + return Unsafe.ReadUnaligned(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(Data), bytePos)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private void BYTESTORE(byte b) + { + Unsafe.WriteUnaligned(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(Data), bytePos), b); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private void OR_BYTESTORE(byte b) + { + byte o = Unsafe.ReadUnaligned(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(Data), bytePos)); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(Data), bytePos), b | o); + } + public void Reset(byte[] data, int pos, int? bitp = null) { Data = data; @@ -108,10 +128,10 @@ public void Reset(byte[] data, int pos, int? bitp = null) /// Pack a floating point value in to the data /// /// Floating point value to pack - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe void PackFloat(float data) { - int d = (*(int*)&data); + uint d = Unsafe.As(ref data); PackBitsFromByte((byte)d); PackBitsFromByte((byte)(d >> 8)); PackBitsFromByte((byte)(d >> 16)); @@ -123,7 +143,7 @@ public unsafe void PackFloat(float data) ///
/// Integer containing the data to pack /// Number of bits of the integer to pack - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void PackBits(int data, int totalCount) { PackBits((uint)data, totalCount); @@ -134,7 +154,7 @@ public void PackBits(int data, int totalCount) ///
/// Unsigned integer containing the data to pack /// Number of bits of the integer to pack - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void PackBits(uint data, int totalCount) { while (totalCount > 8) @@ -147,7 +167,7 @@ public void PackBits(uint data, int totalCount) PackBitsFromByte((byte)data, totalCount); } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void PackBitsFromUInt(uint data) { PackBitsFromByte((byte)data); @@ -156,20 +176,20 @@ public void PackBitsFromUInt(uint data) PackBitsFromByte((byte)(data >> 24)); } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void PackBitsFromInt(int data) { PackBitsFromUInt((uint)data); } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void PackBitsFromUShort(ushort data) { PackBitsFromByte((byte)data); PackBitsFromByte((byte)(data >> 8)); } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void PackBitsFromShort(short data) { PackBitsFromUShort((ushort) data); @@ -292,7 +312,7 @@ public float UnpackFloat() { byte[] output = UnpackBitsArray(32); - if (weAreBigEndian) Array.Reverse(output); + if (!BitConverter.IsLittleEndian) Array.Reverse(output); return BitConverter.ToSingle(output, 0); } @@ -306,7 +326,7 @@ public int UnpackBits(int totalCount) { byte[] output = UnpackBitsArray(totalCount); - if (weAreBigEndian) Array.Reverse(output); + if (!BitConverter.IsLittleEndian) Array.Reverse(output); return BitConverter.ToInt32(output, 0); } @@ -321,7 +341,7 @@ public uint UnpackUBits(int totalCount) { byte[] output = UnpackBitsArray(totalCount); - if (weAreBigEndian) Array.Reverse(output); + if (!BitConverter.IsLittleEndian) Array.Reverse(output); return BitConverter.ToUInt32(output, 0); } @@ -437,67 +457,70 @@ private void PackBitArray(byte[] data, int totalCount) PackBitsFromByte(data[count], totalCount); } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void PackBitsFromByte(byte inbyte) { if(bitPos == 0) { - Data[bytePos++] = inbyte; + BYTESTORE(inbyte); + ++bytePos; if (bytePos < Data.Length) - Data[bytePos] = 0; + BYTESTORE(0); return; } if (inbyte == 0) { ++bytePos; - Data[bytePos] = 0; + BYTESTORE(0); return; } - Data[bytePos++] |= (byte)(inbyte >> bitPos); - Data[bytePos] = (byte)(inbyte << (8 - bitPos)); + OR_BYTESTORE((byte)(inbyte >> bitPos)); + ++bytePos; + OR_BYTESTORE((byte)(inbyte << (8 - bitPos))); } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void PackBitsFromByte(byte inbyte, int count) { + if (count < 1) + return; + if (count > 8) //should not happen count = 7; else --count; - while (count >= 0) + byte cur = READBYTE(); + while (count > 0) { if ((inbyte & (0x01 << count)) != 0) - Data[bytePos] |= (byte)(0x80 >> bitPos); + cur |= (byte)(0x80 >> bitPos); --count; ++bitPos; if (bitPos >= MAX_BITS) { - bitPos = 0; + BYTESTORE(cur); ++bytePos; - if (bytePos < Data.Length) - Data[bytePos] = 0; + cur = 0; + bitPos = 0; } } - } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public void PackBitFromBit(byte inbyte) - { - if ((inbyte & 0x01) != 0) - Data[bytePos] |= (byte)(0x80 >> bitPos); + if ((inbyte & 0x01 ) != 0) + cur |= (byte)(0x80 >> bitPos); ++bitPos; if (bitPos >= MAX_BITS) { bitPos = 0; - ++bytePos; - if (bytePos < Data.Length) - Data[bytePos] = 0; - } + + BYTESTORE(cur); + ++bytePos; + if (bytePos < Data.Length) + BYTESTORE(0); } /// @@ -505,11 +528,11 @@ public void PackBitFromBit(byte inbyte) /// /// Bit to pack - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void PackBit(bool bit) { if (bit) - Data[bytePos] |= (byte)(0x80 >> bitPos); + OR_BYTESTORE((byte)(0x80 >> bitPos)); ++bitPos; @@ -518,7 +541,7 @@ public void PackBit(bool bit) bitPos = 0; ++bytePos; if (bytePos < Data.Length) - Data[bytePos] = 0; + BYTESTORE(0); } } diff --git a/OpenMetaverse/PacketDecoder.cs b/OpenMetaverse/PacketDecoder.cs index 0ad11faa..ed95193e 100644 --- a/OpenMetaverse/PacketDecoder.cs +++ b/OpenMetaverse/PacketDecoder.cs @@ -1657,7 +1657,9 @@ public static string PacketToString(Packet packet) for (int i = 0; i < fields.Length; i++) { // we're not interested in any of these here - if (fields[i].Name == "Type" || fields[i].Name == "Header" || fields[i].Name == "HasVariableBlocks") + if (fields[i].Name == "Type" || fields[i].Name == "Header" || + fields[i].Name == "HasVariableBlocks" || + fields[i].Name == "NeedValidateIDs") continue; if (fields[i].FieldType.IsArray) diff --git a/OpenMetaverse/_Packets_.cs b/OpenMetaverse/_Packets_.cs index 11218f32..d0d2265f 100644 --- a/OpenMetaverse/_Packets_.cs +++ b/OpenMetaverse/_Packets_.cs @@ -700,6 +700,8 @@ public abstract partial class Packet public abstract void FromBytes(Header header, byte[] bytes, ref int i); public abstract byte[] ToBytes(); public abstract byte[][] ToBytesMultiple(); + public bool NeedValidateIDs; + public virtual bool ValidIDs(UUID session, UUID agent) { return true; } public static PacketType GetType(ushort id, PacketFrequency frequency) { @@ -2040,8 +2042,9 @@ public TestMessagePacket() Type = PacketType.TestMessage; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 1; + Header.ID =1; Header.Reliable = true; + NeedValidateIDs = false; Header.Zerocoded = true; TestBlock1 = new TestBlock1Block(); NeighborBlock = new NeighborBlockBlock[4]; @@ -2174,8 +2177,9 @@ public UseCircuitCodePacket() Type = PacketType.UseCircuitCode; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 3; + Header.ID =3; Header.Reliable = true; + NeedValidateIDs = false; CircuitCode = new CircuitCodeBlock(); } @@ -2340,8 +2344,9 @@ public TelehubInfoPacket() Type = PacketType.TelehubInfo; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 10; + Header.ID =10; Header.Reliable = true; + NeedValidateIDs = false; TelehubBlock = new TelehubBlockBlock(); SpawnPointBlock = null; } @@ -2484,8 +2489,9 @@ public EconomyDataRequestPacket() Type = PacketType.EconomyDataRequest; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 24; + Header.ID =24; Header.Reliable = true; + NeedValidateIDs = false; } public EconomyDataRequestPacket(byte[] bytes, ref int i) : this() @@ -2637,8 +2643,9 @@ public EconomyDataPacket() Type = PacketType.EconomyData; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 25; + Header.ID =25; Header.Reliable = true; + NeedValidateIDs = false; Header.Zerocoded = true; Info = new InfoBlock(); } @@ -2794,14 +2801,17 @@ public override int Length public AgentDataBlock AgentData; public DataBlock Data; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public AvatarPickerRequestPacket() { HasVariableBlocks = false; Type = PacketType.AvatarPickerRequest; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 26; + Header.ID =26; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); Data = new DataBlock(); } @@ -2975,8 +2985,9 @@ public AvatarPickerReplyPacket() Type = PacketType.AvatarPickerReply; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 28; + Header.ID =28; Header.Reliable = true; + NeedValidateIDs = false; AgentData = new AgentDataBlock(); Data = null; } @@ -3258,14 +3269,17 @@ public override int Length public TransactionDataBlock TransactionData; public QueryDataBlock QueryData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public PlacesQueryPacket() { HasVariableBlocks = false; Type = PacketType.PlacesQuery; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 29; + Header.ID =29; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); TransactionData = new TransactionDataBlock(); @@ -3519,8 +3533,9 @@ public PlacesReplyPacket() Type = PacketType.PlacesReply; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 30; + Header.ID =30; Header.Reliable = true; + NeedValidateIDs = false; Header.Zerocoded = true; AgentData = new AgentDataBlock(); TransactionData = new TransactionDataBlock(); @@ -3763,14 +3778,17 @@ public override int Length public AgentDataBlock AgentData; public QueryDataBlock QueryData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public DirFindQueryPacket() { HasVariableBlocks = false; Type = PacketType.DirFindQuery; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 31; + Header.ID =31; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); QueryData = new QueryDataBlock(); @@ -3947,14 +3965,17 @@ public override int Length public AgentDataBlock AgentData; public QueryDataBlock QueryData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public DirPlacesQueryPacket() { HasVariableBlocks = false; Type = PacketType.DirPlacesQuery; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 33; + Header.ID =33; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); QueryData = new QueryDataBlock(); @@ -4210,8 +4231,9 @@ public DirPlacesReplyPacket() Type = PacketType.DirPlacesReply; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 35; + Header.ID =35; Header.Reliable = true; + NeedValidateIDs = false; Header.Zerocoded = true; AgentData = new AgentDataBlock(); QueryData = null; @@ -4583,8 +4605,9 @@ public DirPeopleReplyPacket() Type = PacketType.DirPeopleReply; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 36; + Header.ID =36; Header.Reliable = true; + NeedValidateIDs = false; Header.Zerocoded = true; AgentData = new AgentDataBlock(); QueryData = new QueryDataBlock(); @@ -4922,8 +4945,9 @@ public DirEventsReplyPacket() Type = PacketType.DirEventsReply; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 37; + Header.ID =37; Header.Reliable = true; + NeedValidateIDs = false; Header.Zerocoded = true; AgentData = new AgentDataBlock(); QueryData = new QueryDataBlock(); @@ -5249,8 +5273,9 @@ public DirGroupsReplyPacket() Type = PacketType.DirGroupsReply; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 38; + Header.ID =38; Header.Reliable = true; + NeedValidateIDs = false; Header.Zerocoded = true; AgentData = new AgentDataBlock(); QueryData = new QueryDataBlock(); @@ -5496,14 +5521,17 @@ public override int Length public AgentDataBlock AgentData; public QueryDataBlock QueryData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public DirClassifiedQueryPacket() { HasVariableBlocks = false; Type = PacketType.DirClassifiedQuery; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 39; + Header.ID =39; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); QueryData = new QueryDataBlock(); @@ -5761,8 +5789,9 @@ public DirClassifiedReplyPacket() Type = PacketType.DirClassifiedReply; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 41; + Header.ID =41; Header.Reliable = true; + NeedValidateIDs = false; Header.Zerocoded = true; AgentData = new AgentDataBlock(); QueryData = new QueryDataBlock(); @@ -6045,8 +6074,9 @@ public AvatarClassifiedReplyPacket() Type = PacketType.AvatarClassifiedReply; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 42; + Header.ID =42; Header.Reliable = true; + NeedValidateIDs = false; AgentData = new AgentDataBlock(); Data = null; } @@ -6266,14 +6296,17 @@ public override int Length public AgentDataBlock AgentData; public DataBlock Data; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public ClassifiedInfoRequestPacket() { HasVariableBlocks = false; Type = PacketType.ClassifiedInfoRequest; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 43; + Header.ID =43; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); Data = new DataBlock(); @@ -6488,8 +6521,9 @@ public ClassifiedInfoReplyPacket() Type = PacketType.ClassifiedInfoReply; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 44; + Header.ID =44; Header.Reliable = true; + NeedValidateIDs = false; AgentData = new AgentDataBlock(); Data = new DataBlock(); } @@ -6677,14 +6711,17 @@ public override int Length public AgentDataBlock AgentData; public DataBlock Data; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public ClassifiedInfoUpdatePacket() { HasVariableBlocks = false; Type = PacketType.ClassifiedInfoUpdate; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 45; + Header.ID =45; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); Data = new DataBlock(); } @@ -6835,14 +6872,17 @@ public override int Length public AgentDataBlock AgentData; public DataBlock Data; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public ClassifiedDeletePacket() { HasVariableBlocks = false; Type = PacketType.ClassifiedDelete; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 46; + Header.ID =46; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); Data = new DataBlock(); } @@ -6996,14 +7036,17 @@ public override int Length public AgentDataBlock AgentData; public DataBlock Data; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public ClassifiedGodDeletePacket() { HasVariableBlocks = false; Type = PacketType.ClassifiedGodDelete; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 47; + Header.ID =47; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); Data = new DataBlock(); } @@ -7169,14 +7212,17 @@ public override int Length public AgentDataBlock AgentData; public QueryDataBlock QueryData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public DirLandQueryPacket() { HasVariableBlocks = false; Type = PacketType.DirLandQuery; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 48; + Header.ID =48; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); QueryData = new QueryDataBlock(); @@ -7393,8 +7439,9 @@ public DirLandReplyPacket() Type = PacketType.DirLandReply; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 50; + Header.ID =50; Header.Reliable = true; + NeedValidateIDs = false; Header.Zerocoded = true; AgentData = new AgentDataBlock(); QueryData = new QueryDataBlock(); @@ -7625,14 +7672,17 @@ public override int Length public AgentDataBlock AgentData; public QueryDataBlock QueryData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public DirPopularQueryPacket() { HasVariableBlocks = false; Type = PacketType.DirPopularQuery; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 51; + Header.ID =51; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); QueryData = new QueryDataBlock(); @@ -7840,8 +7890,9 @@ public DirPopularReplyPacket() Type = PacketType.DirPopularReply; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 53; + Header.ID =53; Header.Reliable = true; + NeedValidateIDs = false; Header.Zerocoded = true; AgentData = new AgentDataBlock(); QueryData = new QueryDataBlock(); @@ -8069,14 +8120,17 @@ public override int Length public AgentDataBlock AgentData; public DataBlock Data; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public ParcelInfoRequestPacket() { HasVariableBlocks = false; Type = PacketType.ParcelInfoRequest; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 54; + Header.ID =54; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); Data = new DataBlock(); } @@ -8286,8 +8340,9 @@ public ParcelInfoReplyPacket() Type = PacketType.ParcelInfoReply; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 55; + Header.ID =55; Header.Reliable = true; + NeedValidateIDs = false; Header.Zerocoded = true; AgentData = new AgentDataBlock(); Data = new DataBlock(); @@ -8439,14 +8494,17 @@ public override int Length public AgentDataBlock AgentData; public ParcelDataBlock ParcelData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public ParcelObjectOwnersRequestPacket() { HasVariableBlocks = false; Type = PacketType.ParcelObjectOwnersRequest; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 56; + Header.ID =56; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); ParcelData = new ParcelDataBlock(); } @@ -8570,8 +8628,9 @@ public ParcelObjectOwnersReplyPacket() Type = PacketType.ParcelObjectOwnersReply; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 57; + Header.ID =57; Header.Reliable = true; + NeedValidateIDs = false; Header.Zerocoded = true; Data = null; } @@ -8785,14 +8844,17 @@ public override int Length public AgentDataBlock AgentData; public DataBlock Data; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public GroupNoticesListRequestPacket() { HasVariableBlocks = false; Type = PacketType.GroupNoticesListRequest; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 58; + Header.ID =58; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); Data = new DataBlock(); } @@ -8975,8 +9037,9 @@ public GroupNoticesListReplyPacket() Type = PacketType.GroupNoticesListReply; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 59; + Header.ID =59; Header.Reliable = true; + NeedValidateIDs = false; AgentData = new AgentDataBlock(); Data = null; } @@ -9196,14 +9259,17 @@ public override int Length public AgentDataBlock AgentData; public DataBlock Data; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public GroupNoticeRequestPacket() { HasVariableBlocks = false; Type = PacketType.GroupNoticeRequest; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 60; + Header.ID =60; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); Data = new DataBlock(); } @@ -9360,14 +9426,17 @@ public override int Length public AgentDataBlock AgentData; public InfoBlock Info; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public TeleportRequestPacket() { HasVariableBlocks = false; Type = PacketType.TeleportRequest; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 62; + Header.ID =62; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); Info = new InfoBlock(); } @@ -9524,14 +9593,17 @@ public override int Length public AgentDataBlock AgentData; public InfoBlock Info; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public TeleportLocationRequestPacket() { HasVariableBlocks = false; Type = PacketType.TeleportLocationRequest; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 63; + Header.ID =63; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); Info = new InfoBlock(); } @@ -9657,8 +9729,9 @@ public TeleportLocalPacket() Type = PacketType.TeleportLocal; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 64; + Header.ID =64; Header.Reliable = true; + NeedValidateIDs = false; Info = new InfoBlock(); } @@ -9773,8 +9846,9 @@ public TeleportLandmarkRequestPacket() Type = PacketType.TeleportLandmarkRequest; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 65; + Header.ID =65; Header.Reliable = true; + NeedValidateIDs = false; Header.Zerocoded = true; Info = new InfoBlock(); } @@ -9933,8 +10007,9 @@ public TeleportProgressPacket() Type = PacketType.TeleportProgress; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 66; + Header.ID =66; Header.Reliable = true; + NeedValidateIDs = false; AgentData = new AgentDataBlock(); Info = new InfoBlock(); } @@ -10075,8 +10150,9 @@ public TeleportFinishPacket() Type = PacketType.TeleportFinish; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 69; + Header.ID =69; Header.Reliable = true; + NeedValidateIDs = false; Info = new InfoBlock(); } @@ -10272,14 +10348,17 @@ public override int Length public InfoBlock Info; public TargetDataBlock[] TargetData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public StartLurePacket() { HasVariableBlocks = true; Type = PacketType.StartLure; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 70; + Header.ID =70; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); Info = new InfoBlock(); TargetData = null; @@ -10478,8 +10557,9 @@ public TeleportLureRequestPacket() Type = PacketType.TeleportLureRequest; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 71; + Header.ID =71; Header.Reliable = true; + NeedValidateIDs = false; Info = new InfoBlock(); } @@ -10591,8 +10671,9 @@ public TeleportCancelPacket() Type = PacketType.TeleportCancel; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 72; + Header.ID =72; Header.Reliable = true; + NeedValidateIDs = false; Info = new InfoBlock(); } @@ -10701,8 +10782,9 @@ public TeleportStartPacket() Type = PacketType.TeleportStart; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 73; + Header.ID =73; Header.Reliable = true; + NeedValidateIDs = false; Info = new InfoBlock(); } @@ -10874,8 +10956,9 @@ public TeleportFailedPacket() Type = PacketType.TeleportFailed; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 74; + Header.ID =74; Header.Reliable = true; + NeedValidateIDs = false; Info = new InfoBlock(); AlertInfo = null; } @@ -11099,14 +11182,17 @@ public override int Length public AgentDataBlock AgentData; public ObjectDataBlock[] ObjectData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public UndoPacket() { HasVariableBlocks = true; Type = PacketType.Undo; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 75; + Header.ID =75; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); ObjectData = null; } @@ -11330,14 +11416,17 @@ public override int Length public AgentDataBlock AgentData; public ObjectDataBlock[] ObjectData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public RedoPacket() { HasVariableBlocks = true; Type = PacketType.Redo; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 76; + Header.ID =76; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); ObjectData = null; } @@ -11517,14 +11606,17 @@ public override int Length } public AgentDataBlock AgentData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public UndoLandPacket() { HasVariableBlocks = false; Type = PacketType.UndoLand; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 77; + Header.ID =77; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); } @@ -11633,14 +11725,17 @@ public override int Length } public AgentDataBlock AgentData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public AgentPausePacket() { HasVariableBlocks = false; Type = PacketType.AgentPause; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 78; + Header.ID =78; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); } @@ -11749,14 +11844,17 @@ public override int Length } public AgentDataBlock AgentData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public AgentResumePacket() { HasVariableBlocks = false; Type = PacketType.AgentResume; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 79; + Header.ID =79; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); } @@ -11914,14 +12012,17 @@ public override int Length public AgentDataBlock AgentData; public ChatDataBlock ChatData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public ChatFromViewerPacket() { HasVariableBlocks = false; Type = PacketType.ChatFromViewer; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 80; + Header.ID =80; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); ChatData = new ChatDataBlock(); @@ -12085,14 +12186,17 @@ public override int Length public AgentDataBlock AgentData; public ThrottleBlock Throttle; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public AgentThrottlePacket() { HasVariableBlocks = false; Type = PacketType.AgentThrottle; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 81; + Header.ID =81; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); Throttle = new ThrottleBlock(); @@ -12250,14 +12354,17 @@ public override int Length public AgentDataBlock AgentData; public FOVBlockBlock FOVBlock; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public AgentFOVPacket() { HasVariableBlocks = false; Type = PacketType.AgentFOV; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 82; + Header.ID =82; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); FOVBlock = new FOVBlockBlock(); } @@ -12417,14 +12524,17 @@ public override int Length public AgentDataBlock AgentData; public HeightWidthBlockBlock HeightWidthBlock; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public AgentHeightWidthPacket() { HasVariableBlocks = false; Type = PacketType.AgentHeightWidth; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 83; + Header.ID =83; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); HeightWidthBlock = new HeightWidthBlockBlock(); } @@ -12672,14 +12782,17 @@ public override int Length public ObjectDataBlock ObjectData; public VisualParamBlock[] VisualParam; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public AgentSetAppearancePacket() { HasVariableBlocks = true; Type = PacketType.AgentSetAppearance; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 84; + Header.ID =84; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); WearableData = null; @@ -12873,14 +12986,17 @@ public override int Length public AgentDataBlock AgentData; public FuseBlockBlock FuseBlock; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public AgentQuitCopyPacket() { HasVariableBlocks = false; Type = PacketType.AgentQuitCopy; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 85; + Header.ID =85; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); FuseBlock = new FuseBlockBlock(); } @@ -12994,8 +13110,9 @@ public ImageNotInDatabasePacket() Type = PacketType.ImageNotInDatabase; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 86; + Header.ID =86; Header.Reliable = true; + NeedValidateIDs = false; ImageID = new ImageIDBlock(); } @@ -13104,8 +13221,9 @@ public RebakeAvatarTexturesPacket() Type = PacketType.RebakeAvatarTextures; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 87; + Header.ID =87; Header.Reliable = true; + NeedValidateIDs = false; TextureData = new TextureDataBlock(); } @@ -13214,14 +13332,17 @@ public override int Length } public AgentDataBlock AgentData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public SetAlwaysRunPacket() { HasVariableBlocks = false; Type = PacketType.SetAlwaysRun; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 88; + Header.ID =88; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); } @@ -13371,14 +13492,17 @@ public override int Length public AgentDataBlock AgentData; public ObjectDataBlock[] ObjectData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public ObjectDeletePacket() { HasVariableBlocks = true; Type = PacketType.ObjectDelete; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 89; + Header.ID =89; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); ObjectData = null; @@ -13646,14 +13770,17 @@ public override int Length public SharedDataBlock SharedData; public ObjectDataBlock[] ObjectData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public ObjectDuplicatePacket() { HasVariableBlocks = true; Type = PacketType.ObjectDuplicate; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 90; + Header.ID =90; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); SharedData = new SharedDataBlock(); @@ -13909,14 +14036,17 @@ public override int Length public AgentDataBlock AgentData; public ObjectDataBlock[] ObjectData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public ObjectDuplicateOnRayPacket() { HasVariableBlocks = true; Type = PacketType.ObjectDuplicateOnRay; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 91; + Header.ID =91; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); ObjectData = null; @@ -14141,14 +14271,17 @@ public override int Length public AgentDataBlock AgentData; public ObjectDataBlock[] ObjectData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public ObjectScalePacket() { HasVariableBlocks = true; Type = PacketType.ObjectScale; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 92; + Header.ID =92; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); ObjectData = null; @@ -14373,14 +14506,17 @@ public override int Length public AgentDataBlock AgentData; public ObjectDataBlock[] ObjectData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public ObjectRotationPacket() { HasVariableBlocks = true; Type = PacketType.ObjectRotation; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 93; + Header.ID =93; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); ObjectData = null; @@ -14629,14 +14765,17 @@ public override int Length public AgentDataBlock AgentData; public ExtraPhysicsBlock[] ExtraPhysics; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public ObjectFlagUpdatePacket() { HasVariableBlocks = true; Type = PacketType.ObjectFlagUpdate; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 94; + Header.ID =94; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); ExtraPhysics = null; @@ -14861,14 +15000,17 @@ public override int Length public AgentDataBlock AgentData; public ObjectDataBlock[] ObjectData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public ObjectClickActionPacket() { HasVariableBlocks = true; Type = PacketType.ObjectClickAction; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 95; + Header.ID =95; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); ObjectData = null; @@ -15106,14 +15248,17 @@ public override int Length public AgentDataBlock AgentData; public ObjectDataBlock[] ObjectData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public ObjectImagePacket() { HasVariableBlocks = true; Type = PacketType.ObjectImage; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 96; + Header.ID =96; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); ObjectData = null; @@ -15338,14 +15483,17 @@ public override int Length public AgentDataBlock AgentData; public ObjectDataBlock[] ObjectData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public ObjectMaterialPacket() { HasVariableBlocks = true; Type = PacketType.ObjectMaterial; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 97; + Header.ID =97; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); ObjectData = null; @@ -15621,14 +15769,17 @@ public override int Length public AgentDataBlock AgentData; public ObjectDataBlock[] ObjectData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public ObjectShapePacket() { HasVariableBlocks = true; Type = PacketType.ObjectShape; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 98; + Header.ID =98; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); ObjectData = null; @@ -15868,14 +16019,17 @@ public override int Length public AgentDataBlock AgentData; public ObjectDataBlock[] ObjectData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public ObjectExtraParamsPacket() { HasVariableBlocks = true; Type = PacketType.ObjectExtraParams; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 99; + Header.ID =99; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); ObjectData = null; @@ -16143,14 +16297,17 @@ public override int Length public HeaderDataBlock HeaderData; public ObjectDataBlock[] ObjectData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public ObjectOwnerPacket() { HasVariableBlocks = true; Type = PacketType.ObjectOwner; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 100; + Header.ID =100; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); HeaderData = new HeaderDataBlock(); @@ -16382,14 +16539,17 @@ public override int Length public AgentDataBlock AgentData; public ObjectDataBlock[] ObjectData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public ObjectGroupPacket() { HasVariableBlocks = true; Type = PacketType.ObjectGroup; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 101; + Header.ID =101; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); ObjectData = null; @@ -16623,14 +16783,17 @@ public override int Length public AgentDataBlock AgentData; public ObjectDataBlock[] ObjectData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public ObjectBuyPacket() { HasVariableBlocks = true; Type = PacketType.ObjectBuy; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 102; + Header.ID =102; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); ObjectData = null; @@ -16857,14 +17020,17 @@ public override int Length public AgentDataBlock AgentData; public DataBlock Data; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public BuyObjectInventoryPacket() { HasVariableBlocks = false; Type = PacketType.BuyObjectInventory; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 103; + Header.ID =103; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); Data = new DataBlock(); @@ -16982,8 +17148,9 @@ public DerezContainerPacket() Type = PacketType.DerezContainer; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 104; + Header.ID =104; Header.Reliable = true; + NeedValidateIDs = false; Header.Zerocoded = true; Data = new DataBlock(); } @@ -17180,14 +17347,17 @@ public override int Length public HeaderDataBlock HeaderData; public ObjectDataBlock[] ObjectData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public ObjectPermissionsPacket() { HasVariableBlocks = true; Type = PacketType.ObjectPermissions; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 105; + Header.ID =105; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); HeaderData = new HeaderDataBlock(); @@ -17422,14 +17592,17 @@ public override int Length public AgentDataBlock AgentData; public ObjectDataBlock[] ObjectData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public ObjectSaleInfoPacket() { HasVariableBlocks = true; Type = PacketType.ObjectSaleInfo; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 106; + Header.ID =106; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); ObjectData = null; @@ -17660,14 +17833,17 @@ public override int Length public AgentDataBlock AgentData; public ObjectDataBlock[] ObjectData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public ObjectNamePacket() { HasVariableBlocks = true; Type = PacketType.ObjectName; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 107; + Header.ID =107; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); ObjectData = null; @@ -17898,14 +18074,17 @@ public override int Length public AgentDataBlock AgentData; public ObjectDataBlock[] ObjectData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public ObjectDescriptionPacket() { HasVariableBlocks = true; Type = PacketType.ObjectDescription; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 108; + Header.ID =108; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); ObjectData = null; @@ -18130,14 +18309,17 @@ public override int Length public AgentDataBlock AgentData; public ObjectDataBlock[] ObjectData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public ObjectCategoryPacket() { HasVariableBlocks = true; Type = PacketType.ObjectCategory; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 109; + Header.ID =109; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); ObjectData = null; @@ -18359,14 +18541,17 @@ public override int Length public AgentDataBlock AgentData; public ObjectDataBlock[] ObjectData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public ObjectSelectPacket() { HasVariableBlocks = true; Type = PacketType.ObjectSelect; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 110; + Header.ID =110; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); ObjectData = null; @@ -18588,14 +18773,17 @@ public override int Length public AgentDataBlock AgentData; public ObjectDataBlock[] ObjectData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public ObjectDeselectPacket() { HasVariableBlocks = true; Type = PacketType.ObjectDeselect; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 111; + Header.ID =111; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); ObjectData = null; @@ -18823,14 +19011,17 @@ public override int Length public AgentDataBlock AgentData; public ObjectDataBlock[] ObjectData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public ObjectAttachPacket() { HasVariableBlocks = true; Type = PacketType.ObjectAttach; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 112; + Header.ID =112; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); ObjectData = null; @@ -19052,14 +19243,17 @@ public override int Length public AgentDataBlock AgentData; public ObjectDataBlock[] ObjectData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public ObjectDetachPacket() { HasVariableBlocks = true; Type = PacketType.ObjectDetach; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 113; + Header.ID =113; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); ObjectData = null; } @@ -19280,14 +19474,17 @@ public override int Length public AgentDataBlock AgentData; public ObjectDataBlock[] ObjectData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public ObjectDropPacket() { HasVariableBlocks = true; Type = PacketType.ObjectDrop; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 114; + Header.ID =114; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); ObjectData = null; } @@ -19508,14 +19705,17 @@ public override int Length public AgentDataBlock AgentData; public ObjectDataBlock[] ObjectData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public ObjectLinkPacket() { HasVariableBlocks = true; Type = PacketType.ObjectLink; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 115; + Header.ID =115; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); ObjectData = null; } @@ -19736,14 +19936,17 @@ public override int Length public AgentDataBlock AgentData; public ObjectDataBlock[] ObjectData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public ObjectDelinkPacket() { HasVariableBlocks = true; Type = PacketType.ObjectDelink; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 116; + Header.ID =116; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); ObjectData = null; } @@ -20022,14 +20225,17 @@ public override int Length public ObjectDataBlock ObjectData; public SurfaceInfoBlock[] SurfaceInfo; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public ObjectGrabPacket() { HasVariableBlocks = true; Type = PacketType.ObjectGrab; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 117; + Header.ID =117; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); ObjectData = new ObjectDataBlock(); @@ -20322,14 +20528,17 @@ public override int Length public ObjectDataBlock ObjectData; public SurfaceInfoBlock[] SurfaceInfo; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public ObjectGrabUpdatePacket() { HasVariableBlocks = true; Type = PacketType.ObjectGrabUpdate; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 118; + Header.ID =118; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); ObjectData = new ObjectDataBlock(); @@ -20613,14 +20822,17 @@ public override int Length public ObjectDataBlock ObjectData; public SurfaceInfoBlock[] SurfaceInfo; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public ObjectDeGrabPacket() { HasVariableBlocks = true; Type = PacketType.ObjectDeGrab; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 119; + Header.ID =119; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); ObjectData = new ObjectDataBlock(); SurfaceInfo = null; @@ -20847,14 +21059,17 @@ public override int Length public AgentDataBlock AgentData; public ObjectDataBlock ObjectData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public ObjectSpinStartPacket() { HasVariableBlocks = false; Type = PacketType.ObjectSpinStart; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 120; + Header.ID =120; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); ObjectData = new ObjectDataBlock(); @@ -21009,14 +21224,17 @@ public override int Length public AgentDataBlock AgentData; public ObjectDataBlock ObjectData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public ObjectSpinUpdatePacket() { HasVariableBlocks = false; Type = PacketType.ObjectSpinUpdate; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 121; + Header.ID =121; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); ObjectData = new ObjectDataBlock(); @@ -21168,14 +21386,17 @@ public override int Length public AgentDataBlock AgentData; public ObjectDataBlock ObjectData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public ObjectSpinStopPacket() { HasVariableBlocks = false; Type = PacketType.ObjectSpinStop; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 122; + Header.ID =122; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); ObjectData = new ObjectDataBlock(); @@ -21337,8 +21558,9 @@ public ObjectExportSelectedPacket() Type = PacketType.ObjectExportSelected; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 123; + Header.ID =123; Header.Reliable = true; + NeedValidateIDs = false; Header.Zerocoded = true; AgentData = new AgentDataBlock(); ObjectData = null; @@ -21662,14 +21884,17 @@ public override int Length public ParcelDataBlock[] ParcelData; public ModifyBlockExtendedBlock[] ModifyBlockExtended; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public ModifyLandPacket() { HasVariableBlocks = true; Type = PacketType.ModifyLand; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 124; + Header.ID =124; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); ModifyBlock = new ModifyBlockBlock(); @@ -21896,14 +22121,17 @@ public override int Length } public AgentDataBlock AgentData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public VelocityInterpolateOnPacket() { HasVariableBlocks = false; Type = PacketType.VelocityInterpolateOn; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 125; + Header.ID =125; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); } @@ -22009,14 +22237,17 @@ public override int Length } public AgentDataBlock AgentData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public VelocityInterpolateOffPacket() { HasVariableBlocks = false; Type = PacketType.VelocityInterpolateOff; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 126; + Header.ID =126; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); } @@ -22168,14 +22399,17 @@ public override int Length public AgentDataBlock AgentData; public DataBlockBlock DataBlock; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public StateSavePacket() { HasVariableBlocks = false; Type = PacketType.StateSave; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 127; + Header.ID =127; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); DataBlock = new DataBlockBlock(); } @@ -22292,8 +22526,9 @@ public ReportAutosaveCrashPacket() Type = PacketType.ReportAutosaveCrash; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 128; + Header.ID =128; Header.Reliable = true; + NeedValidateIDs = false; AutosaveData = new AutosaveDataBlock(); } @@ -22442,14 +22677,17 @@ public override int Length public AgentDataBlock AgentData; public DataBlockBlock DataBlock; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public SimWideDeletesPacket() { HasVariableBlocks = false; Type = PacketType.SimWideDeletes; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 129; + Header.ID =129; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); DataBlock = new DataBlockBlock(); } @@ -22600,14 +22838,17 @@ public override int Length public AgentDataBlock AgentData; public TargetDataBlock TargetData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public TrackAgentPacket() { HasVariableBlocks = false; Type = PacketType.TrackAgent; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 130; + Header.ID =130; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); TargetData = new TargetDataBlock(); } @@ -22966,14 +23207,17 @@ public override int Length public FailStatsBlock FailStats; public MiscStatsBlock[] MiscStats; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public ViewerStatsPacket() { HasVariableBlocks = true; Type = PacketType.ViewerStats; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 131; + Header.ID =131; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); DownloadTotals = new DownloadTotalsBlock(); @@ -23233,14 +23477,17 @@ public override int Length public AgentDataBlock AgentData; public DataBlock Data; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public ScriptAnswerYesPacket() { HasVariableBlocks = false; Type = PacketType.ScriptAnswerYes; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 132; + Header.ID =132; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); Data = new DataBlock(); } @@ -23442,14 +23689,17 @@ public override int Length public AgentDataBlock AgentData; public ReportDataBlock ReportData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public UserReportPacket() { HasVariableBlocks = false; Type = PacketType.UserReport; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 133; + Header.ID =133; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); ReportData = new ReportDataBlock(); @@ -23624,8 +23874,9 @@ public AlertMessagePacket() Type = PacketType.AlertMessage; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 134; + Header.ID =134; Header.Reliable = true; + NeedValidateIDs = false; AlertData = new AlertDataBlock(); AlertInfo = null; } @@ -23857,8 +24108,9 @@ public AgentAlertMessagePacket() Type = PacketType.AgentAlertMessage; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 135; + Header.ID =135; Header.Reliable = true; + NeedValidateIDs = false; AgentData = new AgentDataBlock(); AlertData = new AlertDataBlock(); } @@ -23985,8 +24237,9 @@ public MeanCollisionAlertPacket() Type = PacketType.MeanCollisionAlert; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 136; + Header.ID =136; Header.Reliable = true; + NeedValidateIDs = false; Header.Zerocoded = true; MeanCollision = null; } @@ -24163,8 +24416,9 @@ public ViewerFrozenMessagePacket() Type = PacketType.ViewerFrozenMessage; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 137; + Header.ID =137; Header.Reliable = true; + NeedValidateIDs = false; FrozenData = new FrozenDataBlock(); } @@ -24273,8 +24527,9 @@ public HealthMessagePacket() Type = PacketType.HealthMessage; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 138; + Header.ID =138; Header.Reliable = true; + NeedValidateIDs = false; Header.Zerocoded = true; HealthData = new HealthDataBlock(); } @@ -24415,8 +24670,9 @@ public ChatFromSimulatorPacket() Type = PacketType.ChatFromSimulator; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 139; + Header.ID =139; Header.Reliable = true; + NeedValidateIDs = false; ChatData = new ChatDataBlock(); } @@ -24659,8 +24915,9 @@ public SimStatsPacket() Type = PacketType.SimStats; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 140; + Header.ID =140; Header.Reliable = true; + NeedValidateIDs = false; Region = new RegionBlock(); Stat = null; PidStat = new PidStatBlock(); @@ -24813,14 +25070,17 @@ public override int Length } public AgentDataBlock AgentData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public RequestRegionInfoPacket() { HasVariableBlocks = false; Type = PacketType.RequestRegionInfo; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 141; + Header.ID =141; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); } @@ -25120,14 +25380,17 @@ public override int Length public RegionInfo2Block RegionInfo2; public RegionInfo3Block[] RegionInfo3; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public RegionInfoPacket() { HasVariableBlocks = true; Type = PacketType.RegionInfo; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 142; + Header.ID =142; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); RegionInfo = new RegionInfoBlock(); @@ -25430,14 +25693,17 @@ public override int Length public RegionInfoBlock RegionInfo; public RegionInfo2Block[] RegionInfo2; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public GodUpdateRegionInfoPacket() { HasVariableBlocks = true; Type = PacketType.GodUpdateRegionInfo; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 143; + Header.ID =143; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); RegionInfo = new RegionInfoBlock(); @@ -25853,8 +26119,9 @@ public RegionHandshakePacket() Type = PacketType.RegionHandshake; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 148; + Header.ID =148; Header.Reliable = true; + NeedValidateIDs = false; Header.Zerocoded = true; RegionInfo = new RegionInfoBlock(); RegionInfo2 = new RegionInfo2Block(); @@ -26089,14 +26356,17 @@ public override int Length public AgentDataBlock AgentData; public RegionInfoBlock RegionInfo; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public RegionHandshakeReplyPacket() { HasVariableBlocks = false; Type = PacketType.RegionHandshakeReply; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 149; + Header.ID =149; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); RegionInfo = new RegionInfoBlock(); @@ -26226,8 +26496,9 @@ public SimulatorViewerTimeMessagePacket() Type = PacketType.SimulatorViewerTimeMessage; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 150; + Header.ID =150; Header.Reliable = true; + NeedValidateIDs = false; TimeInfo = new TimeInfoBlock(); } @@ -26342,8 +26613,9 @@ public EnableSimulatorPacket() Type = PacketType.EnableSimulator; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 151; + Header.ID =151; Header.Reliable = true; + NeedValidateIDs = false; SimulatorInfo = new SimulatorInfoBlock(); } @@ -26412,8 +26684,9 @@ public DisableSimulatorPacket() Type = PacketType.DisableSimulator; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 152; + Header.ID =152; Header.Reliable = true; + NeedValidateIDs = false; } public DisableSimulatorPacket(byte[] bytes, ref int i) : this() @@ -26535,8 +26808,9 @@ public TransferRequestPacket() Type = PacketType.TransferRequest; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 153; + Header.ID =153; Header.Reliable = true; + NeedValidateIDs = false; Header.Zerocoded = true; TransferInfo = new TransferInfoBlock(); } @@ -26667,8 +26941,9 @@ public TransferInfoPacket() Type = PacketType.TransferInfo; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 154; + Header.ID =154; Header.Reliable = true; + NeedValidateIDs = false; Header.Zerocoded = true; TransferInfo = new TransferInfoBlock(); } @@ -26781,8 +27056,9 @@ public TransferAbortPacket() Type = PacketType.TransferAbort; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 155; + Header.ID =155; Header.Reliable = true; + NeedValidateIDs = false; Header.Zerocoded = true; TransferInfo = new TransferInfoBlock(); } @@ -26916,8 +27192,9 @@ public RequestXferPacket() Type = PacketType.RequestXfer; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 156; + Header.ID =156; Header.Reliable = true; + NeedValidateIDs = false; Header.Zerocoded = true; XferID = new XferIDBlock(); } @@ -27030,8 +27307,9 @@ public AbortXferPacket() Type = PacketType.AbortXfer; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 157; + Header.ID =157; Header.Reliable = true; + NeedValidateIDs = false; XferID = new XferIDBlock(); } @@ -27318,8 +27596,9 @@ public AvatarAppearancePacket() Type = PacketType.AvatarAppearance; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 158; + Header.ID =158; Header.Reliable = true; + NeedValidateIDs = false; Header.Zerocoded = true; Sender = new SenderBlock(); ObjectData = new ObjectDataBlock(); @@ -27632,8 +27911,9 @@ public SetFollowCamPropertiesPacket() Type = PacketType.SetFollowCamProperties; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 159; + Header.ID =159; Header.Reliable = true; + NeedValidateIDs = false; ObjectData = new ObjectDataBlock(); CameraProperty = null; } @@ -27816,8 +28096,9 @@ public ClearFollowCamPropertiesPacket() Type = PacketType.ClearFollowCamProperties; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 160; + Header.ID =160; Header.Reliable = true; + NeedValidateIDs = false; ObjectData = new ObjectDataBlock(); } @@ -27926,8 +28207,9 @@ public RequestPayPricePacket() Type = PacketType.RequestPayPrice; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 161; + Header.ID =161; Header.Reliable = true; + NeedValidateIDs = false; ObjectData = new ObjectDataBlock(); } @@ -28080,8 +28362,9 @@ public PayPriceReplyPacket() Type = PacketType.PayPriceReply; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 162; + Header.ID =162; Header.Reliable = true; + NeedValidateIDs = false; ObjectData = new ObjectDataBlock(); ButtonData = null; } @@ -28319,8 +28602,9 @@ public KickUserPacket() Type = PacketType.KickUser; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 163; + Header.ID =163; Header.Reliable = true; + NeedValidateIDs = false; TargetBlock = new TargetBlockBlock(); UserInfo = new UserInfoBlock(); } @@ -28452,8 +28736,9 @@ public GodKickUserPacket() Type = PacketType.GodKickUser; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 165; + Header.ID =165; Header.Reliable = true; + NeedValidateIDs = false; UserInfo = new UserInfoBlock(); } @@ -28602,14 +28887,17 @@ public override int Length public AgentDataBlock AgentData; public DataBlock Data; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public EjectUserPacket() { HasVariableBlocks = false; Type = PacketType.EjectUser; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 167; + Header.ID =167; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); Data = new DataBlock(); } @@ -28763,14 +29051,17 @@ public override int Length public AgentDataBlock AgentData; public DataBlock Data; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public FreezeUserPacket() { HasVariableBlocks = false; Type = PacketType.FreezeUser; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 168; + Header.ID =168; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); Data = new DataBlock(); } @@ -28884,14 +29175,17 @@ public override int Length } public AgentDataBlock AgentData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public AvatarPropertiesRequestPacket() { HasVariableBlocks = false; Type = PacketType.AvatarPropertiesRequest; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 169; + Header.ID =169; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); } @@ -29089,8 +29383,9 @@ public AvatarPropertiesReplyPacket() Type = PacketType.AvatarPropertiesReply; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 171; + Header.ID =171; Header.Reliable = true; + NeedValidateIDs = false; Header.Zerocoded = true; AgentData = new AgentDataBlock(); PropertiesData = new PropertiesDataBlock(); @@ -29274,8 +29569,9 @@ public AvatarInterestsReplyPacket() Type = PacketType.AvatarInterestsReply; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 172; + Header.ID =172; Header.Reliable = true; + NeedValidateIDs = false; Header.Zerocoded = true; AgentData = new AgentDataBlock(); PropertiesData = new PropertiesDataBlock(); @@ -29499,8 +29795,9 @@ public AvatarGroupsReplyPacket() Type = PacketType.AvatarGroupsReply; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 173; + Header.ID =173; Header.Reliable = true; + NeedValidateIDs = false; Header.Zerocoded = true; AgentData = new AgentDataBlock(); GroupData = null; @@ -29705,14 +30002,17 @@ public override int Length public AgentDataBlock AgentData; public PropertiesDataBlock PropertiesData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public AvatarPropertiesUpdatePacket() { HasVariableBlocks = false; Type = PacketType.AvatarPropertiesUpdate; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 174; + Header.ID =174; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); PropertiesData = new PropertiesDataBlock(); @@ -29890,14 +30190,17 @@ public override int Length public AgentDataBlock AgentData; public PropertiesDataBlock PropertiesData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public AvatarInterestsUpdatePacket() { HasVariableBlocks = false; Type = PacketType.AvatarInterestsUpdate; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 175; + Header.ID =175; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); PropertiesData = new PropertiesDataBlock(); @@ -30061,8 +30364,9 @@ public AvatarNotesReplyPacket() Type = PacketType.AvatarNotesReply; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 176; + Header.ID =176; Header.Reliable = true; + NeedValidateIDs = false; AgentData = new AgentDataBlock(); Data = new DataBlock(); } @@ -30222,14 +30526,17 @@ public override int Length public AgentDataBlock AgentData; public DataBlock Data; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public AvatarNotesUpdatePacket() { HasVariableBlocks = false; Type = PacketType.AvatarNotesUpdate; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 177; + Header.ID =177; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); Data = new DataBlock(); } @@ -30396,8 +30703,9 @@ public AvatarPicksReplyPacket() Type = PacketType.AvatarPicksReply; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 178; + Header.ID =178; Header.Reliable = true; + NeedValidateIDs = false; AgentData = new AgentDataBlock(); Data = null; } @@ -30617,14 +30925,17 @@ public override int Length public AgentDataBlock AgentData; public EventDataBlock EventData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public EventInfoRequestPacket() { HasVariableBlocks = false; Type = PacketType.EventInfoRequest; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 179; + Header.ID =179; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); EventData = new EventDataBlock(); } @@ -30840,8 +31151,9 @@ public EventInfoReplyPacket() Type = PacketType.EventInfoReply; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 180; + Header.ID =180; Header.Reliable = true; + NeedValidateIDs = false; AgentData = new AgentDataBlock(); EventData = new EventDataBlock(); } @@ -30992,14 +31304,17 @@ public override int Length public AgentDataBlock AgentData; public EventDataBlock EventData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public EventNotificationAddRequestPacket() { HasVariableBlocks = false; Type = PacketType.EventNotificationAddRequest; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 181; + Header.ID =181; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); EventData = new EventDataBlock(); } @@ -31150,14 +31465,17 @@ public override int Length public AgentDataBlock AgentData; public EventDataBlock EventData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public EventNotificationRemoveRequestPacket() { HasVariableBlocks = false; Type = PacketType.EventNotificationRemoveRequest; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 182; + Header.ID =182; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); EventData = new EventDataBlock(); } @@ -31363,14 +31681,17 @@ public override int Length public EventDataBlock EventData; public QueryDataBlock QueryData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public EventGodDeletePacket() { HasVariableBlocks = false; Type = PacketType.EventGodDelete; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 183; + Header.ID =183; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); EventData = new EventDataBlock(); QueryData = new QueryDataBlock(); @@ -31587,8 +31908,9 @@ public PickInfoReplyPacket() Type = PacketType.PickInfoReply; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 184; + Header.ID =184; Header.Reliable = true; + NeedValidateIDs = false; AgentData = new AgentDataBlock(); Data = new DataBlock(); } @@ -31776,14 +32098,17 @@ public override int Length public AgentDataBlock AgentData; public DataBlock Data; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public PickInfoUpdatePacket() { HasVariableBlocks = false; Type = PacketType.PickInfoUpdate; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 185; + Header.ID =185; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); Data = new DataBlock(); } @@ -31934,14 +32259,17 @@ public override int Length public AgentDataBlock AgentData; public DataBlock Data; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public PickDeletePacket() { HasVariableBlocks = false; Type = PacketType.PickDelete; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 186; + Header.ID =186; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); Data = new DataBlock(); } @@ -32095,14 +32423,17 @@ public override int Length public AgentDataBlock AgentData; public DataBlock Data; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public PickGodDeletePacket() { HasVariableBlocks = false; Type = PacketType.PickGodDelete; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 187; + Header.ID =187; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); Data = new DataBlock(); } @@ -32278,8 +32609,9 @@ public ScriptQuestionPacket() Type = PacketType.ScriptQuestion; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 188; + Header.ID =188; Header.Reliable = true; + NeedValidateIDs = false; Data = new DataBlock(); Experience = new ExperienceBlock(); } @@ -32400,8 +32732,9 @@ public ScriptControlChangePacket() Type = PacketType.ScriptControlChange; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 189; + Header.ID =189; Header.Reliable = true; + NeedValidateIDs = false; Data = null; } @@ -32701,8 +33034,9 @@ public ScriptDialogPacket() Type = PacketType.ScriptDialog; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 190; + Header.ID =190; Header.Reliable = true; + NeedValidateIDs = false; Header.Zerocoded = true; Data = new DataBlock(); Buttons = null; @@ -32977,14 +33311,17 @@ public override int Length public AgentDataBlock AgentData; public DataBlock Data; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public ScriptDialogReplyPacket() { HasVariableBlocks = false; Type = PacketType.ScriptDialogReply; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 191; + Header.ID =191; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); Data = new DataBlock(); @@ -33096,14 +33433,17 @@ public override int Length } public AgentDataBlock AgentData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public ForceScriptControlReleasePacket() { HasVariableBlocks = false; Type = PacketType.ForceScriptControlRelease; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 192; + Header.ID =192; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); } @@ -33252,14 +33592,17 @@ public override int Length public AgentDataBlock AgentData; public DataBlock Data; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public RevokePermissionsPacket() { HasVariableBlocks = false; Type = PacketType.RevokePermissions; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 193; + Header.ID =193; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); Data = new DataBlock(); } @@ -33402,8 +33745,9 @@ public LoadURLPacket() Type = PacketType.LoadURL; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 194; + Header.ID =194; Header.Reliable = true; + NeedValidateIDs = false; Data = new DataBlock(); } @@ -33531,8 +33875,9 @@ public ScriptTeleportRequestPacket() Type = PacketType.ScriptTeleportRequest; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 195; + Header.ID =195; Header.Reliable = true; + NeedValidateIDs = false; Data = new DataBlock(); } @@ -33650,8 +33995,9 @@ public ParcelOverlayPacket() Type = PacketType.ParcelOverlay; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 196; + Header.ID =196; Header.Reliable = true; + NeedValidateIDs = false; Header.Zerocoded = true; ParcelData = new ParcelDataBlock(); } @@ -33801,14 +34147,17 @@ public override int Length public AgentDataBlock AgentData; public ParcelDataBlock ParcelData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public ParcelPropertiesRequestByIDPacket() { HasVariableBlocks = false; Type = PacketType.ParcelPropertiesRequestByID; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 197; + Header.ID =197; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); ParcelData = new ParcelDataBlock(); @@ -34032,14 +34381,17 @@ public override int Length public AgentDataBlock AgentData; public ParcelDataBlock ParcelData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public ParcelPropertiesUpdatePacket() { HasVariableBlocks = false; Type = PacketType.ParcelPropertiesUpdate; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 198; + Header.ID =198; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); ParcelData = new ParcelDataBlock(); @@ -34276,14 +34628,17 @@ public override int Length public TaskIDsBlock[] TaskIDs; public OwnerIDsBlock[] OwnerIDs; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public ParcelReturnObjectsPacket() { HasVariableBlocks = true; Type = PacketType.ParcelReturnObjects; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 199; + Header.ID =199; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); ParcelData = new ParcelDataBlock(); @@ -34553,14 +34908,17 @@ public override int Length public AgentDataBlock AgentData; public ParcelDataBlock ParcelData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public ParcelSetOtherCleanTimePacket() { HasVariableBlocks = false; Type = PacketType.ParcelSetOtherCleanTime; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 200; + Header.ID =200; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); ParcelData = new ParcelDataBlock(); @@ -34797,14 +35155,17 @@ public override int Length public TaskIDsBlock[] TaskIDs; public OwnerIDsBlock[] OwnerIDs; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public ParcelDisableObjectsPacket() { HasVariableBlocks = true; Type = PacketType.ParcelDisableObjects; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 201; + Header.ID =201; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); ParcelData = new ParcelDataBlock(); @@ -35115,14 +35476,17 @@ public override int Length public ParcelDataBlock ParcelData; public ReturnIDsBlock[] ReturnIDs; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public ParcelSelectObjectsPacket() { HasVariableBlocks = true; Type = PacketType.ParcelSelectObjects; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 202; + Header.ID =202; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); ParcelData = new ParcelDataBlock(); @@ -35310,14 +35674,17 @@ public override int Length } public AgentDataBlock AgentData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public EstateCovenantRequestPacket() { HasVariableBlocks = false; Type = PacketType.EstateCovenantRequest; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 203; + Header.ID =203; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); } @@ -35441,8 +35808,9 @@ public EstateCovenantReplyPacket() Type = PacketType.EstateCovenantReply; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 204; + Header.ID =204; Header.Reliable = true; + NeedValidateIDs = false; Data = new DataBlock(); } @@ -35592,8 +35960,9 @@ public ForceObjectSelectPacket() Type = PacketType.ForceObjectSelect; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 205; + Header.ID =205; Header.Reliable = true; + NeedValidateIDs = false; _Header = new HeaderBlock(); Data = null; } @@ -35813,14 +36182,17 @@ public override int Length public AgentDataBlock AgentData; public ParcelDataBlock ParcelData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public ParcelBuyPassPacket() { HasVariableBlocks = false; Type = PacketType.ParcelBuyPass; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 206; + Header.ID =206; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); ParcelData = new ParcelDataBlock(); } @@ -35974,14 +36346,17 @@ public override int Length public AgentDataBlock AgentData; public DataBlock Data; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public ParcelDeedToGroupPacket() { HasVariableBlocks = false; Type = PacketType.ParcelDeedToGroup; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 207; + Header.ID =207; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); Data = new DataBlock(); } @@ -36132,14 +36507,17 @@ public override int Length public AgentDataBlock AgentData; public DataBlock Data; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public ParcelReclaimPacket() { HasVariableBlocks = false; Type = PacketType.ParcelReclaim; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 208; + Header.ID =208; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); Data = new DataBlock(); } @@ -36346,14 +36724,17 @@ public override int Length public DataBlock Data; public ParcelDataBlock[] ParcelData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public ParcelClaimPacket() { HasVariableBlocks = true; Type = PacketType.ParcelClaim; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 209; + Header.ID =209; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); Data = new DataBlock(); @@ -36590,14 +36971,17 @@ public override int Length public AgentDataBlock AgentData; public ParcelDataBlock ParcelData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public ParcelJoinPacket() { HasVariableBlocks = false; Type = PacketType.ParcelJoin; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 210; + Header.ID =210; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); ParcelData = new ParcelDataBlock(); } @@ -36757,14 +37141,17 @@ public override int Length public AgentDataBlock AgentData; public ParcelDataBlock ParcelData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public ParcelDividePacket() { HasVariableBlocks = false; Type = PacketType.ParcelDivide; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 211; + Header.ID =211; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); ParcelData = new ParcelDataBlock(); } @@ -36915,14 +37302,17 @@ public override int Length public AgentDataBlock AgentData; public DataBlock Data; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public ParcelReleasePacket() { HasVariableBlocks = false; Type = PacketType.ParcelRelease; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 212; + Header.ID =212; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); Data = new DataBlock(); } @@ -37128,14 +37518,17 @@ public override int Length public DataBlock Data; public ParcelDataBlock ParcelData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public ParcelBuyPacket() { HasVariableBlocks = false; Type = PacketType.ParcelBuy; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 213; + Header.ID =213; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); Data = new DataBlock(); @@ -37295,14 +37688,17 @@ public override int Length public AgentDataBlock AgentData; public DataBlock Data; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public ParcelGodForceOwnerPacket() { HasVariableBlocks = false; Type = PacketType.ParcelGodForceOwner; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 214; + Header.ID =214; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); Data = new DataBlock(); @@ -37460,14 +37856,17 @@ public override int Length public AgentDataBlock AgentData; public DataBlock Data; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public ParcelAccessListRequestPacket() { HasVariableBlocks = false; Type = PacketType.ParcelAccessListRequest; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 215; + Header.ID =215; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); Data = new DataBlock(); @@ -37638,8 +38037,9 @@ public ParcelAccessListReplyPacket() Type = PacketType.ParcelAccessListReply; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 216; + Header.ID =216; Header.Reliable = true; + NeedValidateIDs = false; Header.Zerocoded = true; Data = new DataBlock(); List = null; @@ -37919,14 +38319,17 @@ public override int Length public DataBlock Data; public ListBlock[] List; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public ParcelAccessListUpdatePacket() { HasVariableBlocks = true; Type = PacketType.ParcelAccessListUpdate; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 217; + Header.ID =217; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); Data = new DataBlock(); @@ -38157,14 +38560,17 @@ public override int Length public AgentDataBlock AgentData; public DataBlock Data; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public ParcelDwellRequestPacket() { HasVariableBlocks = false; Type = PacketType.ParcelDwellRequest; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 218; + Header.ID =218; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); Data = new DataBlock(); } @@ -38324,8 +38730,9 @@ public ParcelDwellReplyPacket() Type = PacketType.ParcelDwellReply; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 219; + Header.ID =219; Header.Reliable = true; + NeedValidateIDs = false; AgentData = new AgentDataBlock(); Data = new DataBlock(); } @@ -38476,14 +38883,17 @@ public override int Length public AgentDataBlock AgentData; public ParcelDataBlock ParcelData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public ParcelGodMarkAsContentPacket() { HasVariableBlocks = false; Type = PacketType.ParcelGodMarkAsContent; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 227; + Header.ID =227; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); ParcelData = new ParcelDataBlock(); } @@ -38637,14 +39047,17 @@ public override int Length public AgentDataBlock AgentData; public ParcelDataBlock ParcelData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public ViewerStartAuctionPacket() { HasVariableBlocks = false; Type = PacketType.ViewerStartAuction; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 228; + Header.ID =228; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); ParcelData = new ParcelDataBlock(); } @@ -38759,8 +39172,9 @@ public UUIDNameRequestPacket() Type = PacketType.UUIDNameRequest; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 235; + Header.ID =235; Header.Reliable = true; + NeedValidateIDs = false; UUIDNameBlock = null; } @@ -38953,8 +39367,9 @@ public UUIDNameReplyPacket() Type = PacketType.UUIDNameReply; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 236; + Header.ID =236; Header.Reliable = true; + NeedValidateIDs = false; UUIDNameBlock = null; } @@ -39131,8 +39546,9 @@ public UUIDGroupNameRequestPacket() Type = PacketType.UUIDGroupNameRequest; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 237; + Header.ID =237; Header.Reliable = true; + NeedValidateIDs = false; UUIDNameBlock = null; } @@ -39318,8 +39734,9 @@ public UUIDGroupNameReplyPacket() Type = PacketType.UUIDGroupNameReply; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 238; + Header.ID =238; Header.Reliable = true; + NeedValidateIDs = false; UUIDNameBlock = null; } @@ -39492,14 +39909,17 @@ public override int Length } public AgentDataBlock AgentData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public ChildAgentDyingPacket() { HasVariableBlocks = false; Type = PacketType.ChildAgentDying; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 240; + Header.ID =240; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); } @@ -39606,14 +40026,17 @@ public override int Length } public AgentDataBlock AgentData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public ChildAgentUnknownPacket() { HasVariableBlocks = false; Type = PacketType.ChildAgentUnknown; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 241; + Header.ID =241; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); } @@ -39725,8 +40148,9 @@ public GetScriptRunningPacket() Type = PacketType.GetScriptRunning; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 243; + Header.ID =243; Header.Reliable = true; + NeedValidateIDs = false; Script = new ScriptBlock(); } @@ -39841,8 +40265,9 @@ public ScriptRunningReplyPacket() Type = PacketType.ScriptRunningReply; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 244; + Header.ID =244; Header.Reliable = true; + NeedValidateIDs = false; Script = new ScriptBlock(); } @@ -39994,14 +40419,17 @@ public override int Length public AgentDataBlock AgentData; public ScriptBlock Script; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public SetScriptRunningPacket() { HasVariableBlocks = false; Type = PacketType.SetScriptRunning; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 245; + Header.ID =245; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); Script = new ScriptBlock(); } @@ -40155,14 +40583,17 @@ public override int Length public AgentDataBlock AgentData; public ScriptBlock Script; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public ScriptResetPacket() { HasVariableBlocks = false; Type = PacketType.ScriptReset; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 246; + Header.ID =246; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); Script = new ScriptBlock(); } @@ -40312,8 +40743,9 @@ public ScriptSensorRequestPacket() Type = PacketType.ScriptSensorRequest; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 247; + Header.ID =247; Header.Reliable = true; + NeedValidateIDs = false; Header.Zerocoded = true; Requester = new RequesterBlock(); } @@ -40494,8 +40926,9 @@ public ScriptSensorReplyPacket() Type = PacketType.ScriptSensorReply; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 248; + Header.ID =248; Header.Reliable = true; + NeedValidateIDs = false; Header.Zerocoded = true; Requester = new RequesterBlock(); SensedData = null; @@ -40679,14 +41112,17 @@ public override int Length } public AgentDataBlock AgentData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public CompleteAgentMovementPacket() { HasVariableBlocks = false; Type = PacketType.CompleteAgentMovement; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 249; + Header.ID =249; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); } @@ -40887,14 +41323,17 @@ public override int Length public DataBlock Data; public SimDataBlock SimData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public AgentMovementCompletePacket() { HasVariableBlocks = false; Type = PacketType.AgentMovementComplete; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 250; + Header.ID =250; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); Data = new DataBlock(); SimData = new SimDataBlock(); @@ -41010,14 +41449,17 @@ public override int Length } public AgentDataBlock AgentData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public LogoutRequestPacket() { HasVariableBlocks = false; Type = PacketType.LogoutRequest; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 252; + Header.ID =252; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); } @@ -41164,14 +41606,17 @@ public override int Length public AgentDataBlock AgentData; public InventoryDataBlock[] InventoryData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public LogoutReplyPacket() { HasVariableBlocks = true; Type = PacketType.LogoutReply; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 253; + Header.ID =253; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); InventoryData = null; @@ -41439,14 +41884,17 @@ public override int Length public AgentDataBlock AgentData; public MessageBlockBlock MessageBlock; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public ImprovedInstantMessagePacket() { HasVariableBlocks = false; Type = PacketType.ImprovedInstantMessage; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 254; + Header.ID =254; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); MessageBlock = new MessageBlockBlock(); @@ -41558,14 +42006,17 @@ public override int Length } public AgentDataBlock AgentData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public RetrieveInstantMessagesPacket() { HasVariableBlocks = false; Type = PacketType.RetrieveInstantMessages; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 255; + Header.ID =255; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); } @@ -41724,8 +42175,9 @@ public FindAgentPacket() Type = PacketType.FindAgent; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 256; + Header.ID =256; Header.Reliable = true; + NeedValidateIDs = false; AgentBlock = new AgentBlockBlock(); LocationBlock = null; } @@ -41948,14 +42400,17 @@ public override int Length public AgentDataBlock AgentData; public RequestBlockBlock RequestBlock; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public RequestGodlikePowersPacket() { HasVariableBlocks = false; Type = PacketType.RequestGodlikePowers; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 257; + Header.ID =257; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); RequestBlock = new RequestBlockBlock(); } @@ -42109,14 +42564,17 @@ public override int Length public AgentDataBlock AgentData; public GrantDataBlock GrantData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public GrantGodlikePowersPacket() { HasVariableBlocks = false; Type = PacketType.GrantGodlikePowers; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 258; + Header.ID =258; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); GrantData = new GrantDataBlock(); } @@ -42326,14 +42784,17 @@ public override int Length public MethodDataBlock MethodData; public ParamListBlock[] ParamList; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public GodlikeMessagePacket() { HasVariableBlocks = true; Type = PacketType.GodlikeMessage; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 259; + Header.ID =259; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); MethodData = new MethodDataBlock(); @@ -42620,14 +43081,17 @@ public override int Length public MethodDataBlock MethodData; public ParamListBlock[] ParamList; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public EstateOwnerMessagePacket() { HasVariableBlocks = true; Type = PacketType.EstateOwnerMessage; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 260; + Header.ID =260; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); MethodData = new MethodDataBlock(); @@ -42914,14 +43378,17 @@ public override int Length public MethodDataBlock MethodData; public ParamListBlock[] ParamList; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public GenericMessagePacket() { HasVariableBlocks = true; Type = PacketType.GenericMessage; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 261; + Header.ID =261; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); MethodData = new MethodDataBlock(); @@ -43149,14 +43616,17 @@ public override int Length public AgentDataBlock AgentData; public MuteDataBlock MuteData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public MuteListRequestPacket() { HasVariableBlocks = false; Type = PacketType.MuteListRequest; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 262; + Header.ID =262; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); MuteData = new MuteDataBlock(); } @@ -43322,14 +43792,17 @@ public override int Length public AgentDataBlock AgentData; public MuteDataBlock MuteData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public UpdateMuteListEntryPacket() { HasVariableBlocks = false; Type = PacketType.UpdateMuteListEntry; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 263; + Header.ID =263; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); MuteData = new MuteDataBlock(); } @@ -43489,14 +43962,17 @@ public override int Length public AgentDataBlock AgentData; public MuteDataBlock MuteData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public RemoveMuteListEntryPacket() { HasVariableBlocks = false; Type = PacketType.RemoveMuteListEntry; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 264; + Header.ID =264; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); MuteData = new MuteDataBlock(); } @@ -43694,14 +44170,17 @@ public override int Length public NotecardDataBlock NotecardData; public InventoryDataBlock[] InventoryData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public CopyInventoryFromNotecardPacket() { HasVariableBlocks = true; Type = PacketType.CopyInventoryFromNotecard; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 265; + Header.ID =265; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); NotecardData = new NotecardDataBlock(); @@ -44006,14 +44485,17 @@ public override int Length public AgentDataBlock AgentData; public InventoryDataBlock[] InventoryData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public UpdateInventoryItemPacket() { HasVariableBlocks = true; Type = PacketType.UpdateInventoryItem; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 266; + Header.ID =266; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); InventoryData = null; @@ -44317,8 +44799,9 @@ public UpdateCreateInventoryItemPacket() Type = PacketType.UpdateCreateInventoryItem; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 267; + Header.ID =267; Header.Reliable = true; + NeedValidateIDs = false; Header.Zerocoded = true; AgentData = new AgentDataBlock(); InventoryData = null; @@ -44555,14 +45038,17 @@ public override int Length public AgentDataBlock AgentData; public InventoryDataBlock[] InventoryData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public MoveInventoryItemPacket() { HasVariableBlocks = true; Type = PacketType.MoveInventoryItem; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 268; + Header.ID =268; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); InventoryData = null; @@ -44802,14 +45288,17 @@ public override int Length public AgentDataBlock AgentData; public InventoryDataBlock[] InventoryData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public CopyInventoryItemPacket() { HasVariableBlocks = true; Type = PacketType.CopyInventoryItem; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 269; + Header.ID =269; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); InventoryData = null; @@ -45031,14 +45520,17 @@ public override int Length public AgentDataBlock AgentData; public InventoryDataBlock[] InventoryData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public RemoveInventoryItemPacket() { HasVariableBlocks = true; Type = PacketType.RemoveInventoryItem; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 270; + Header.ID =270; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); InventoryData = null; } @@ -45262,14 +45754,17 @@ public override int Length public AgentDataBlock AgentData; public InventoryDataBlock[] InventoryData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public ChangeInventoryItemFlagsPacket() { HasVariableBlocks = true; Type = PacketType.ChangeInventoryItemFlags; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 271; + Header.ID =271; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); InventoryData = null; } @@ -45495,8 +45990,9 @@ public SaveAssetIntoInventoryPacket() Type = PacketType.SaveAssetIntoInventory; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 272; + Header.ID =272; Header.Reliable = true; + NeedValidateIDs = false; AgentData = new AgentDataBlock(); InventoryData = new InventoryDataBlock(); } @@ -45662,14 +46158,17 @@ public override int Length public AgentDataBlock AgentData; public FolderDataBlock FolderData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public CreateInventoryFolderPacket() { HasVariableBlocks = false; Type = PacketType.CreateInventoryFolder; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 273; + Header.ID =273; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); FolderData = new FolderDataBlock(); } @@ -45836,14 +46335,17 @@ public override int Length public AgentDataBlock AgentData; public FolderDataBlock[] FolderData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public UpdateInventoryFolderPacket() { HasVariableBlocks = true; Type = PacketType.UpdateInventoryFolder; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 274; + Header.ID =274; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); FolderData = null; } @@ -46070,14 +46572,17 @@ public override int Length public AgentDataBlock AgentData; public InventoryDataBlock[] InventoryData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public MoveInventoryFolderPacket() { HasVariableBlocks = true; Type = PacketType.MoveInventoryFolder; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 275; + Header.ID =275; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); InventoryData = null; @@ -46299,14 +46804,17 @@ public override int Length public AgentDataBlock AgentData; public FolderDataBlock[] FolderData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public RemoveInventoryFolderPacket() { HasVariableBlocks = true; Type = PacketType.RemoveInventoryFolder; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 276; + Header.ID =276; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); FolderData = null; } @@ -46538,14 +47046,17 @@ public override int Length public AgentDataBlock AgentData; public InventoryDataBlock InventoryData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public FetchInventoryDescendentsPacket() { HasVariableBlocks = false; Type = PacketType.FetchInventoryDescendents; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 277; + Header.ID =277; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); InventoryData = new InventoryDataBlock(); @@ -46839,8 +47350,9 @@ public InventoryDescendentsPacket() Type = PacketType.InventoryDescendents; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 278; + Header.ID =278; Header.Reliable = true; + NeedValidateIDs = false; Header.Zerocoded = true; AgentData = new AgentDataBlock(); FolderData = null; @@ -47104,14 +47616,17 @@ public override int Length public AgentDataBlock AgentData; public InventoryDataBlock[] InventoryData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public FetchInventoryPacket() { HasVariableBlocks = true; Type = PacketType.FetchInventory; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 279; + Header.ID =279; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); InventoryData = null; @@ -47406,8 +47921,9 @@ public FetchInventoryReplyPacket() Type = PacketType.FetchInventoryReply; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 280; + Header.ID =280; Header.Reliable = true; + NeedValidateIDs = false; Header.Zerocoded = true; AgentData = new AgentDataBlock(); InventoryData = null; @@ -47764,8 +48280,9 @@ public BulkUpdateInventoryPacket() Type = PacketType.BulkUpdateInventory; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 281; + Header.ID =281; Header.Reliable = true; + NeedValidateIDs = false; Header.Zerocoded = true; AgentData = new AgentDataBlock(); FolderData = null; @@ -48067,14 +48584,17 @@ public override int Length public FolderDataBlock[] FolderData; public ItemDataBlock[] ItemData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public RemoveInventoryObjectsPacket() { HasVariableBlocks = true; Type = PacketType.RemoveInventoryObjects; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 284; + Header.ID =284; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); FolderData = null; ItemData = null; @@ -48333,14 +48853,17 @@ public override int Length public AgentDataBlock AgentData; public InventoryDataBlock InventoryData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public PurgeInventoryDescendentsPacket() { HasVariableBlocks = false; Type = PacketType.PurgeInventoryDescendents; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 285; + Header.ID =285; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); InventoryData = new InventoryDataBlock(); @@ -48605,14 +49128,17 @@ public override int Length public UpdateDataBlock UpdateData; public InventoryDataBlock InventoryData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public UpdateTaskInventoryPacket() { HasVariableBlocks = false; Type = PacketType.UpdateTaskInventory; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 286; + Header.ID =286; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); UpdateData = new UpdateDataBlock(); @@ -48772,14 +49298,17 @@ public override int Length public AgentDataBlock AgentData; public InventoryDataBlock InventoryData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public RemoveTaskInventoryPacket() { HasVariableBlocks = false; Type = PacketType.RemoveTaskInventory; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 287; + Header.ID =287; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); InventoryData = new InventoryDataBlock(); @@ -48937,14 +49466,17 @@ public override int Length public AgentDataBlock AgentData; public InventoryDataBlock InventoryData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public MoveTaskInventoryPacket() { HasVariableBlocks = false; Type = PacketType.MoveTaskInventory; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 288; + Header.ID =288; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); InventoryData = new InventoryDataBlock(); } @@ -49095,14 +49627,17 @@ public override int Length public AgentDataBlock AgentData; public InventoryDataBlock InventoryData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public RequestTaskInventoryPacket() { HasVariableBlocks = false; Type = PacketType.RequestTaskInventory; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 289; + Header.ID =289; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); InventoryData = new InventoryDataBlock(); } @@ -49228,8 +49763,9 @@ public ReplyTaskInventoryPacket() Type = PacketType.ReplyTaskInventory; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 290; + Header.ID =290; Header.Reliable = true; + NeedValidateIDs = false; Header.Zerocoded = true; InventoryData = new InventoryDataBlock(); } @@ -49432,14 +49968,17 @@ public override int Length public AgentBlockBlock AgentBlock; public ObjectDataBlock[] ObjectData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public DeRezObjectPacket() { HasVariableBlocks = true; Type = PacketType.DeRezObject; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 291; + Header.ID =291; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); AgentBlock = new AgentBlockBlock(); @@ -49633,8 +50172,9 @@ public DeRezAckPacket() Type = PacketType.DeRezAck; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 292; + Header.ID =292; Header.Reliable = true; + NeedValidateIDs = false; TransactionData = new TransactionDataBlock(); } @@ -49926,14 +50466,17 @@ public override int Length public RezDataBlock RezData; public InventoryDataBlock InventoryData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public RezObjectPacket() { HasVariableBlocks = false; Type = PacketType.RezObject; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 293; + Header.ID =293; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); RezData = new RezDataBlock(); @@ -50210,14 +50753,17 @@ public override int Length public NotecardDataBlock NotecardData; public InventoryDataBlock[] InventoryData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public RezObjectFromNotecardPacket() { HasVariableBlocks = true; Type = PacketType.RezObjectFromNotecard; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 294; + Header.ID =294; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); RezData = new RezDataBlock(); @@ -50493,14 +51039,17 @@ public override int Length public TransactionBlockBlock TransactionBlock; public FolderDataBlock[] FolderData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public AcceptFriendshipPacket() { HasVariableBlocks = true; Type = PacketType.AcceptFriendship; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 297; + Header.ID =297; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); TransactionBlock = new TransactionBlockBlock(); FolderData = null; @@ -50727,14 +51276,17 @@ public override int Length public AgentDataBlock AgentData; public TransactionBlockBlock TransactionBlock; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public DeclineFriendshipPacket() { HasVariableBlocks = false; Type = PacketType.DeclineFriendship; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 298; + Header.ID =298; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); TransactionBlock = new TransactionBlockBlock(); } @@ -50885,14 +51437,17 @@ public override int Length public AgentDataBlock AgentData; public ExBlockBlock ExBlock; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public TerminateFriendshipPacket() { HasVariableBlocks = false; Type = PacketType.TerminateFriendship; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 300; + Header.ID =300; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); ExBlock = new ExBlockBlock(); } @@ -51046,14 +51601,17 @@ public override int Length public AgentDataBlock AgentData; public AgentBlockBlock AgentBlock; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public OfferCallingCardPacket() { HasVariableBlocks = false; Type = PacketType.OfferCallingCard; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 301; + Header.ID =301; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); AgentBlock = new AgentBlockBlock(); } @@ -51245,14 +51803,17 @@ public override int Length public TransactionBlockBlock TransactionBlock; public FolderDataBlock[] FolderData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public AcceptCallingCardPacket() { HasVariableBlocks = true; Type = PacketType.AcceptCallingCard; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 302; + Header.ID =302; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); TransactionBlock = new TransactionBlockBlock(); FolderData = null; @@ -51479,14 +52040,17 @@ public override int Length public AgentDataBlock AgentData; public TransactionBlockBlock TransactionBlock; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public DeclineCallingCardPacket() { HasVariableBlocks = false; Type = PacketType.DeclineCallingCard; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 303; + Header.ID =303; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); TransactionBlock = new TransactionBlockBlock(); } @@ -51753,14 +52317,17 @@ public override int Length public UpdateBlockBlock UpdateBlock; public InventoryBlockBlock InventoryBlock; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public RezScriptPacket() { HasVariableBlocks = false; Type = PacketType.RezScript; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 304; + Header.ID =304; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); UpdateBlock = new UpdateBlockBlock(); @@ -51951,14 +52518,17 @@ public override int Length public AgentDataBlock AgentData; public InventoryBlockBlock InventoryBlock; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public CreateInventoryItemPacket() { HasVariableBlocks = false; Type = PacketType.CreateInventoryItem; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 305; + Header.ID =305; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); InventoryBlock = new InventoryBlockBlock(); @@ -52159,14 +52729,17 @@ public override int Length public EventDataBlock EventData; public InventoryBlockBlock InventoryBlock; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public CreateLandmarkForEventPacket() { HasVariableBlocks = false; Type = PacketType.CreateLandmarkForEvent; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 306; + Header.ID =306; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); EventData = new EventDataBlock(); @@ -52286,8 +52859,9 @@ public RegionHandleRequestPacket() Type = PacketType.RegionHandleRequest; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 309; + Header.ID =309; Header.Reliable = true; + NeedValidateIDs = false; RequestBlock = new RequestBlockBlock(); } @@ -52399,8 +52973,9 @@ public RegionIDAndHandleReplyPacket() Type = PacketType.RegionIDAndHandleReply; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 310; + Header.ID =310; Header.Reliable = true; + NeedValidateIDs = false; ReplyBlock = new ReplyBlockBlock(); } @@ -52573,14 +53148,17 @@ public override int Length public AgentDataBlock AgentData; public MoneyDataBlock MoneyData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public MoneyTransferRequestPacket() { HasVariableBlocks = false; Type = PacketType.MoneyTransferRequest; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 311; + Header.ID =311; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); MoneyData = new MoneyDataBlock(); @@ -52732,14 +53310,17 @@ public override int Length public AgentDataBlock AgentData; public MoneyDataBlock MoneyData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public MoneyBalanceRequestPacket() { HasVariableBlocks = false; Type = PacketType.MoneyBalanceRequest; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 313; + Header.ID =313; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); MoneyData = new MoneyDataBlock(); @@ -52942,8 +53523,9 @@ public MoneyBalanceReplyPacket() Type = PacketType.MoneyBalanceReply; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 314; + Header.ID =314; Header.Reliable = true; + NeedValidateIDs = false; Header.Zerocoded = true; MoneyData = new MoneyDataBlock(); TransactionInfo = new TransactionInfoBlock(); @@ -53189,8 +53771,9 @@ public RoutedMoneyBalanceReplyPacket() Type = PacketType.RoutedMoneyBalanceReply; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 315; + Header.ID =315; Header.Reliable = true; + NeedValidateIDs = false; Header.Zerocoded = true; TargetBlock = new TargetBlockBlock(); MoneyData = new MoneyDataBlock(); @@ -53357,14 +53940,17 @@ public override int Length public AgentDataBlock AgentData; public DataBlock[] Data; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public ActivateGesturesPacket() { HasVariableBlocks = true; Type = PacketType.ActivateGestures; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 316; + Header.ID =316; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); Data = null; } @@ -53591,14 +54177,17 @@ public override int Length public AgentDataBlock AgentData; public DataBlock[] Data; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public DeactivateGesturesPacket() { HasVariableBlocks = true; Type = PacketType.DeactivateGestures; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 317; + Header.ID =317; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); Data = null; } @@ -53790,8 +54379,9 @@ public MuteListUpdatePacket() Type = PacketType.MuteListUpdate; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 318; + Header.ID =318; Header.Reliable = true; + NeedValidateIDs = false; MuteData = new MuteDataBlock(); } @@ -53900,8 +54490,9 @@ public UseCachedMuteListPacket() Type = PacketType.UseCachedMuteList; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 319; + Header.ID =319; Header.Reliable = true; + NeedValidateIDs = false; AgentData = new AgentDataBlock(); } @@ -54051,14 +54642,17 @@ public override int Length public AgentDataBlock AgentData; public RightsBlock[] Rights; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public GrantUserRightsPacket() { HasVariableBlocks = true; Type = PacketType.GrantUserRights; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 320; + Header.ID =320; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); Rights = null; } @@ -54285,8 +54879,9 @@ public ChangeUserRightsPacket() Type = PacketType.ChangeUserRights; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 321; + Header.ID =321; Header.Reliable = true; + NeedValidateIDs = false; AgentData = new AgentDataBlock(); Rights = null; } @@ -54470,8 +55065,9 @@ public OnlineNotificationPacket() Type = PacketType.OnlineNotification; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 322; + Header.ID =322; Header.Reliable = true; + NeedValidateIDs = false; AgentBlock = null; } @@ -54648,8 +55244,9 @@ public OfflineNotificationPacket() Type = PacketType.OfflineNotification; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 323; + Header.ID =323; Header.Reliable = true; + NeedValidateIDs = false; AgentBlock = null; } @@ -54877,14 +55474,17 @@ public override int Length public AgentDataBlock AgentData; public StartLocationDataBlock StartLocationData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public SetStartLocationRequestPacket() { HasVariableBlocks = false; Type = PacketType.SetStartLocationRequest; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 324; + Header.ID =324; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); StartLocationData = new StartLocationDataBlock(); @@ -55017,8 +55617,9 @@ public AssetUploadRequestPacket() Type = PacketType.AssetUploadRequest; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 333; + Header.ID =333; Header.Reliable = true; + NeedValidateIDs = false; AssetBlock = new AssetBlockBlock(); } @@ -55133,8 +55734,9 @@ public AssetUploadCompletePacket() Type = PacketType.AssetUploadComplete; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 334; + Header.ID =334; Header.Reliable = true; + NeedValidateIDs = false; AssetBlock = new AssetBlockBlock(); } @@ -55311,14 +55913,17 @@ public override int Length public AgentDataBlock AgentData; public GroupDataBlock GroupData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public CreateGroupRequestPacket() { HasVariableBlocks = false; Type = PacketType.CreateGroupRequest; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 339; + Header.ID =339; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); GroupData = new GroupDataBlock(); @@ -55485,8 +56090,9 @@ public CreateGroupReplyPacket() Type = PacketType.CreateGroupReply; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 340; + Header.ID =340; Header.Reliable = true; + NeedValidateIDs = false; AgentData = new AgentDataBlock(); ReplyData = new ReplyDataBlock(); } @@ -55664,14 +56270,17 @@ public override int Length public AgentDataBlock AgentData; public GroupDataBlock GroupData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public UpdateGroupInfoPacket() { HasVariableBlocks = false; Type = PacketType.UpdateGroupInfo; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 341; + Header.ID =341; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); GroupData = new GroupDataBlock(); @@ -55833,14 +56442,17 @@ public override int Length public AgentDataBlock AgentData; public RoleChangeBlock[] RoleChange; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public GroupRoleChangesPacket() { HasVariableBlocks = true; Type = PacketType.GroupRoleChanges; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 342; + Header.ID =342; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); RoleChange = null; } @@ -56060,14 +56672,17 @@ public override int Length public AgentDataBlock AgentData; public GroupDataBlock GroupData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public JoinGroupRequestPacket() { HasVariableBlocks = false; Type = PacketType.JoinGroupRequest; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 343; + Header.ID =343; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); GroupData = new GroupDataBlock(); @@ -56225,8 +56840,9 @@ public JoinGroupReplyPacket() Type = PacketType.JoinGroupReply; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 344; + Header.ID =344; Header.Reliable = true; + NeedValidateIDs = false; AgentData = new AgentDataBlock(); GroupData = new GroupDataBlock(); } @@ -56418,14 +57034,17 @@ public override int Length public GroupDataBlock GroupData; public EjectDataBlock[] EjectData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public EjectGroupMemberRequestPacket() { HasVariableBlocks = true; Type = PacketType.EjectGroupMemberRequest; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 345; + Header.ID =345; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); GroupData = new GroupDataBlock(); EjectData = null; @@ -56695,8 +57314,9 @@ public EjectGroupMemberReplyPacket() Type = PacketType.EjectGroupMemberReply; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 346; + Header.ID =346; Header.Reliable = true; + NeedValidateIDs = false; AgentData = new AgentDataBlock(); GroupData = new GroupDataBlock(); EjectData = new EjectDataBlock(); @@ -56852,14 +57472,17 @@ public override int Length public AgentDataBlock AgentData; public GroupDataBlock GroupData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public LeaveGroupRequestPacket() { HasVariableBlocks = false; Type = PacketType.LeaveGroupRequest; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 347; + Header.ID =347; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); GroupData = new GroupDataBlock(); } @@ -57016,8 +57639,9 @@ public LeaveGroupReplyPacket() Type = PacketType.LeaveGroupReply; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 348; + Header.ID =348; Header.Reliable = true; + NeedValidateIDs = false; AgentData = new AgentDataBlock(); GroupData = new GroupDataBlock(); } @@ -57212,14 +57836,17 @@ public override int Length public GroupDataBlock GroupData; public InviteDataBlock[] InviteData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public InviteGroupRequestPacket() { HasVariableBlocks = true; Type = PacketType.InviteGroupRequest; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 349; + Header.ID =349; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); GroupData = new GroupDataBlock(); InviteData = null; @@ -57446,14 +58073,17 @@ public override int Length public AgentDataBlock AgentData; public GroupDataBlock GroupData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public GroupProfileRequestPacket() { HasVariableBlocks = false; Type = PacketType.GroupProfileRequest; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 351; + Header.ID =351; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); GroupData = new GroupDataBlock(); } @@ -57666,8 +58296,9 @@ public GroupProfileReplyPacket() Type = PacketType.GroupProfileReply; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 352; + Header.ID =352; Header.Reliable = true; + NeedValidateIDs = false; Header.Zerocoded = true; AgentData = new AgentDataBlock(); GroupData = new GroupDataBlock(); @@ -57828,14 +58459,17 @@ public override int Length public AgentDataBlock AgentData; public MoneyDataBlock MoneyData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public GroupAccountSummaryRequestPacket() { HasVariableBlocks = false; Type = PacketType.GroupAccountSummaryRequest; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 353; + Header.ID =353; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); MoneyData = new MoneyDataBlock(); @@ -58064,8 +58698,9 @@ public GroupAccountSummaryReplyPacket() Type = PacketType.GroupAccountSummaryReply; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 354; + Header.ID =354; Header.Reliable = true; + NeedValidateIDs = false; Header.Zerocoded = true; AgentData = new AgentDataBlock(); MoneyData = new MoneyDataBlock(); @@ -58226,14 +58861,17 @@ public override int Length public AgentDataBlock AgentData; public MoneyDataBlock MoneyData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public GroupAccountDetailsRequestPacket() { HasVariableBlocks = false; Type = PacketType.GroupAccountDetailsRequest; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 355; + Header.ID =355; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); MoneyData = new MoneyDataBlock(); @@ -58456,8 +59094,9 @@ public GroupAccountDetailsReplyPacket() Type = PacketType.GroupAccountDetailsReply; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 356; + Header.ID =356; Header.Reliable = true; + NeedValidateIDs = false; Header.Zerocoded = true; AgentData = new AgentDataBlock(); MoneyData = new MoneyDataBlock(); @@ -58694,14 +59333,17 @@ public override int Length public AgentDataBlock AgentData; public MoneyDataBlock MoneyData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public GroupAccountTransactionsRequestPacket() { HasVariableBlocks = false; Type = PacketType.GroupAccountTransactionsRequest; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 357; + Header.ID =357; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); MoneyData = new MoneyDataBlock(); @@ -58941,8 +59583,9 @@ public GroupAccountTransactionsReplyPacket() Type = PacketType.GroupAccountTransactionsReply; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 358; + Header.ID =358; Header.Reliable = true; + NeedValidateIDs = false; Header.Zerocoded = true; AgentData = new AgentDataBlock(); MoneyData = new MoneyDataBlock(); @@ -59210,14 +59853,17 @@ public override int Length public GroupDataBlock GroupData; public TransactionDataBlock TransactionData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public GroupActiveProposalsRequestPacket() { HasVariableBlocks = false; Type = PacketType.GroupActiveProposalsRequest; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 359; + Header.ID =359; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); GroupData = new GroupDataBlock(); TransactionData = new TransactionDataBlock(); @@ -59472,8 +60118,9 @@ public GroupActiveProposalItemReplyPacket() Type = PacketType.GroupActiveProposalItemReply; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 360; + Header.ID =360; Header.Reliable = true; + NeedValidateIDs = false; Header.Zerocoded = true; AgentData = new AgentDataBlock(); TransactionData = new TransactionDataBlock(); @@ -59741,14 +60388,17 @@ public override int Length public GroupDataBlock GroupData; public TransactionDataBlock TransactionData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public GroupVoteHistoryRequestPacket() { HasVariableBlocks = false; Type = PacketType.GroupVoteHistoryRequest; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 361; + Header.ID =361; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); GroupData = new GroupDataBlock(); TransactionData = new TransactionDataBlock(); @@ -60059,8 +60709,9 @@ public GroupVoteHistoryItemReplyPacket() Type = PacketType.GroupVoteHistoryItemReply; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 362; + Header.ID =362; Header.Reliable = true; + NeedValidateIDs = false; Header.Zerocoded = true; AgentData = new AgentDataBlock(); TransactionData = new TransactionDataBlock(); @@ -60313,14 +60964,17 @@ public override int Length public AgentDataBlock AgentData; public ProposalDataBlock ProposalData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public StartGroupProposalPacket() { HasVariableBlocks = false; Type = PacketType.StartGroupProposal; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 363; + Header.ID =363; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); ProposalData = new ProposalDataBlock(); @@ -60484,14 +61138,17 @@ public override int Length public AgentDataBlock AgentData; public ProposalDataBlock ProposalData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public GroupProposalBallotPacket() { HasVariableBlocks = false; Type = PacketType.GroupProposalBallot; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 364; + Header.ID =364; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); ProposalData = new ProposalDataBlock(); } @@ -60645,14 +61302,17 @@ public override int Length public AgentDataBlock AgentData; public GroupDataBlock GroupData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public GroupMembersRequestPacket() { HasVariableBlocks = false; Type = PacketType.GroupMembersRequest; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 366; + Header.ID =366; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); GroupData = new GroupDataBlock(); } @@ -60878,8 +61538,9 @@ public GroupMembersReplyPacket() Type = PacketType.GroupMembersReply; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 367; + Header.ID =367; Header.Reliable = true; + NeedValidateIDs = false; Header.Zerocoded = true; AgentData = new AgentDataBlock(); GroupData = new GroupDataBlock(); @@ -61070,14 +61731,17 @@ public override int Length } public AgentDataBlock AgentData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public ActivateGroupPacket() { HasVariableBlocks = false; Type = PacketType.ActivateGroup; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 368; + Header.ID =368; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); } @@ -61227,14 +61891,17 @@ public override int Length public AgentDataBlock AgentData; public DataBlock Data; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public SetGroupContributionPacket() { HasVariableBlocks = false; Type = PacketType.SetGroupContribution; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 369; + Header.ID =369; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); Data = new DataBlock(); } @@ -61428,14 +62095,17 @@ public override int Length public DataBlock Data; public NewDataBlock NewData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public SetGroupAcceptNoticesPacket() { HasVariableBlocks = false; Type = PacketType.SetGroupAcceptNotices; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 370; + Header.ID =370; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); Data = new DataBlock(); NewData = new NewDataBlock(); @@ -61594,14 +62264,17 @@ public override int Length public AgentDataBlock AgentData; public GroupDataBlock GroupData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public GroupRoleDataRequestPacket() { HasVariableBlocks = false; Type = PacketType.GroupRoleDataRequest; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 371; + Header.ID =371; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); GroupData = new GroupDataBlock(); } @@ -61831,8 +62504,9 @@ public GroupRoleDataReplyPacket() Type = PacketType.GroupRoleDataReply; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 372; + Header.ID =372; Header.Reliable = true; + NeedValidateIDs = false; AgentData = new AgentDataBlock(); GroupData = new GroupDataBlock(); RoleData = null; @@ -62062,14 +62736,17 @@ public override int Length public AgentDataBlock AgentData; public GroupDataBlock GroupData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public GroupRoleMembersRequestPacket() { HasVariableBlocks = false; Type = PacketType.GroupRoleMembersRequest; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 373; + Header.ID =373; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); GroupData = new GroupDataBlock(); } @@ -62236,8 +62913,9 @@ public GroupRoleMembersReplyPacket() Type = PacketType.GroupRoleMembersReply; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 374; + Header.ID =374; Header.Reliable = true; + NeedValidateIDs = false; AgentData = new AgentDataBlock(); MemberData = null; } @@ -62423,14 +63101,17 @@ public override int Length } public AgentDataBlock AgentData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public GroupTitlesRequestPacket() { HasVariableBlocks = false; Type = PacketType.GroupTitlesRequest; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 375; + Header.ID =375; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); } @@ -62598,8 +63279,9 @@ public GroupTitlesReplyPacket() Type = PacketType.GroupTitlesReply; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 376; + Header.ID =376; Header.Reliable = true; + NeedValidateIDs = false; Header.Zerocoded = true; AgentData = new AgentDataBlock(); GroupData = null; @@ -62786,14 +63468,17 @@ public override int Length } public AgentDataBlock AgentData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public GroupTitleUpdatePacket() { HasVariableBlocks = false; Type = PacketType.GroupTitleUpdate; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 377; + Header.ID =377; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); } @@ -62972,14 +63657,17 @@ public override int Length public AgentDataBlock AgentData; public RoleDataBlock[] RoleData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public GroupRoleUpdatePacket() { HasVariableBlocks = true; Type = PacketType.GroupRoleUpdate; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 378; + Header.ID =378; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); RoleData = null; } @@ -63165,8 +63853,9 @@ public LiveHelpGroupRequestPacket() Type = PacketType.LiveHelpGroupRequest; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 379; + Header.ID =379; Header.Reliable = true; + NeedValidateIDs = false; RequestData = new RequestDataBlock(); } @@ -63287,8 +63976,9 @@ public LiveHelpGroupReplyPacket() Type = PacketType.LiveHelpGroupReply; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 380; + Header.ID =380; Header.Reliable = true; + NeedValidateIDs = false; ReplyData = new ReplyDataBlock(); } @@ -63394,14 +64084,17 @@ public override int Length } public AgentDataBlock AgentData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public AgentWearablesRequestPacket() { HasVariableBlocks = false; Type = PacketType.AgentWearablesRequest; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 381; + Header.ID =381; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); } @@ -63557,14 +64250,17 @@ public override int Length public AgentDataBlock AgentData; public WearableDataBlock[] WearableData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public AgentWearablesUpdatePacket() { HasVariableBlocks = true; Type = PacketType.AgentWearablesUpdate; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 382; + Header.ID =382; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); WearableData = null; @@ -63789,14 +64485,17 @@ public override int Length public AgentDataBlock AgentData; public WearableDataBlock[] WearableData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public AgentIsNowWearingPacket() { HasVariableBlocks = true; Type = PacketType.AgentIsNowWearing; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 383; + Header.ID =383; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); WearableData = null; @@ -64024,14 +64723,17 @@ public override int Length public AgentDataBlock AgentData; public WearableDataBlock[] WearableData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public AgentCachedTexturePacket() { HasVariableBlocks = true; Type = PacketType.AgentCachedTexture; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 384; + Header.ID =384; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); WearableData = null; } @@ -64267,14 +64969,17 @@ public override int Length public AgentDataBlock AgentData; public WearableDataBlock[] WearableData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public AgentCachedTextureResponsePacket() { HasVariableBlocks = true; Type = PacketType.AgentCachedTextureResponse; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 385; + Header.ID =385; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); WearableData = null; } @@ -64454,14 +65159,17 @@ public override int Length } public AgentDataBlock AgentData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public AgentDataUpdateRequestPacket() { HasVariableBlocks = false; Type = PacketType.AgentDataUpdateRequest; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 386; + Header.ID =386; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); } @@ -64606,8 +65314,9 @@ public AgentDataUpdatePacket() Type = PacketType.AgentDataUpdate; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 387; + Header.ID =387; Header.Reliable = true; + NeedValidateIDs = false; Header.Zerocoded = true; AgentData = new AgentDataBlock(); } @@ -64733,8 +65442,9 @@ public GroupDataUpdatePacket() Type = PacketType.GroupDataUpdate; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 388; + Header.ID =388; Header.Reliable = true; + NeedValidateIDs = false; Header.Zerocoded = true; AgentGroupData = null; } @@ -64973,8 +65683,9 @@ public AgentGroupDataUpdatePacket() Type = PacketType.AgentGroupDataUpdate; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 389; + Header.ID =389; Header.Reliable = true; + NeedValidateIDs = false; Header.Zerocoded = true; AgentData = new AgentDataBlock(); GroupData = null; @@ -65161,8 +65872,9 @@ public AgentDropGroupPacket() Type = PacketType.AgentDropGroup; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 390; + Header.ID =390; Header.Reliable = true; + NeedValidateIDs = false; Header.Zerocoded = true; AgentData = new AgentDataBlock(); } @@ -65343,14 +66055,17 @@ public override int Length public AgentDataBlock AgentData; public ObjectDataBlock ObjectData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public RezSingleAttachmentFromInvPacket() { HasVariableBlocks = false; Type = PacketType.RezSingleAttachmentFromInv; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 395; + Header.ID =395; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); ObjectData = new ObjectDataBlock(); @@ -65583,14 +66298,17 @@ public override int Length public HeaderDataBlock HeaderData; public ObjectDataBlock[] ObjectData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public RezMultipleAttachmentsFromInvPacket() { HasVariableBlocks = true; Type = PacketType.RezMultipleAttachmentsFromInv; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 396; + Header.ID =396; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); HeaderData = new HeaderDataBlock(); @@ -65784,8 +66502,9 @@ public DetachAttachmentIntoInvPacket() Type = PacketType.DetachAttachmentIntoInv; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 397; + Header.ID =397; Header.Reliable = true; + NeedValidateIDs = false; ObjectData = new ObjectDataBlock(); } @@ -65975,14 +66694,17 @@ public override int Length public HeaderDataBlock HeaderData; public ObjectDataBlock[] ObjectData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public CreateNewOutfitAttachmentsPacket() { HasVariableBlocks = true; Type = PacketType.CreateNewOutfitAttachments; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 398; + Header.ID =398; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); HeaderData = new HeaderDataBlock(); ObjectData = null; @@ -66169,14 +66891,17 @@ public override int Length } public AgentDataBlock AgentData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public UserInfoRequestPacket() { HasVariableBlocks = false; Type = PacketType.UserInfoRequest; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 399; + Header.ID =399; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); } @@ -66341,8 +67066,9 @@ public UserInfoReplyPacket() Type = PacketType.UserInfoReply; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 400; + Header.ID =400; Header.Reliable = true; + NeedValidateIDs = false; AgentData = new AgentDataBlock(); UserData = new UserDataBlock(); } @@ -66502,14 +67228,17 @@ public override int Length public AgentDataBlock AgentData; public UserDataBlock UserData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public UpdateUserInfoPacket() { HasVariableBlocks = false; Type = PacketType.UpdateUserInfo; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 401; + Header.ID =401; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); UserData = new UserDataBlock(); } @@ -66676,8 +67405,9 @@ public InitiateDownloadPacket() Type = PacketType.InitiateDownload; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 403; + Header.ID =403; Header.Reliable = true; + NeedValidateIDs = false; AgentData = new AgentDataBlock(); FileData = new FileDataBlock(); } @@ -66797,14 +67527,17 @@ public override int Length } public AgentDataBlock AgentData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public MapLayerRequestPacket() { HasVariableBlocks = false; Type = PacketType.MapLayerRequest; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 405; + Header.ID =405; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); } @@ -66969,8 +67702,9 @@ public MapLayerReplyPacket() Type = PacketType.MapLayerReply; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 406; + Header.ID =406; Header.Reliable = true; + NeedValidateIDs = false; AgentData = new AgentDataBlock(); LayerData = null; } @@ -67208,14 +67942,17 @@ public override int Length public AgentDataBlock AgentData; public PositionDataBlock PositionData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public MapBlockRequestPacket() { HasVariableBlocks = false; Type = PacketType.MapBlockRequest; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 407; + Header.ID =407; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); PositionData = new PositionDataBlock(); } @@ -67381,14 +68118,17 @@ public override int Length public AgentDataBlock AgentData; public NameDataBlock NameData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public MapNameRequestPacket() { HasVariableBlocks = false; Type = PacketType.MapNameRequest; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 408; + Header.ID =408; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); NameData = new NameDataBlock(); } @@ -67617,8 +68357,9 @@ public MapBlockReplyPacket() Type = PacketType.MapBlockReply; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 409; + Header.ID =409; Header.Reliable = true; + NeedValidateIDs = false; AgentData = new AgentDataBlock(); Data = null; Size = null; @@ -67889,14 +68630,17 @@ public override int Length public AgentDataBlock AgentData; public RequestDataBlock RequestData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public MapItemRequestPacket() { HasVariableBlocks = false; Type = PacketType.MapItemRequest; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 410; + Header.ID =410; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); RequestData = new RequestDataBlock(); } @@ -68115,8 +68859,9 @@ public MapItemReplyPacket() Type = PacketType.MapItemReply; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 411; + Header.ID =411; Header.Reliable = true; + NeedValidateIDs = false; AgentData = new AgentDataBlock(); RequestData = new RequestDataBlock(); Data = null; @@ -68352,14 +69097,17 @@ public override int Length } public AgentDataBlock AgentData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public SendPostcardPacket() { HasVariableBlocks = false; Type = PacketType.SendPostcard; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 412; + Header.ID =412; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); } @@ -68474,8 +69222,9 @@ public ParcelMediaCommandMessagePacket() Type = PacketType.ParcelMediaCommandMessage; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 419; + Header.ID =419; Header.Reliable = true; + NeedValidateIDs = false; CommandBlock = new CommandBlockBlock(); } @@ -68658,8 +69407,9 @@ public ParcelMediaUpdatePacket() Type = PacketType.ParcelMediaUpdate; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 420; + Header.ID =420; Header.Reliable = true; + NeedValidateIDs = false; DataBlock = new DataBlockBlock(); DataBlockExtended = new DataBlockExtendedBlock(); } @@ -68825,14 +69575,17 @@ public override int Length public AgentDataBlock AgentData; public RequestDataBlock RequestData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public LandStatRequestPacket() { HasVariableBlocks = false; Type = PacketType.LandStatRequest; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 421; + Header.ID =421; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); RequestData = new RequestDataBlock(); } @@ -69024,8 +69777,9 @@ public LandStatReplyPacket() Type = PacketType.LandStatReply; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 422; + Header.ID =422; Header.Reliable = true; + NeedValidateIDs = false; RequestData = new RequestDataBlock(); ReportData = null; } @@ -69281,8 +70035,9 @@ public ErrorPacket() Type = PacketType.Error; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 423; + Header.ID =423; Header.Reliable = true; + NeedValidateIDs = false; Header.Zerocoded = true; AgentData = new AgentDataBlock(); Data = new DataBlock(); @@ -69438,14 +70193,17 @@ public override int Length public AgentDataBlock AgentData; public ObjectDataBlock[] ObjectData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public ObjectIncludeInSearchPacket() { HasVariableBlocks = true; Type = PacketType.ObjectIncludeInSearch; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 424; + Header.ID =424; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); ObjectData = null; } @@ -69735,14 +70493,17 @@ public override int Length public AgentDataBlock AgentData; public InventoryDataBlock InventoryData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public RezRestoreToWorldPacket() { HasVariableBlocks = false; Type = PacketType.RezRestoreToWorld; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 425; + Header.ID =425; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); InventoryData = new InventoryDataBlock(); } @@ -69924,14 +70685,17 @@ public override int Length public AgentDataBlock AgentData; public InventoryBlockBlock InventoryBlock; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public LinkInventoryItemPacket() { HasVariableBlocks = false; Type = PacketType.LinkInventoryItem; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 426; + Header.ID =426; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); InventoryBlock = new InventoryBlockBlock(); @@ -70142,14 +70906,17 @@ public override int Length public MethodDataBlock MethodData; public ParamListBlock[] ParamList; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public LargeGenericMessagePacket() { HasVariableBlocks = true; Type = PacketType.LargeGenericMessage; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 430; + Header.ID =430; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); MethodData = new MethodDataBlock(); ParamList = null; @@ -70340,8 +71107,9 @@ public PacketAckPacket() Type = PacketType.PacketAck; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 65531; + Header.ID =65531; Header.Reliable = true; + NeedValidateIDs = false; Packets = null; } @@ -70520,8 +71288,9 @@ public OpenCircuitPacket() Type = PacketType.OpenCircuit; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 65532; + Header.ID =65532; Header.Reliable = true; + NeedValidateIDs = false; CircuitInfo = new CircuitInfoBlock(); } @@ -70590,8 +71359,9 @@ public CloseCircuitPacket() Type = PacketType.CloseCircuit; Header = new Header(); Header.Frequency = PacketFrequency.Low; - Header.ID = 65533; + Header.ID =65533; Header.Reliable = true; + NeedValidateIDs = false; } public CloseCircuitPacket(byte[] bytes, ref int i) : this() @@ -70819,14 +71589,17 @@ public override int Length public AgentDataBlock AgentData; public ObjectDataBlock ObjectData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public ObjectAddPacket() { HasVariableBlocks = false; Type = PacketType.ObjectAdd; Header = new Header(); Header.Frequency = PacketFrequency.Medium; - Header.ID = 1; + Header.ID =1; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); ObjectData = new ObjectDataBlock(); @@ -70991,14 +71764,17 @@ public override int Length public AgentDataBlock AgentData; public ObjectDataBlock[] ObjectData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public MultipleObjectUpdatePacket() { HasVariableBlocks = true; Type = PacketType.MultipleObjectUpdate; Header = new Header(); Header.Frequency = PacketFrequency.Medium; - Header.ID = 2; + Header.ID =2; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); ObjectData = null; @@ -71223,14 +71999,17 @@ public override int Length public AgentDataBlock AgentData; public ObjectDataBlock[] ObjectData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public RequestMultipleObjectsPacket() { HasVariableBlocks = true; Type = PacketType.RequestMultipleObjects; Header = new Header(); Header.Frequency = PacketFrequency.Medium; - Header.ID = 3; + Header.ID =3; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); ObjectData = null; @@ -71455,14 +72234,17 @@ public override int Length public AgentDataBlock AgentData; public ObjectDataBlock[] ObjectData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public ObjectPositionPacket() { HasVariableBlocks = true; Type = PacketType.ObjectPosition; Header = new Header(); Header.Frequency = PacketFrequency.Medium; - Header.ID = 4; + Header.ID =4; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); ObjectData = null; @@ -71686,14 +72468,17 @@ public override int Length public AgentDataBlock AgentData; public ObjectDataBlock ObjectData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public RequestObjectPropertiesFamilyPacket() { HasVariableBlocks = false; Type = PacketType.RequestObjectPropertiesFamily; Header = new Header(); Header.Frequency = PacketFrequency.Medium; - Header.ID = 5; + Header.ID =5; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); ObjectData = new ObjectDataBlock(); @@ -71899,8 +72684,9 @@ public CoarseLocationUpdatePacket() Type = PacketType.CoarseLocationUpdate; Header = new Header(); Header.Frequency = PacketFrequency.Medium; - Header.ID = 6; + Header.ID =6; Header.Reliable = true; + NeedValidateIDs = false; Location = null; Index = new IndexBlock(); AgentData = null; @@ -72146,14 +72932,17 @@ public override int Length public RegionDataBlock RegionData; public InfoBlock Info; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public CrossedRegionPacket() { HasVariableBlocks = false; Type = PacketType.CrossedRegion; Header = new Header(); Header.Frequency = PacketFrequency.Medium; - Header.ID = 7; + Header.ID =7; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); RegionData = new RegionDataBlock(); Info = new InfoBlock(); @@ -72269,14 +73058,17 @@ public override int Length } public AgentDataBlock AgentData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public ConfirmEnableSimulatorPacket() { HasVariableBlocks = false; Type = PacketType.ConfirmEnableSimulator; Header = new Header(); Header.Frequency = PacketFrequency.Medium; - Header.ID = 8; + Header.ID =8; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); } @@ -72486,8 +73278,9 @@ public ObjectPropertiesPacket() Type = PacketType.ObjectProperties; Header = new Header(); Header.Frequency = PacketFrequency.Medium; - Header.ID = 9; + Header.ID =9; Header.Reliable = true; + NeedValidateIDs = false; Header.Zerocoded = true; ObjectData = null; } @@ -72719,8 +73512,9 @@ public ObjectPropertiesFamilyPacket() Type = PacketType.ObjectPropertiesFamily; Header = new Header(); Header.Frequency = PacketFrequency.Medium; - Header.ID = 10; + Header.ID =10; Header.Reliable = true; + NeedValidateIDs = false; Header.Zerocoded = true; ObjectData = new ObjectDataBlock(); } @@ -72882,14 +73676,17 @@ public override int Length public AgentDataBlock AgentData; public ParcelDataBlock ParcelData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public ParcelPropertiesRequestPacket() { HasVariableBlocks = false; Type = PacketType.ParcelPropertiesRequest; Header = new Header(); Header.Frequency = PacketFrequency.Medium; - Header.ID = 11; + Header.ID =11; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); ParcelData = new ParcelDataBlock(); @@ -73016,8 +73813,9 @@ public AttachedSoundPacket() Type = PacketType.AttachedSound; Header = new Header(); Header.Frequency = PacketFrequency.Medium; - Header.ID = 13; + Header.ID =13; Header.Reliable = true; + NeedValidateIDs = false; DataBlock = new DataBlockBlock(); } @@ -73129,8 +73927,9 @@ public AttachedSoundGainChangePacket() Type = PacketType.AttachedSoundGainChange; Header = new Header(); Header.Frequency = PacketFrequency.Medium; - Header.ID = 14; + Header.ID =14; Header.Reliable = true; + NeedValidateIDs = false; DataBlock = new DataBlockBlock(); } @@ -73246,8 +74045,9 @@ public PreloadSoundPacket() Type = PacketType.PreloadSound; Header = new Header(); Header.Frequency = PacketFrequency.Medium; - Header.ID = 15; + Header.ID =15; Header.Reliable = true; + NeedValidateIDs = false; DataBlock = null; } @@ -73483,14 +74283,17 @@ public override int Length public AgentDataBlock AgentData; public EffectBlock[] Effect; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public ViewerEffectPacket() { HasVariableBlocks = true; Type = PacketType.ViewerEffect; Header = new Header(); Header.Frequency = PacketFrequency.Medium; - Header.ID = 17; + Header.ID =17; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); Effect = null; @@ -73677,8 +74480,9 @@ public StartPingCheckPacket() Type = PacketType.StartPingCheck; Header = new Header(); Header.Frequency = PacketFrequency.High; - Header.ID = 1; + Header.ID =1; Header.Reliable = true; + NeedValidateIDs = false; PingID = new PingIDBlock(); } @@ -73787,8 +74591,9 @@ public CompletePingCheckPacket() Type = PacketType.CompletePingCheck; Header = new Header(); Header.Frequency = PacketFrequency.High; - Header.ID = 2; + Header.ID =2; Header.Reliable = true; + NeedValidateIDs = false; PingID = new PingIDBlock(); } @@ -73924,14 +74729,17 @@ public override int Length } public AgentDataBlock AgentData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public AgentUpdatePacket() { HasVariableBlocks = false; Type = PacketType.AgentUpdate; Header = new Header(); Header.Frequency = PacketFrequency.High; - Header.ID = 4; + Header.ID =4; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); } @@ -74129,14 +74937,17 @@ public override int Length public AnimationListBlock[] AnimationList; public PhysicalAvatarEventListBlock[] PhysicalAvatarEventList; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public AgentAnimationPacket() { HasVariableBlocks = true; Type = PacketType.AgentAnimation; Header = new Header(); Header.Frequency = PacketFrequency.High; - Header.ID = 5; + Header.ID =5; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); AnimationList = null; PhysicalAvatarEventList = null; @@ -74398,14 +75209,17 @@ public override int Length public AgentDataBlock AgentData; public TargetObjectBlock TargetObject; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public AgentRequestSitPacket() { HasVariableBlocks = false; Type = PacketType.AgentRequestSit; Header = new Header(); Header.Frequency = PacketFrequency.High; - Header.ID = 6; + Header.ID =6; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); TargetObject = new TargetObjectBlock(); @@ -74517,14 +75331,17 @@ public override int Length } public AgentDataBlock AgentData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public AgentSitPacket() { HasVariableBlocks = false; Type = PacketType.AgentSit; Header = new Header(); Header.Frequency = PacketFrequency.High; - Header.ID = 7; + Header.ID =7; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); } @@ -74683,14 +75500,17 @@ public override int Length public AgentDataBlock AgentData; public RequestImageBlock[] RequestImage; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public RequestImagePacket() { HasVariableBlocks = true; Type = PacketType.RequestImage; Header = new Header(); Header.Frequency = PacketFrequency.High; - Header.ID = 8; + Header.ID =8; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); RequestImage = null; } @@ -74928,8 +75748,9 @@ public ImageDataPacket() Type = PacketType.ImageData; Header = new Header(); Header.Frequency = PacketFrequency.High; - Header.ID = 9; + Header.ID =9; Header.Reliable = true; + NeedValidateIDs = false; ImageID = new ImageIDBlock(); ImageData = new ImageDataBlock(); } @@ -75092,8 +75913,9 @@ public ImagePacketPacket() Type = PacketType.ImagePacket; Header = new Header(); Header.Frequency = PacketFrequency.High; - Header.ID = 10; + Header.ID =10; Header.Reliable = true; + NeedValidateIDs = false; ImageID = new ImageIDBlock(); ImageData = new ImageDataBlock(); } @@ -75253,8 +76075,9 @@ public LayerDataPacket() Type = PacketType.LayerData; Header = new Header(); Header.Frequency = PacketFrequency.High; - Header.ID = 11; + Header.ID =11; Header.Reliable = true; + NeedValidateIDs = false; LayerID = new LayerIDBlock(); LayerData = new LayerDataBlock(); } @@ -75586,8 +76409,9 @@ public ObjectUpdatePacket() Type = PacketType.ObjectUpdate; Header = new Header(); Header.Frequency = PacketFrequency.High; - Header.ID = 12; + Header.ID =12; Header.Reliable = true; + NeedValidateIDs = false; Header.Zerocoded = true; RegionData = new RegionDataBlock(); ObjectData = null; @@ -75824,8 +76648,9 @@ public ObjectUpdateCompressedPacket() Type = PacketType.ObjectUpdateCompressed; Header = new Header(); Header.Frequency = PacketFrequency.High; - Header.ID = 13; + Header.ID =13; Header.Reliable = true; + NeedValidateIDs = false; RegionData = new RegionDataBlock(); ObjectData = null; } @@ -76058,8 +76883,9 @@ public ObjectUpdateCachedPacket() Type = PacketType.ObjectUpdateCached; Header = new Header(); Header.Frequency = PacketFrequency.High; - Header.ID = 14; + Header.ID =14; Header.Reliable = true; + NeedValidateIDs = false; RegionData = new RegionDataBlock(); ObjectData = null; } @@ -76299,8 +77125,9 @@ public ImprovedTerseObjectUpdatePacket() Type = PacketType.ImprovedTerseObjectUpdate; Header = new Header(); Header.Frequency = PacketFrequency.High; - Header.ID = 15; + Header.ID =15; Header.Reliable = true; + NeedValidateIDs = false; RegionData = new RegionDataBlock(); ObjectData = null; } @@ -76484,8 +77311,9 @@ public KillObjectPacket() Type = PacketType.KillObject; Header = new Header(); Header.Frequency = PacketFrequency.High; - Header.ID = 16; + Header.ID =16; Header.Reliable = true; + NeedValidateIDs = false; ObjectData = null; } @@ -76679,8 +77507,9 @@ public TransferPacketPacket() Type = PacketType.TransferPacket; Header = new Header(); Header.Frequency = PacketFrequency.High; - Header.ID = 17; + Header.ID =17; Header.Reliable = true; + NeedValidateIDs = false; TransferData = new TransferDataBlock(); } @@ -76838,8 +77667,9 @@ public SendXferPacketPacket() Type = PacketType.SendXferPacket; Header = new Header(); Header.Frequency = PacketFrequency.High; - Header.ID = 18; + Header.ID =18; Header.Reliable = true; + NeedValidateIDs = false; XferID = new XferIDBlock(); DataPacket = new DataPacketBlock(); } @@ -76956,8 +77786,9 @@ public ConfirmXferPacketPacket() Type = PacketType.ConfirmXferPacket; Header = new Header(); Header.Frequency = PacketFrequency.High; - Header.ID = 19; + Header.ID =19; Header.Reliable = true; + NeedValidateIDs = false; XferID = new XferIDBlock(); } @@ -77198,8 +78029,9 @@ public AvatarAnimationPacket() Type = PacketType.AvatarAnimation; Header = new Header(); Header.Frequency = PacketFrequency.High; - Header.ID = 20; + Header.ID =20; Header.Reliable = true; + NeedValidateIDs = false; Sender = new SenderBlock(); AnimationList = null; AnimationSourceList = null; @@ -77515,8 +78347,9 @@ public AvatarSitResponsePacket() Type = PacketType.AvatarSitResponse; Header = new Header(); Header.Frequency = PacketFrequency.High; - Header.ID = 21; + Header.ID =21; Header.Reliable = true; + NeedValidateIDs = false; Header.Zerocoded = true; SitObject = new SitObjectBlock(); SitTransform = new SitTransformBlock(); @@ -77631,8 +78464,9 @@ public CameraConstraintPacket() Type = PacketType.CameraConstraint; Header = new Header(); Header.Frequency = PacketFrequency.High; - Header.ID = 22; + Header.ID =22; Header.Reliable = true; + NeedValidateIDs = false; Header.Zerocoded = true; CameraCollidePlane = new CameraCollidePlaneBlock(); } @@ -78031,8 +78865,9 @@ public ParcelPropertiesPacket() Type = PacketType.ParcelProperties; Header = new Header(); Header.Frequency = PacketFrequency.High; - Header.ID = 23; + Header.ID =23; Header.Reliable = true; + NeedValidateIDs = false; Header.Zerocoded = true; ParcelData = new ParcelDataBlock(); AgeVerificationBlock = new AgeVerificationBlockBlock(); @@ -78541,14 +79376,17 @@ public override int Length public AgentAccessBlock[] AgentAccess; public AgentInfoBlock[] AgentInfo; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public ChildAgentUpdatePacket() { HasVariableBlocks = true; Type = PacketType.ChildAgentUpdate; Header = new Header(); Header.Frequency = PacketFrequency.High; - Header.ID = 25; + Header.ID =25; Header.Reliable = true; + NeedValidateIDs = true; Header.Zerocoded = true; AgentData = new AgentDataBlock(); GroupData = null; @@ -78969,14 +79807,17 @@ public override int Length } public AgentDataBlock AgentData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public ChildAgentAlivePacket() { HasVariableBlocks = false; Type = PacketType.ChildAgentAlive; Header = new Header(); Header.Frequency = PacketFrequency.High; - Header.ID = 26; + Header.ID =26; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); } @@ -79112,14 +79953,17 @@ public override int Length } public AgentDataBlock AgentData; + public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); } + public ChildAgentPositionUpdatePacket() { HasVariableBlocks = false; Type = PacketType.ChildAgentPositionUpdate; Header = new Header(); Header.Frequency = PacketFrequency.High; - Header.ID = 27; + Header.ID =27; Header.Reliable = true; + NeedValidateIDs = true; AgentData = new AgentDataBlock(); } @@ -79246,8 +80090,9 @@ public SoundTriggerPacket() Type = PacketType.SoundTrigger; Header = new Header(); Header.Frequency = PacketFrequency.High; - Header.ID = 29; + Header.ID =29; Header.Reliable = true; + NeedValidateIDs = false; SoundData = new SoundDataBlock(); } @@ -79400,8 +80245,9 @@ public ObjectAnimationPacket() Type = PacketType.ObjectAnimation; Header = new Header(); Header.Frequency = PacketFrequency.High; - Header.ID = 30; + Header.ID =30; Header.Reliable = true; + NeedValidateIDs = false; Sender = new SenderBlock(); AnimationList = null; } @@ -79630,8 +80476,9 @@ public GenericStreamingMessagePacket() Type = PacketType.GenericStreamingMessage; Header = new Header(); Header.Frequency = PacketFrequency.High; - Header.ID = 31; + Header.ID =31; Header.Reliable = true; + NeedValidateIDs = false; MethodData = new MethodDataBlock(); DataBlock = new DataBlockBlock(); } diff --git a/OpenMetaverseTypes/Enums.cs b/OpenMetaverseTypes/Enums.cs index f00b3373..a75fd760 100644 --- a/OpenMetaverseTypes/Enums.cs +++ b/OpenMetaverseTypes/Enums.cs @@ -106,7 +106,12 @@ public enum AssetType : sbyte Settings = 56, /// Render material - Material = 57 + Material = 57, + + GLTF = 58, + GLTF_bin = 59, + + OSMaterial = -2 // OpenSimulator specific } ///
@@ -241,7 +246,10 @@ public enum InventoryType : sbyte Settings = 25, - Material = 26 + Material = 26, + + GLTF = 27, + GLTF_bin = 28 } /// diff --git a/OpenMetaverseTypes/Matrix3x3.cs b/OpenMetaverseTypes/Matrix3x3.cs index 8ff3c797..38178de6 100644 --- a/OpenMetaverseTypes/Matrix3x3.cs +++ b/OpenMetaverseTypes/Matrix3x3.cs @@ -29,7 +29,6 @@ using System.Runtime.InteropServices; using System.Runtime.Intrinsics.X86; using System.Runtime.Intrinsics; -using System.IO; namespace OpenMetaverse { diff --git a/OpenMetaverseTypes/OSUTF8.cs b/OpenMetaverseTypes/OSUTF8.cs index 0cbbec22..7eb931cc 100644 --- a/OpenMetaverseTypes/OSUTF8.cs +++ b/OpenMetaverseTypes/OSUTF8.cs @@ -101,6 +101,13 @@ public osUTF8(string source) m_len = m_data.Length; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public osUTF8(ReadOnlySpan ut8) + { + m_data = ut8.ToArray(); + m_len = m_data.Length; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public osUTF8(string source, int maxlen) { @@ -283,6 +290,16 @@ public bool Equals(string s) return Equals(o); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool Equals(ReadOnlySpan s) + { + if(m_len != s.Length) + return false; + + ReadOnlySpan os = m_data.AsSpan(0, m_data.Length); + return os.SequenceEqual(s); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool operator ==(osUTF8 value1, osUTF8 value2) { @@ -555,6 +572,15 @@ public void Append(osUTF8 b) m_len += nbytes; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(ReadOnlySpan b) + { + int nbytes = b.Length; + CheckCapacity(nbytes); + b.CopyTo(new Span(m_data,m_len, nbytes)); + m_len += nbytes; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe void AppendInt(sbyte v) { @@ -790,7 +816,7 @@ public bool StartsWith(byte b) [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool StartsWith(char b) { - return m_data[0] == (byte)b; + return Unsafe.As(ref MemoryMarshal.GetArrayDataReference(m_data)) == (byte)b; } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -802,7 +828,7 @@ public bool EndsWith(byte b) [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool EndsWith(char b) { - return m_data[m_len - 1] == (byte)b; + return Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(m_data), m_len - 1)) == (byte)b; } public unsafe bool EndsWith(osUTF8 other) diff --git a/OpenMetaverseTypes/OSUTF8Constants.cs b/OpenMetaverseTypes/OSUTF8Constants.cs index 25213dd3..8d7a3518 100644 --- a/OpenMetaverseTypes/OSUTF8Constants.cs +++ b/OpenMetaverseTypes/OSUTF8Constants.cs @@ -31,108 +31,107 @@ namespace OpenMetaverse public static class osUTF8Const { // direct utf8 string byte arrays to use with osUTF8 and osUTF8Slice - // waste time calling osUTF8.GetASCIIBytes just because it is more readable then {(byte)char,... } form - public static readonly byte[] XMLundef = osUTF8.GetASCIIBytes(""); - public static readonly byte[] XMLfullbooleanOne = osUTF8.GetASCIIBytes("1"); - public static readonly byte[] XMLfullbooleanZero = osUTF8.GetASCIIBytes("0"); - public static readonly byte[] XMLintegerStart = osUTF8.GetASCIIBytes(""); - public static readonly byte[] XMLintegerEmpty = osUTF8.GetASCIIBytes(""); - public static readonly byte[] XMLintegerEnd = osUTF8.GetASCIIBytes(""); - public static readonly byte[] XMLrealStart = osUTF8.GetASCIIBytes(""); - public static readonly byte[] XMLrealZero = osUTF8.GetASCIIBytes("0"); - public static readonly byte[] XMLrealZeroarrayEnd = osUTF8.GetASCIIBytes("0"); - public static readonly byte[] XMLrealEnd = osUTF8.GetASCIIBytes(""); - public static readonly byte[] XMLrealEndarrayEnd = osUTF8.GetASCIIBytes(""); - public static readonly byte[] XMLstringStart = osUTF8.GetASCIIBytes(""); - public static readonly byte[] XMLstringEmpty = osUTF8.GetASCIIBytes(""); - public static readonly byte[] XMLstringEnd = osUTF8.GetASCIIBytes(""); - public static readonly byte[] XMLuuidStart = osUTF8.GetASCIIBytes(""); - public static readonly byte[] XMLuuidEmpty = osUTF8.GetASCIIBytes(""); - public static readonly byte[] XMLuuidEnd = osUTF8.GetASCIIBytes(""); - public static readonly byte[] XMLdateStart = osUTF8.GetASCIIBytes(""); - public static readonly byte[] XMLdateEmpty = osUTF8.GetASCIIBytes(""); - public static readonly byte[] XMLdateEnd = osUTF8.GetASCIIBytes(""); - public static readonly byte[] XMLuriStart = osUTF8.GetASCIIBytes(""); - public static readonly byte[] XMLuriEmpty = osUTF8.GetASCIIBytes(""); - public static readonly byte[] XMLuriEnd = osUTF8.GetASCIIBytes(""); - public static readonly byte[] XMLformalBinaryStart = osUTF8.GetASCIIBytes(""); - public static readonly byte[] XMLbinaryStart = osUTF8.GetASCIIBytes(""); - public static readonly byte[] XMLbinaryEmpty = osUTF8.GetASCIIBytes(""); - public static readonly byte[] XMLbinaryEnd = osUTF8.GetASCIIBytes(""); - public static readonly byte[] XMLmapStart = osUTF8.GetASCIIBytes(""); - public static readonly byte[] XMLmapEmpty = osUTF8.GetASCIIBytes(""); - public static readonly byte[] XMLmapEnd = osUTF8.GetASCIIBytes(""); - public static readonly byte[] XMLkeyStart = osUTF8.GetASCIIBytes(""); - public static readonly byte[] XMLkeyEmpty = osUTF8.GetASCIIBytes(""); - public static readonly byte[] XMLkeyEnd = osUTF8.GetASCIIBytes(""); - public static readonly byte[] XMLkeyEndundef = osUTF8.GetASCIIBytes(""); - public static readonly byte[] XMLkeyEndmapStart = osUTF8.GetASCIIBytes(""); - public static readonly byte[] XMLkeyEndmapEmpty = osUTF8.GetASCIIBytes(""); - public static readonly byte[] XMLkeyEndarrayStart = osUTF8.GetASCIIBytes(""); - public static readonly byte[] XMLkeyEndarrayEmpty = osUTF8.GetASCIIBytes(""); - public static readonly byte[] XMLkeyEndarrayStartmapStart = osUTF8.GetASCIIBytes(""); - public static readonly byte[] XMLarrayStart = osUTF8.GetASCIIBytes(""); - public static readonly byte[] XMLarrayStartrealZero = osUTF8.GetASCIIBytes("0"); - public static readonly byte[] XMLarrayStartrealStart = osUTF8.GetASCIIBytes(""); - public static readonly byte[] XMLkeyEndarrayStartrealZero = osUTF8.GetASCIIBytes("0"); - public static readonly byte[] XMLkeyEndarrayStartrealStart = osUTF8.GetASCIIBytes(""); - public static readonly byte[] XMLarrayEmpty = osUTF8.GetASCIIBytes(""); - public static readonly byte[] XMLarrayEnd = osUTF8.GetASCIIBytes(""); - public static readonly byte[] XMLamp_lt = osUTF8.GetASCIIBytes("<"); - public static readonly byte[] XMLamp_gt = osUTF8.GetASCIIBytes(">"); - public static readonly byte[] XMLamp = osUTF8.GetASCIIBytes("&"); - public static readonly byte[] XMLamp_quot = osUTF8.GetASCIIBytes("""); - public static readonly byte[] XMLamp_apos = osUTF8.GetASCIIBytes("'"); - public static readonly byte[] XMLformalHeader = osUTF8.GetASCIIBytes(""); - public static readonly byte[] XMLformalHeaderllsdstart = osUTF8.GetASCIIBytes(""); - public static readonly byte[] XMLllsdStart = osUTF8.GetASCIIBytes(""); - public static readonly byte[] XMLllsdEnd = osUTF8.GetASCIIBytes(""); - public static readonly byte[] XMLllsdEmpty = osUTF8.GetASCIIBytes(""); - public static readonly byte[] XMLmapEndarrayEnd = osUTF8.GetASCIIBytes(""); - - public static readonly byte[] XMLarrayEndmapEnd = osUTF8.GetASCIIBytes(""); - - public static readonly byte[] XMLelement_name_Empty = osUTF8.GetASCIIBytes("name"); - public static readonly byte[] XMLelement_name_Start = osUTF8.GetASCIIBytes("name"); - - public static readonly byte[] XMLelement_agent_id_Empty = osUTF8.GetASCIIBytes("agent_id"); - public static readonly byte[] XMLelement_agent_id_Start = osUTF8.GetASCIIBytes("agent_id"); - - public static readonly byte[] XMLelement_owner_id_Empty = osUTF8.GetASCIIBytes("owner_id"); - public static readonly byte[] XMLelement_owner_id_Start = osUTF8.GetASCIIBytes("owner_id"); - - public static readonly byte[] XMLelement_creator_id_Empty = osUTF8.GetASCIIBytes("creator_id"); - public static readonly byte[] XMLelement_creator_id_Start = osUTF8.GetASCIIBytes("creator_id"); - - public static readonly byte[] XMLelement_group_id_Empty = osUTF8.GetASCIIBytes("group_id"); - public static readonly byte[] XMLelement_group_id_Start = osUTF8.GetASCIIBytes("cgroup_id"); - - public static readonly byte[] XMLelement_parent_id_Empty = osUTF8.GetASCIIBytes("parent_id"); - public static readonly byte[] XMLelement_parent_id_Start = osUTF8.GetASCIIBytes("parent_id"); - - public static readonly byte[] XMLelement_folder_id_Empty = osUTF8.GetASCIIBytes("folder_id"); - public static readonly byte[] XMLelement_folder_id_Start = osUTF8.GetASCIIBytes("folder_id"); - - public static readonly byte[] XMLelement_asset_id_Empty = osUTF8.GetASCIIBytes("asset_id"); - public static readonly byte[] XMLelement_asset_id_Start = osUTF8.GetASCIIBytes("asset_id"); - - public static readonly byte[] XMLelement_item_id_Empty = osUTF8.GetASCIIBytes("item_id"); - public static readonly byte[] XMLelement_item_id_Start = osUTF8.GetASCIIBytes("item_id"); - - public static readonly byte[] XMLelement_category_id_Empty = osUTF8.GetASCIIBytes("category_id"); - public static readonly byte[] XMLelement_category_id_Start = osUTF8.GetASCIIBytes("category_id"); - - public static readonly byte[] XMLelement_version_Empty = osUTF8.GetASCIIBytes("version"); - public static readonly byte[] XMLelement_version_Start = osUTF8.GetASCIIBytes("version"); - - public static readonly byte[] XMLelement_sale_info_Empty = osUTF8.GetASCIIBytes("sale_infosale_pricesale_type"); - public static readonly byte[] XMLelement_sale_info_Start = osUTF8.GetASCIIBytes("sale_infosale_price"); - public static readonly byte[] XMLelement_sale_info_Mid = osUTF8.GetASCIIBytes("sale_type"); - public static readonly byte[] XMLelement_sale_info_End = osUTF8.GetASCIIBytes(""); - - public static readonly byte[] OSUTF8null = { (byte)'n', (byte)'u', (byte)'l', (byte)'l' }; - public static readonly byte[] OSUTF8true = { (byte)'t', (byte)'r', (byte)'u', (byte)'e' }; - public static readonly byte[] OSUTF8false = { (byte)'f', (byte)'a', (byte)'l', (byte)'s', (byte)'e' }; + public static readonly byte[] XMLundef = ""u8.ToArray(); + public static readonly byte[] XMLfullbooleanOne = "1"u8.ToArray(); + public static readonly byte[] XMLfullbooleanZero = "0"u8.ToArray(); + public static readonly byte[] XMLintegerStart = ""u8.ToArray(); + public static readonly byte[] XMLintegerEmpty = ""u8.ToArray(); + public static readonly byte[] XMLintegerEnd = ""u8.ToArray(); + public static readonly byte[] XMLrealStart = ""u8.ToArray(); + public static readonly byte[] XMLrealZero = "0"u8.ToArray(); + public static readonly byte[] XMLrealZeroarrayEnd = "0"u8.ToArray(); + public static readonly byte[] XMLrealEnd = ""u8.ToArray(); + public static readonly byte[] XMLrealEndarrayEnd = ""u8.ToArray(); + public static readonly byte[] XMLstringStart = ""u8.ToArray(); + public static readonly byte[] XMLstringEmpty = ""u8.ToArray(); + public static readonly byte[] XMLstringEnd = ""u8.ToArray(); + public static readonly byte[] XMLuuidStart = ""u8.ToArray(); + public static readonly byte[] XMLuuidEmpty = ""u8.ToArray(); + public static readonly byte[] XMLuuidEnd = ""u8.ToArray(); + public static readonly byte[] XMLdateStart = ""u8.ToArray(); + public static readonly byte[] XMLdateEmpty = ""u8.ToArray(); + public static readonly byte[] XMLdateEnd = ""u8.ToArray(); + public static readonly byte[] XMLuriStart = ""u8.ToArray(); + public static readonly byte[] XMLuriEmpty = ""u8.ToArray(); + public static readonly byte[] XMLuriEnd = ""u8.ToArray(); + public static readonly byte[] XMLformalBinaryStart = ""u8.ToArray(); + public static readonly byte[] XMLbinaryStart = ""u8.ToArray(); + public static readonly byte[] XMLbinaryEmpty = ""u8.ToArray(); + public static readonly byte[] XMLbinaryEnd = ""u8.ToArray(); + public static readonly byte[] XMLmapStart = ""u8.ToArray(); + public static readonly byte[] XMLmapEmpty = ""u8.ToArray(); + public static readonly byte[] XMLmapEnd = ""u8.ToArray(); + public static readonly byte[] XMLkeyStart = ""u8.ToArray(); + public static readonly byte[] XMLkeyEmpty = ""u8.ToArray(); + public static readonly byte[] XMLkeyEnd = ""u8.ToArray(); + public static readonly byte[] XMLkeyEndundef = ""u8.ToArray(); + public static readonly byte[] XMLkeyEndmapStart = ""u8.ToArray(); + public static readonly byte[] XMLkeyEndmapEmpty = ""u8.ToArray(); + public static readonly byte[] XMLkeyEndarrayStart = ""u8.ToArray(); + public static readonly byte[] XMLkeyEndarrayEmpty = ""u8.ToArray(); + public static readonly byte[] XMLkeyEndarrayStartmapStart = ""u8.ToArray(); + public static readonly byte[] XMLarrayStart = ""u8.ToArray(); + public static readonly byte[] XMLarrayStartrealZero = "0"u8.ToArray(); + public static readonly byte[] XMLarrayStartrealStart = ""u8.ToArray(); + public static readonly byte[] XMLkeyEndarrayStartrealZero = "0"u8.ToArray(); + public static readonly byte[] XMLkeyEndarrayStartrealStart = ""u8.ToArray(); + public static readonly byte[] XMLarrayEmpty = ""u8.ToArray(); + public static readonly byte[] XMLarrayEnd = ""u8.ToArray(); + public static readonly byte[] XMLamp_lt = "<"u8.ToArray(); + public static readonly byte[] XMLamp_gt = ">"u8.ToArray(); + public static readonly byte[] XMLamp = "&"u8.ToArray(); + public static readonly byte[] XMLamp_quot = """u8.ToArray(); + public static readonly byte[] XMLamp_apos = "'"u8.ToArray(); + public static readonly byte[] XMLformalHeader = ""u8.ToArray(); + public static readonly byte[] XMLformalHeaderllsdstart = ""u8.ToArray(); + public static readonly byte[] XMLllsdStart = ""u8.ToArray(); + public static readonly byte[] XMLllsdEnd = ""u8.ToArray(); + public static readonly byte[] XMLllsdEmpty = ""u8.ToArray(); + public static readonly byte[] XMLmapEndarrayEnd = ""u8.ToArray(); + + public static readonly byte[] XMLarrayEndmapEnd = ""u8.ToArray(); + + public static readonly byte[] XMLelement_name_Empty = "name"u8.ToArray(); + public static readonly byte[] XMLelement_name_Start = "name"u8.ToArray(); + + public static readonly byte[] XMLelement_agent_id_Empty = "agent_id"u8.ToArray(); + public static readonly byte[] XMLelement_agent_id_Start = "agent_id"u8.ToArray(); + + public static readonly byte[] XMLelement_owner_id_Empty = "owner_id"u8.ToArray(); + public static readonly byte[] XMLelement_owner_id_Start = "owner_id"u8.ToArray(); + + public static readonly byte[] XMLelement_creator_id_Empty = "creator_id"u8.ToArray(); + public static readonly byte[] XMLelement_creator_id_Start = "creator_id"u8.ToArray(); + + public static readonly byte[] XMLelement_group_id_Empty = "group_id"u8.ToArray(); + public static readonly byte[] XMLelement_group_id_Start = "cgroup_id"u8.ToArray(); + + public static readonly byte[] XMLelement_parent_id_Empty = "parent_id"u8.ToArray(); + public static readonly byte[] XMLelement_parent_id_Start = "parent_id"u8.ToArray(); + + public static readonly byte[] XMLelement_folder_id_Empty = "folder_id"u8.ToArray(); + public static readonly byte[] XMLelement_folder_id_Start = "folder_id"u8.ToArray(); + + public static readonly byte[] XMLelement_asset_id_Empty = "asset_id"u8.ToArray(); + public static readonly byte[] XMLelement_asset_id_Start = "asset_id"u8.ToArray(); + + public static readonly byte[] XMLelement_item_id_Empty = "item_id"u8.ToArray(); + public static readonly byte[] XMLelement_item_id_Start = "item_id"u8.ToArray(); + + public static readonly byte[] XMLelement_category_id_Empty = "category_id"u8.ToArray(); + public static readonly byte[] XMLelement_category_id_Start = "category_id"u8.ToArray(); + + public static readonly byte[] XMLelement_version_Empty = "version"u8.ToArray(); + public static readonly byte[] XMLelement_version_Start = "version"u8.ToArray(); + + public static readonly byte[] XMLelement_sale_info_Empty = "sale_infosale_pricesale_type"u8.ToArray(); + public static readonly byte[] XMLelement_sale_info_Start = "sale_infosale_price"u8.ToArray(); + public static readonly byte[] XMLelement_sale_info_Mid = "sale_type"u8.ToArray(); + public static readonly byte[] XMLelement_sale_info_End = ""u8.ToArray(); + + public static readonly byte[] OSUTF8null = "null"u8.ToArray(); + public static readonly byte[] OSUTF8true = "true"u8.ToArray(); + public static readonly byte[] OSUTF8false = "false"u8.ToArray(); public static readonly byte[] base64Bytes = {(byte)'A',(byte)'B',(byte)'C',(byte)'D',(byte)'E',(byte)'F',(byte)'G',(byte)'H',(byte)'I',(byte)'J',(byte)'K',(byte)'L',(byte)'M',(byte)'N',(byte)'O', (byte)'P',(byte)'Q',(byte)'R',(byte)'S',(byte)'T',(byte)'U',(byte)'V',(byte)'W',(byte)'X',(byte)'Y',(byte)'Z',(byte)'a',(byte)'b',(byte)'c',(byte)'d', diff --git a/OpenMetaverseTypes/Quaternion.cs b/OpenMetaverseTypes/Quaternion.cs index 85817fed..1b96c248 100644 --- a/OpenMetaverseTypes/Quaternion.cs +++ b/OpenMetaverseTypes/Quaternion.cs @@ -116,7 +116,7 @@ public Quaternion(Quaternion q) [MethodImpl(MethodImplOptions.AggressiveInlining)] public Quaternion(Vector128 q) : this() { - Unsafe.As>(ref Unsafe.AsRef(this)) = q; + Unsafe.As>(ref this) = q; } [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/Programs/GridProxy/GridProxy.cs b/Programs/GridProxy/GridProxy.cs index 8a259a76..9131e23b 100644 --- a/Programs/GridProxy/GridProxy.cs +++ b/Programs/GridProxy/GridProxy.cs @@ -1053,10 +1053,8 @@ private bool KnownCapDelegate(CapsRequest capReq, CapsStage stage) if (stage == CapsStage.Response) { - if (capReq.Response != null && capReq.Response is OSDMap) + if (capReq.Response is OSDMap map) { - OSDMap map = (OSDMap)capReq.Response; - if (map.ContainsKey("uploader")) { string val = map["uploader"].AsString(); diff --git a/Programs/WinGridProxy/ProxyManager.cs b/Programs/WinGridProxy/ProxyManager.cs index 731b71a7..b96da8e4 100644 --- a/Programs/WinGridProxy/ProxyManager.cs +++ b/Programs/WinGridProxy/ProxyManager.cs @@ -199,6 +199,7 @@ private bool EventQueueGetHandler(CapsRequest req, CapsStage stage) RawResponse = OSDParser.SerializeLLSDXmlBytes(bodyMap), Response = bodyMap }; + capReq.ExtraInfo = $"Event iD {EventID} Message {i + 1}/{events}"; OnEventMessageLog?.Invoke(capReq, CapsStage.Response); diff --git a/Programs/WinGridProxy/SessionTypes.cs b/Programs/WinGridProxy/SessionTypes.cs index 582b3ed9..7b635ca5 100644 --- a/Programs/WinGridProxy/SessionTypes.cs +++ b/Programs/WinGridProxy/SessionTypes.cs @@ -689,7 +689,15 @@ public override string ToPrettyString(Direction direction) if (direction == this.Direction) { IMessage message = null; - OSD osd = OSDParser.Deserialize(this.ResponseBytes); + OSD osd; + try + { + osd = OSDParser.Deserialize(this.ResponseBytes); + } + catch (Exception e) + { + return "Decode failed"; + } OSDMap data = (OSDMap)osd; if (data.ContainsKey("body")) message = MessageUtils.DecodeEvent(this.Name, (OSDMap)data["body"]); diff --git a/Programs/mapgenerator/mapgenerator.cs b/Programs/mapgenerator/mapgenerator.cs index 1275f290..523bbebe 100644 --- a/Programs/mapgenerator/mapgenerator.cs +++ b/Programs/mapgenerator/mapgenerator.cs @@ -384,6 +384,9 @@ static void WritePacketClass(TextWriter writer, MapPacket packet) bool hasVariableBlocks = false; string sanitizedName; + bool hasSessionID = false; + bool hasAgentID = false; + //writer.WriteLine(" /// " + packet.Name + " packet"); writer.WriteLine(" /// "); writer.WriteLine(" public sealed class " + packet.Name + "Packet : Packet" + Environment.NewLine + " {"); @@ -450,19 +453,37 @@ static void WritePacketClass(TextWriter writer, MapPacket packet) //writer.WriteLine(" /// " + block.Name + " block"); writer.WriteLine(" public " + block.Name + "Block" + ((block.Count != 1) ? "[]" : "") + " " + sanitizedName + ";"); + if(block.Name.Equals("AgentData")) + { + foreach (MapField field in block.Fields) + { + if(field.Name == "SessionID") + hasSessionID = true; + else if(field.Name == "AgentID") + hasAgentID = true; + } + } } writer.WriteLine(""); + if (hasSessionID && hasAgentID) + { + writer.WriteLine(" public override bool ValidIDs(UUID session, UUID agent) { return session.Equals(AgentData.SessionID) && agent.Equals(AgentData.AgentID); }"); + writer.WriteLine(); + } + // Default constructor //writer.WriteLine(" /// Default constructor"); writer.WriteLine(" public " + packet.Name + "Packet()" + Environment.NewLine + " {"); - writer.WriteLine(" HasVariableBlocks = " + hasVariableBlocks.ToString().ToLowerInvariant() + ";"); - writer.WriteLine(" Type = PacketType." + packet.Name + ";"); + writer.WriteLine($" HasVariableBlocks = {hasVariableBlocks.ToString().ToLowerInvariant()};"); + writer.WriteLine($" Type = PacketType.{packet.Name};"); writer.WriteLine(" Header = new Header();"); - writer.WriteLine(" Header.Frequency = PacketFrequency." + packet.Frequency + ";"); - writer.WriteLine(" Header.ID = " + packet.ID + ";"); + writer.WriteLine($" Header.Frequency = PacketFrequency.{packet.Frequency};"); + writer.WriteLine($" Header.ID ={packet.ID};"); writer.WriteLine(" Header.Reliable = true;"); // Turn the reliable flag on by default + writer.WriteLine($" NeedValidateIDs = {(hasSessionID && hasAgentID).ToString().ToLowerInvariant()};"); + if (packet.Encoded) { writer.WriteLine(" Header.Zerocoded = true;"); } foreach (MapBlock block in packet.Blocks) { @@ -908,7 +929,7 @@ static void WriteToBytesMultiple(TextWriter writer, MapPacket packet) static int Main(string[] args) { ProtocolManager protocol; - List unused = new(); + HashSet unused = new(); TextWriter writer; try @@ -994,8 +1015,10 @@ static int Main(string[] args) " public abstract void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer);" + Environment.NewLine + " public abstract void FromBytes(Header header, byte[] bytes, ref int i);" + Environment.NewLine + " public abstract byte[] ToBytes();" + Environment.NewLine + - " public abstract byte[][] ToBytesMultiple();" - ); + " public abstract byte[][] ToBytesMultiple();" + Environment.NewLine + + " public bool NeedValidateIDs;" + Environment.NewLine + + " public virtual bool ValidIDs(UUID session, UUID agent) { return true; }" + ); ; writer.WriteLine(); // Write the Packet.GetType() function From 2045c6a4dfd48594058dd6a7becce1d920c3a328 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Fri, 2 May 2025 20:11:53 +0100 Subject: [PATCH 128/149] fix merge --- OpenMetaverse/BitPack.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/OpenMetaverse/BitPack.cs b/OpenMetaverse/BitPack.cs index 0254043c..efcade52 100644 --- a/OpenMetaverse/BitPack.cs +++ b/OpenMetaverse/BitPack.cs @@ -476,7 +476,7 @@ public void PackBitsFromByte(byte inbyte) } OR_BYTESTORE((byte)(inbyte >> bitPos)); ++bytePos; - OR_BYTESTORE((byte)(inbyte << (8 - bitPos))); + BYTESTORE((byte)(inbyte << (8 - bitPos))); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -511,16 +511,16 @@ public void PackBitsFromByte(byte inbyte, int count) if ((inbyte & 0x01 ) != 0) cur |= (byte)(0x80 >> bitPos); + BYTESTORE(cur); ++bitPos; if (bitPos >= MAX_BITS) { bitPos = 0; - - BYTESTORE(cur); - ++bytePos; - if (bytePos < Data.Length) - BYTESTORE(0); + ++bytePos; + if (bytePos < Data.Length) + BYTESTORE(0); + } } /// From 7344aa72110e2e288d39db81690662f9c9d33d5a Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Wed, 18 Jun 2025 15:11:01 +0100 Subject: [PATCH 129/149] include our own fork of Dalhia's PrimMesher --- .../MeshmerizerR.cs | 2 - .../StructuredData.cs | 216 ++ OpenMetaverse/Assets/AssetTypes/AssetMesh.cs | 4 +- PrimMesher/CONTRIBUTORS.txt | 9 + PrimMesher/ObjMesh.cs | 222 ++ PrimMesher/PrimMesher.cs | 2324 +++++++++++++++++ PrimMesher/Properties/AssemblyInfo.cs | 13 + PrimMesher/SculptMap.cs | 193 ++ PrimMesher/SculptMesh.cs | 646 +++++ PrimMesher/VertexIndexer.cs | 184 ++ prebuild.xml | 21 + prebuildCoreLib.xml | 21 + runprebuild.sh | 4 +- 13 files changed, 3853 insertions(+), 6 deletions(-) create mode 100644 PrimMesher/CONTRIBUTORS.txt create mode 100644 PrimMesher/ObjMesh.cs create mode 100644 PrimMesher/PrimMesher.cs create mode 100644 PrimMesher/Properties/AssemblyInfo.cs create mode 100644 PrimMesher/SculptMap.cs create mode 100644 PrimMesher/SculptMesh.cs create mode 100644 PrimMesher/VertexIndexer.cs diff --git a/OpenMetaverse.Rendering.Meshmerizer/MeshmerizerR.cs b/OpenMetaverse.Rendering.Meshmerizer/MeshmerizerR.cs index 1fcb04c0..31415e96 100644 --- a/OpenMetaverse.Rendering.Meshmerizer/MeshmerizerR.cs +++ b/OpenMetaverse.Rendering.Meshmerizer/MeshmerizerR.cs @@ -33,8 +33,6 @@ using System; using System.Collections.Generic; -using System.Drawing; -using System.Text; using OMV = OpenMetaverse; using OMVR = OpenMetaverse.Rendering; diff --git a/OpenMetaverse.StructuredData/StructuredData.cs b/OpenMetaverse.StructuredData/StructuredData.cs index 02aa8859..12a64fa9 100644 --- a/OpenMetaverse.StructuredData/StructuredData.cs +++ b/OpenMetaverse.StructuredData/StructuredData.cs @@ -1755,6 +1755,222 @@ public bool TryGetValue(string key, out OSD llsd) return dicvalue.TryGetValue(key, out llsd); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool TryGetOSDMap(string key, out OSDMap ossd) + { + if (dicvalue.TryGetValue(key, out OSD tmp) && tmp is OSDMap map) + { + ossd = map; + return true; + } + ossd = null; + return false; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool TryGetOSDArray(string key, out OSDArray ossd) + { + if (dicvalue.TryGetValue(key, out OSD tmp) && tmp is OSDArray arr) + { + ossd = arr; + return true; + } + ossd = null; + return false; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool TryGetBool(string key, out bool ossd) + { + if (dicvalue.TryGetValue(key, out OSD tmp)) + { + ossd = tmp.AsBoolean(); + return true; + } + ossd = false; + return false; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool TryGetInt(string key, out int ossd) + { + if (dicvalue.TryGetValue(key, out OSD tmp)) + { + ossd = tmp.AsInteger(); + return true; + } + ossd = 0; + return false; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool TryGetLong(string key, out long ossd) + { + if (dicvalue.TryGetValue(key, out OSD tmp)) + { + ossd = tmp.AsLong(); + return true; + } + ossd = 0; + return false; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool TryGetFloat(string key, out float ossd) + { + if (dicvalue.TryGetValue(key, out OSD tmp)) + { + ossd = (float)tmp.AsReal(); + return true; + } + ossd = 0f; + return false; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool TryGetDouble(string key, out double ossd) + { + if (dicvalue.TryGetValue(key, out OSD tmp)) + { + ossd = tmp.AsReal(); + return true; + } + ossd = 0.0; + return false; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool TryGetString(string key, out string ossd) + { + if (dicvalue.TryGetValue(key, out OSD tmp)) + { + ossd = tmp.AsString(); + return true; + } + ossd = string.Empty; + return false; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool TryGetUUID(string key, out UUID ossd) + { + if (dicvalue.TryGetValue(key, out OSD tmp)) + { + ossd = tmp.AsUUID(); + return true; + } + ossd = UUID.Zero; + return false; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool TryGetDate(string key, out DateTime ossd) + { + if (dicvalue.TryGetValue(key, out OSD tmp)) + { + ossd = tmp.AsDate(); + return true; + } + ossd = Utils.Epoch; + return false; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool TryGetUri(string key, out Uri ossd) + { + if (dicvalue.TryGetValue(key, out OSD tmp)) + { + ossd = tmp.AsUri(); + return true; + } + ossd = null; + return false; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool TryGetBinary(string key, out byte[] ossd) + { + if (dicvalue.TryGetValue(key, out OSD tmp)) + { + ossd = tmp.AsBinary(); + return true; + } + ossd = null; + return false; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool TryGetVector2(string key, out Vector2 ossd) + { + if (dicvalue.TryGetValue(key, out OSD tmp)) + { + ossd = tmp.AsVector2(); + return true; + } + ossd = Vector2.Zero; + return false; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool TryGetVector3(string key, out Vector3 ossd) + { + if (dicvalue.TryGetValue(key, out OSD tmp)) + { + ossd = tmp.AsVector3(); + return true; + } + ossd = Vector3.Zero; + return false; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool TryGetVector3d(string key, out Vector3d ossd) + { + if (dicvalue.TryGetValue(key, out OSD tmp)) + { + ossd = tmp.AsVector3d(); + return true; + } + ossd = Vector3d.Zero; + return false; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool TryGetVector4(string key, out Vector4 ossd) + { + if (dicvalue.TryGetValue(key, out OSD tmp)) + { + ossd = tmp.AsVector4(); + return true; + } + ossd = Vector4.Zero; + return false; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool TryGetQuat(string key, out Quaternion ossd) + { + if (dicvalue.TryGetValue(key, out OSD tmp)) + { + ossd = tmp.AsQuaternion(); + return true; + } + ossd = Quaternion.Identity; + return false; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool TryGetColor4(string key, out Color4 ossd) + { + if (dicvalue.TryGetValue(key, out OSD tmp)) + { + ossd = tmp.AsColor4(); + return true; + } + ossd = Color4.Black; + return false; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public override void Clear() { diff --git a/OpenMetaverse/Assets/AssetTypes/AssetMesh.cs b/OpenMetaverse/Assets/AssetTypes/AssetMesh.cs index 3c76ca3f..164af717 100644 --- a/OpenMetaverse/Assets/AssetTypes/AssetMesh.cs +++ b/OpenMetaverse/Assets/AssetTypes/AssetMesh.cs @@ -69,9 +69,9 @@ public override bool Decode() { try { - MeshData = new OSDMap(); + MeshData = []; - using (MemoryStream data = new MemoryStream(AssetData)) + using (MemoryStream data = new(AssetData)) { OSDMap header = (OSDMap)OSDParser.DeserializeLLSDBinary(data); MeshData["asset_header"] = header; diff --git a/PrimMesher/CONTRIBUTORS.txt b/PrimMesher/CONTRIBUTORS.txt new file mode 100644 index 00000000..cd638b4b --- /dev/null +++ b/PrimMesher/CONTRIBUTORS.txt @@ -0,0 +1,9 @@ +Original primary developer of PrimMesher is Dahlia Trimble. https://github.com/dahliaT/PrimMesher + +Additional contributors (in no particular order): +Morgaine Dinova +Latif Kalifa (lkalif) + +Some portions of PrimMesher are from the following projects: +* OpenSimulator (original extrusion concept) +* LibOpenMetaverse (quaternion multiplication routine) diff --git a/PrimMesher/ObjMesh.cs b/PrimMesher/ObjMesh.cs new file mode 100644 index 00000000..6843d39c --- /dev/null +++ b/PrimMesher/ObjMesh.cs @@ -0,0 +1,222 @@ +/* + * Copyright (c) Contributors + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Text; +using System.Text.RegularExpressions; + +namespace PrimMesher +{ + public class ObjMesh + { + List coords = new List(); + List normals = new List(); + List uvs = new List(); + + public string meshName = string.Empty; + public List> viewerVertices = new List>(); + public List> viewerPolygons = new List>(); + + List faceVertices = new List(); + List facePolygons = new List(); + public int numPrimFaces; + + Dictionary viewerVertexLookup = new Dictionary(); + + public ObjMesh(string path) + { + ProcessStream(new StreamReader(path)); + } + + + public ObjMesh(StreamReader sr) + { + ProcessStream(sr); + } + + + private void ProcessStream(StreamReader s) + { + numPrimFaces = 0; + + while (!s.EndOfStream) + { + string line = s.ReadLine().Trim(); + string[] tokens = Regex.Split(line, @"\s+"); + + // Skip blank lines and comments + if (tokens.Length > 0 && tokens[0] != String.Empty && !tokens[0].StartsWith("#")) + ProcessTokens(tokens); + } + MakePrimFace(); + } + + public VertexIndexer GetVertexIndexer() + { + VertexIndexer vi = new VertexIndexer(); + vi.numPrimFaces = this.numPrimFaces; + vi.viewerPolygons = this.viewerPolygons; + vi.viewerVertices = this.viewerVertices; + + return vi; + } + + + private void ProcessTokens(string[] tokens) + { + switch (tokens[0].ToLower()) + { + case "o": + meshName = tokens[1]; + break; + + case "v": + coords.Add(ParseCoord(tokens)); + break; + + case "vt": + { + uvs.Add(ParseUVCoord(tokens)); + break; + } + + case "vn": + normals.Add(ParseCoord(tokens)); + break; + + case "g": + + MakePrimFace(); + + break; + + case "s": + break; + + case "f": + + int[] vertIndices = new int[3]; + + for (int vertexIndex = 1; vertexIndex <= 3; vertexIndex++) + { + string[] indices = tokens[vertexIndex].Split('/'); + + int positionIndex = int.Parse(indices[0], + CultureInfo.InvariantCulture) - 1; + + int texCoordIndex = -1; + int normalIndex = -1; + + if (indices.Length > 1) + { + + if (int.TryParse(indices[1], System.Globalization.NumberStyles.Integer, CultureInfo.InvariantCulture, out texCoordIndex)) + texCoordIndex--; + else texCoordIndex = -1; + + } + + if (indices.Length > 2) + { + if (int.TryParse(indices[1], System.Globalization.NumberStyles.Integer, CultureInfo.InvariantCulture, out normalIndex)) + normalIndex--; + else normalIndex = -1; + } + + int hash = hashInts(positionIndex, texCoordIndex, normalIndex); + + if (viewerVertexLookup.ContainsKey(hash)) + vertIndices[vertexIndex - 1] = viewerVertexLookup[hash]; + else + { + ViewerVertex vv = new ViewerVertex(); + vv.v = coords[positionIndex]; + if (normalIndex > -1) + vv.n = normals[normalIndex]; + if (texCoordIndex > -1) + vv.uv = uvs[texCoordIndex]; + faceVertices.Add(vv); + vertIndices[vertexIndex - 1] = viewerVertexLookup[hash] = faceVertices.Count - 1; + } + } + + facePolygons.Add(new ViewerPolygon(vertIndices[0], vertIndices[1], vertIndices[2])); + break; + + case "mtllib": + break; + + case "usemtl": + break; + + default: + break; + } + } + + + private void MakePrimFace() + { + if (faceVertices.Count > 0 && facePolygons.Count > 0) + { + viewerVertices.Add(faceVertices); + faceVertices = new List(); + viewerPolygons.Add(facePolygons); + + facePolygons = new List(); + + viewerVertexLookup = new Dictionary(); + + numPrimFaces++; + } + } + + private UVCoord ParseUVCoord(string[] tokens) + { + return new UVCoord( + float.Parse(tokens[1], CultureInfo.InvariantCulture), + float.Parse(tokens[1], CultureInfo.InvariantCulture)); + } + + private Coord ParseCoord(string[] tokens) + { + return new Coord( + float.Parse(tokens[1], CultureInfo.InvariantCulture), + float.Parse(tokens[2], CultureInfo.InvariantCulture), + float.Parse(tokens[3], CultureInfo.InvariantCulture)); + } + + private int hashInts(int i1, int i2, int i3) + { + return (i1.ToString() + " " + i2.ToString() + " " + i3.ToString()).GetHashCode(); + } + } +} diff --git a/PrimMesher/PrimMesher.cs b/PrimMesher/PrimMesher.cs new file mode 100644 index 00000000..c6892ce0 --- /dev/null +++ b/PrimMesher/PrimMesher.cs @@ -0,0 +1,2324 @@ +/* + * Copyright (c) Contributors + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using System.IO; + +namespace PrimMesher +{ + public struct Quat + { + /// X value + public float X; + /// Y value + public float Y; + /// Z value + public float Z; + /// W value + public float W; + + public Quat(float x, float y, float z, float w) + { + X = x; + Y = y; + Z = z; + W = w; + } + + public Quat(Coord axis, float angle) + { + axis = axis.Normalize(); + + angle *= 0.5f; + float c = (float)Math.Cos(angle); + float s = (float)Math.Sin(angle); + + X = axis.X * s; + Y = axis.Y * s; + Z = axis.Z * s; + W = c; + + Normalize(); + } + + public float Length() + { + return (float)Math.Sqrt(X * X + Y * Y + Z * Z + W * W); + } + + public Quat Normalize() + { + const float MAG_THRESHOLD = 0.0000001f; + float mag = Length(); + + // Catch very small rounding errors when normalizing + if (mag > MAG_THRESHOLD) + { + float oomag = 1f / mag; + X *= oomag; + Y *= oomag; + Z *= oomag; + W *= oomag; + } + else + { + X = 0f; + Y = 0f; + Z = 0f; + W = 1f; + } + + return this; + } + + public static Quat operator *(Quat q1, Quat q2) + { + float x = q1.W * q2.X + q1.X * q2.W + q1.Y * q2.Z - q1.Z * q2.Y; + float y = q1.W * q2.Y - q1.X * q2.Z + q1.Y * q2.W + q1.Z * q2.X; + float z = q1.W * q2.Z + q1.X * q2.Y - q1.Y * q2.X + q1.Z * q2.W; + float w = q1.W * q2.W - q1.X * q2.X - q1.Y * q2.Y - q1.Z * q2.Z; + return new Quat(x, y, z, w); + } + + public override string ToString() + { + return "< X: " + this.X.ToString() + ", Y: " + this.Y.ToString() + ", Z: " + this.Z.ToString() + ", W: " + this.W.ToString() + ">"; + } + } + + public struct Coord + { + public float X; + public float Y; + public float Z; + + public Coord(float x, float y, float z) + { + this.X = x; + this.Y = y; + this.Z = z; + } + + public float Length() + { + return (float)Math.Sqrt(this.X * this.X + this.Y * this.Y + this.Z * this.Z); + } + + public Coord Invert() + { + this.X = -this.X; + this.Y = -this.Y; + this.Z = -this.Z; + + return this; + } + + public Coord Normalize() + { + const float MAG_THRESHOLD = 0.0000001f; + float mag = Length(); + + // Catch very small rounding errors when normalizing + if (mag > MAG_THRESHOLD) + { + float oomag = 1.0f / mag; + this.X *= oomag; + this.Y *= oomag; + this.Z *= oomag; + } + else + { + this.X = 0.0f; + this.Y = 0.0f; + this.Z = 0.0f; + } + + return this; + } + + public override string ToString() + { + return this.X.ToString() + " " + this.Y.ToString() + " " + this.Z.ToString(); + } + + public static Coord Cross(Coord c1, Coord c2) + { + return new Coord( + c1.Y * c2.Z - c2.Y * c1.Z, + c1.Z * c2.X - c2.Z * c1.X, + c1.X * c2.Y - c2.X * c1.Y + ); + } + + public static Coord operator +(Coord v, Coord a) + { + return new Coord(v.X + a.X, v.Y + a.Y, v.Z + a.Z); + } + + public static Coord operator *(Coord v, Coord m) + { + return new Coord(v.X * m.X, v.Y * m.Y, v.Z * m.Z); + } + + public static Coord operator *(Coord v, Quat q) + { + // From http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/transforms/ + + Coord c2 = new Coord(0.0f, 0.0f, 0.0f); + + c2.X = q.W * q.W * v.X + + 2f * q.Y * q.W * v.Z - + 2f * q.Z * q.W * v.Y + + q.X * q.X * v.X + + 2f * q.Y * q.X * v.Y + + 2f * q.Z * q.X * v.Z - + q.Z * q.Z * v.X - + q.Y * q.Y * v.X; + + c2.Y = + 2f * q.X * q.Y * v.X + + q.Y * q.Y * v.Y + + 2f * q.Z * q.Y * v.Z + + 2f * q.W * q.Z * v.X - + q.Z * q.Z * v.Y + + q.W * q.W * v.Y - + 2f * q.X * q.W * v.Z - + q.X * q.X * v.Y; + + c2.Z = + 2f * q.X * q.Z * v.X + + 2f * q.Y * q.Z * v.Y + + q.Z * q.Z * v.Z - + 2f * q.W * q.Y * v.X - + q.Y * q.Y * v.Z + + 2f * q.W * q.X * v.Y - + q.X * q.X * v.Z + + q.W * q.W * v.Z; + + return c2; + } + } + + public struct UVCoord + { + public float U; + public float V; + + + public UVCoord(float u, float v) + { + this.U = u; + this.V = v; + } + + public UVCoord Flip() + { + this.U = 1.0f - this.U; + this.V = 1.0f - this.V; + return this; + } + } + + public struct Face + { + public int primFace; + + // vertices + public int v1; + public int v2; + public int v3; + + //normals + public int n1; + public int n2; + public int n3; + + // uvs + public int uv1; + public int uv2; + public int uv3; + + public Face(int v1, int v2, int v3) + { + primFace = 0; + + this.v1 = v1; + this.v2 = v2; + this.v3 = v3; + + this.n1 = 0; + this.n2 = 0; + this.n3 = 0; + + this.uv1 = 0; + this.uv2 = 0; + this.uv3 = 0; + + } + + public Face(int v1, int v2, int v3, int n1, int n2, int n3) + { + primFace = 0; + + this.v1 = v1; + this.v2 = v2; + this.v3 = v3; + + this.n1 = n1; + this.n2 = n2; + this.n3 = n3; + + this.uv1 = 0; + this.uv2 = 0; + this.uv3 = 0; + } + + public Coord SurfaceNormal(List coordList) + { + Coord c1 = coordList[this.v1]; + Coord c2 = coordList[this.v2]; + Coord c3 = coordList[this.v3]; + + Coord edge1 = new Coord(c2.X - c1.X, c2.Y - c1.Y, c2.Z - c1.Z); + Coord edge2 = new Coord(c3.X - c1.X, c3.Y - c1.Y, c3.Z - c1.Z); + + return Coord.Cross(edge1, edge2).Normalize(); + } + } + + public struct ViewerFace + { + public int primFaceNumber; + + public Coord v1; + public Coord v2; + public Coord v3; + + public int coordIndex1; + public int coordIndex2; + public int coordIndex3; + + public Coord n1; + public Coord n2; + public Coord n3; + + public UVCoord uv1; + public UVCoord uv2; + public UVCoord uv3; + + public ViewerFace(int primFaceNumber) + { + this.primFaceNumber = primFaceNumber; + + this.v1 = new Coord(); + this.v2 = new Coord(); + this.v3 = new Coord(); + + this.coordIndex1 = this.coordIndex2 = this.coordIndex3 = -1; // -1 means not assigned yet + + this.n1 = new Coord(); + this.n2 = new Coord(); + this.n3 = new Coord(); + + this.uv1 = new UVCoord(); + this.uv2 = new UVCoord(); + this.uv3 = new UVCoord(); + } + + public void Scale(float x, float y, float z) + { + this.v1.X *= x; + this.v1.Y *= y; + this.v1.Z *= z; + + this.v2.X *= x; + this.v2.Y *= y; + this.v2.Z *= z; + + this.v3.X *= x; + this.v3.Y *= y; + this.v3.Z *= z; + } + + public void AddPos(float x, float y, float z) + { + this.v1.X += x; + this.v2.X += x; + this.v3.X += x; + + this.v1.Y += y; + this.v2.Y += y; + this.v3.Y += y; + + this.v1.Z += z; + this.v2.Z += z; + this.v3.Z += z; + } + + public void AddRot(Quat q) + { + this.v1 *= q; + this.v2 *= q; + this.v3 *= q; + + this.n1 *= q; + this.n2 *= q; + this.n3 *= q; + } + + public void CalcSurfaceNormal() + { + + Coord edge1 = new Coord(this.v2.X - this.v1.X, this.v2.Y - this.v1.Y, this.v2.Z - this.v1.Z); + Coord edge2 = new Coord(this.v3.X - this.v1.X, this.v3.Y - this.v1.Y, this.v3.Z - this.v1.Z); + + this.n1 = this.n2 = this.n3 = Coord.Cross(edge1, edge2).Normalize(); + } + } + + internal struct Angle + { + internal float angle; + internal float X; + internal float Y; + + internal Angle(float angle, float x, float y) + { + this.angle = angle; + this.X = x; + this.Y = y; + } + } + + internal class AngleList + { + private float iX, iY; // intersection point + + private static Angle[] angles3 = + { + new Angle(0.0f, 1.0f, 0.0f), + new Angle(0.33333333333333333f, -0.5f, 0.86602540378443871f), + new Angle(0.66666666666666667f, -0.5f, -0.86602540378443837f), + new Angle(1.0f, 1.0f, 0.0f) + }; + + private static Coord[] normals3 = + { + new Coord(0.25f, 0.4330127019f, 0.0f).Normalize(), + new Coord(-0.5f, 0.0f, 0.0f).Normalize(), + new Coord(0.25f, -0.4330127019f, 0.0f).Normalize(), + new Coord(0.25f, 0.4330127019f, 0.0f).Normalize() + }; + + private static Angle[] angles4 = + { + new Angle(0.0f, 1.0f, 0.0f), + new Angle(0.25f, 0.0f, 1.0f), + new Angle(0.5f, -1.0f, 0.0f), + new Angle(0.75f, 0.0f, -1.0f), + new Angle(1.0f, 1.0f, 0.0f) + }; + + private static Coord[] normals4 = + { + new Coord(0.5f, 0.5f, 0.0f).Normalize(), + new Coord(-0.5f, 0.5f, 0.0f).Normalize(), + new Coord(-0.5f, -0.5f, 0.0f).Normalize(), + new Coord(0.5f, -0.5f, 0.0f).Normalize(), + new Coord(0.5f, 0.5f, 0.0f).Normalize() + }; + + private static Angle[] angles24 = + { + new Angle(0.0f, 1.0f, 0.0f), + new Angle(0.041666666666666664f, 0.96592582628906831f, 0.25881904510252074f), + new Angle(0.083333333333333329f, 0.86602540378443871f, 0.5f), + new Angle(0.125f, 0.70710678118654757f, 0.70710678118654746f), + new Angle(0.16666666666666667f, 0.5f, 0.8660254037844386f), + new Angle(0.20833333333333331f, 0.25881904510252096f, 0.9659258262890682f), + new Angle(0.25f, 0.0f, 1.0f), + new Angle(0.29166666666666663f, -0.25881904510252063f, 0.96592582628906831f), + new Angle(0.33333333333333333f, -0.5f, 0.86602540378443871f), + new Angle(0.375f, -0.70710678118654746f, 0.70710678118654757f), + new Angle(0.41666666666666663f, -0.86602540378443849f, 0.5f), + new Angle(0.45833333333333331f, -0.9659258262890682f, 0.25881904510252102f), + new Angle(0.5f, -1.0f, 0.0f), + new Angle(0.54166666666666663f, -0.96592582628906842f, -0.25881904510252035f), + new Angle(0.58333333333333326f, -0.86602540378443882f, -0.5f), + new Angle(0.62499999999999989f, -0.70710678118654791f, -0.70710678118654713f), + new Angle(0.66666666666666667f, -0.5f, -0.86602540378443837f), + new Angle(0.70833333333333326f, -0.25881904510252152f, -0.96592582628906809f), + new Angle(0.75f, 0.0f, -1.0f), + new Angle(0.79166666666666663f, 0.2588190451025203f, -0.96592582628906842f), + new Angle(0.83333333333333326f, 0.5f, -0.86602540378443904f), + new Angle(0.875f, 0.70710678118654735f, -0.70710678118654768f), + new Angle(0.91666666666666663f, 0.86602540378443837f, -0.5f), + new Angle(0.95833333333333326f, 0.96592582628906809f, -0.25881904510252157f), + new Angle(1.0f, 1.0f, 0.0f) + }; + + private Angle interpolatePoints(float newPoint, Angle p1, Angle p2) + { + float m = (newPoint - p1.angle) / (p2.angle - p1.angle); + return new Angle(newPoint, p1.X + m * (p2.X - p1.X), p1.Y + m * (p2.Y - p1.Y)); + } + + private void intersection(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4) + { // ref: http://local.wasp.uwa.edu.au/~pbourke/geometry/lineline2d/ + double denom = (y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1); + double uaNumerator = (x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3); + + if (denom != 0.0) + { + double ua = uaNumerator / denom; + iX = (float)(x1 + ua * (x2 - x1)); + iY = (float)(y1 + ua * (y2 - y1)); + } + } + + internal List angles; + internal List normals; + + internal void makeAngles(int sides, float startAngle, float stopAngle) + { + angles = new List(); + normals = new List(); + + double twoPi = System.Math.PI * 2.0; + float twoPiInv = 1.0f / (float)twoPi; + + if (sides < 1) + throw new Exception("number of sides not greater than zero"); + if (stopAngle <= startAngle) + throw new Exception("stopAngle not greater than startAngle"); + + if ((sides == 3 || sides == 4 || sides == 24)) + { + startAngle *= twoPiInv; + stopAngle *= twoPiInv; + + Angle[] sourceAngles; + if (sides == 3) + sourceAngles = angles3; + else if (sides == 4) + sourceAngles = angles4; + else sourceAngles = angles24; + + int startAngleIndex = (int)(startAngle * sides); + int endAngleIndex = sourceAngles.Length - 1; + if (stopAngle < 1.0f) + endAngleIndex = (int)(stopAngle * sides) + 1; + if (endAngleIndex == startAngleIndex) + endAngleIndex++; + + for (int angleIndex = startAngleIndex; angleIndex < endAngleIndex + 1; angleIndex++) + { + angles.Add(sourceAngles[angleIndex]); + if (sides == 3) + normals.Add(normals3[angleIndex]); + else if (sides == 4) + normals.Add(normals4[angleIndex]); + } + + if (startAngle > 0.0f) + angles[0] = interpolatePoints(startAngle, angles[0], angles[1]); + + if (stopAngle < 1.0f) + { + int lastAngleIndex = angles.Count - 1; + angles[lastAngleIndex] = interpolatePoints(stopAngle, angles[lastAngleIndex - 1], angles[lastAngleIndex]); + } + } + else + { + double stepSize = twoPi / sides; + + int startStep = (int)(startAngle / stepSize); + double angle = stepSize * startStep; + int step = startStep; + double stopAngleTest = stopAngle; + if (stopAngle < twoPi) + { + stopAngleTest = stepSize * ((int)(stopAngle / stepSize) + 1); + if (stopAngleTest < stopAngle) + stopAngleTest += stepSize; + if (stopAngleTest > twoPi) + stopAngleTest = twoPi; + } + + while (angle <= stopAngleTest) + { + Angle newAngle; + newAngle.angle = (float)angle; + newAngle.X = (float)System.Math.Cos(angle); + newAngle.Y = (float)System.Math.Sin(angle); + angles.Add(newAngle); + step += 1; + angle = stepSize * step; + } + + if (startAngle > angles[0].angle) + { + Angle newAngle; + intersection(angles[0].X, angles[0].Y, angles[1].X, angles[1].Y, 0.0f, 0.0f, (float)Math.Cos(startAngle), (float)Math.Sin(startAngle)); + newAngle.angle = startAngle; + newAngle.X = iX; + newAngle.Y = iY; + angles[0] = newAngle; + } + + int index = angles.Count - 1; + if (stopAngle < angles[index].angle) + { + Angle newAngle; + intersection(angles[index - 1].X, angles[index - 1].Y, angles[index].X, angles[index].Y, 0.0f, 0.0f, (float)Math.Cos(stopAngle), (float)Math.Sin(stopAngle)); + newAngle.angle = stopAngle; + newAngle.X = iX; + newAngle.Y = iY; + angles[index] = newAngle; + } + } + } + } + + /// + /// generates a profile for extrusion + /// + public class Profile + { + private const float twoPi = 2.0f * (float)Math.PI; + + public string errorMessage = null; + + public List coords; + public List faces; + public List vertexNormals; + public List us; + public List faceUVs; + public List faceNumbers; + + // use these for making individual meshes for each prim face + public List outerCoordIndices = null; + public List hollowCoordIndices = null; + public List cut1CoordIndices = null; + public List cut2CoordIndices = null; + + public Coord faceNormal = new Coord(0.0f, 0.0f, 1.0f); + public Coord cutNormal1 = new Coord(); + public Coord cutNormal2 = new Coord(); + + public int numOuterVerts = 0; + public int numHollowVerts = 0; + + public int outerFaceNumber = -1; + public int hollowFaceNumber = -1; + + public bool calcVertexNormals = false; + public int bottomFaceNumber = 0; + public int numPrimFaces = 0; + + public Profile() + { + this.coords = new List(); + this.faces = new List(); + this.vertexNormals = new List(); + this.us = new List(); + this.faceUVs = new List(); + this.faceNumbers = new List(); + } + + public Profile(int sides, float profileStart, float profileEnd, float hollow, int hollowSides, bool createFaces, bool calcVertexNormals) + { + this.calcVertexNormals = calcVertexNormals; + this.coords = new List(); + this.faces = new List(); + this.vertexNormals = new List(); + this.us = new List(); + this.faceUVs = new List(); + this.faceNumbers = new List(); + + Coord center = new Coord(0.0f, 0.0f, 0.0f); + + List hollowCoords = new List(); + List hollowNormals = new List(); + List hollowUs = new List(); + + if (calcVertexNormals) + { + this.outerCoordIndices = new List(); + this.hollowCoordIndices = new List(); + this.cut1CoordIndices = new List(); + this.cut2CoordIndices = new List(); + } + + bool hasHollow = (hollow > 0.0f); + + bool hasProfileCut = (profileStart > 0.0f || profileEnd < 1.0f); + + AngleList angles = new AngleList(); + AngleList hollowAngles = new AngleList(); + + float xScale = 0.5f; + float yScale = 0.5f; + if (sides == 4) // corners of a square are sqrt(2) from center + { + xScale = 0.707107f; + yScale = 0.707107f; + } + + float startAngle = profileStart * twoPi; + float stopAngle = profileEnd * twoPi; + + try { angles.makeAngles(sides, startAngle, stopAngle); } + catch (Exception ex) + { + + errorMessage = "makeAngles failed: Exception: " + ex.ToString() + + "\nsides: " + sides.ToString() + " startAngle: " + startAngle.ToString() + " stopAngle: " + stopAngle.ToString(); + + return; + } + + this.numOuterVerts = angles.angles.Count; + + // flag to create as few triangles as possible for 3 or 4 side profile + bool simpleFace = (sides < 5 && !hasHollow && !hasProfileCut); + + if (hasHollow) + { + if (sides == hollowSides) + hollowAngles = angles; + else + { + try { hollowAngles.makeAngles(hollowSides, startAngle, stopAngle); } + catch (Exception ex) + { + errorMessage = "makeAngles failed: Exception: " + ex.ToString() + + "\nsides: " + sides.ToString() + " startAngle: " + startAngle.ToString() + " stopAngle: " + stopAngle.ToString(); + + return; + } + } + this.numHollowVerts = hollowAngles.angles.Count; + } + else if (!simpleFace) + { + this.coords.Add(center); + if (this.calcVertexNormals) + this.vertexNormals.Add(new Coord(0.0f, 0.0f, 1.0f)); + this.us.Add(0.0f); + } + + float z = 0.0f; + + Angle angle; + Coord newVert = new Coord(); + if (hasHollow && hollowSides != sides) + { + int numHollowAngles = hollowAngles.angles.Count; + for (int i = 0; i < numHollowAngles; i++) + { + angle = hollowAngles.angles[i]; + newVert.X = hollow * xScale * angle.X; + newVert.Y = hollow * yScale * angle.Y; + newVert.Z = z; + + hollowCoords.Add(newVert); + if (this.calcVertexNormals) + { + if (hollowSides < 5) + hollowNormals.Add(hollowAngles.normals[i].Invert()); + else + hollowNormals.Add(new Coord(-angle.X, -angle.Y, 0.0f)); + + if (hollowSides == 4) + hollowUs.Add(angle.angle * hollow * 0.707107f); + else + hollowUs.Add(angle.angle * hollow); + } + } + } + + int index = 0; + int numAngles = angles.angles.Count; + + for (int i = 0; i < numAngles; i++) + { + angle = angles.angles[i]; + newVert.X = angle.X * xScale; + newVert.Y = angle.Y * yScale; + newVert.Z = z; + this.coords.Add(newVert); + if (this.calcVertexNormals) + { + this.outerCoordIndices.Add(this.coords.Count - 1); + + if (sides < 5) + { + this.vertexNormals.Add(angles.normals[i]); + float u = angle.angle; + this.us.Add(u); + } + else + { + this.vertexNormals.Add(new Coord(angle.X, angle.Y, 0.0f)); + this.us.Add(angle.angle); + } + } + + if (hasHollow) + { + if (hollowSides == sides) + { + newVert.X *= hollow; + newVert.Y *= hollow; + newVert.Z = z; + hollowCoords.Add(newVert); + if (this.calcVertexNormals) + { + if (sides < 5) + { + hollowNormals.Add(angles.normals[i].Invert()); + } + + else + hollowNormals.Add(new Coord(-angle.X, -angle.Y, 0.0f)); + + hollowUs.Add(angle.angle * hollow); + } + } + } + else if (!simpleFace && createFaces && angle.angle > 0.0001f) + { + Face newFace = new Face(); + newFace.v1 = 0; + newFace.v2 = index; + newFace.v3 = index + 1; + + this.faces.Add(newFace); + } + index += 1; + } + + if (hasHollow) + { + hollowCoords.Reverse(); + if (this.calcVertexNormals) + { + hollowNormals.Reverse(); + hollowUs.Reverse(); + } + + if (createFaces) + { + int numTotalVerts = this.numOuterVerts + this.numHollowVerts; + + if (this.numOuterVerts == this.numHollowVerts) + { + Face newFace = new Face(); + + for (int coordIndex = 0; coordIndex < this.numOuterVerts - 1; coordIndex++) + { + newFace.v1 = coordIndex; + newFace.v2 = coordIndex + 1; + newFace.v3 = numTotalVerts - coordIndex - 1; + this.faces.Add(newFace); + + newFace.v1 = coordIndex + 1; + newFace.v2 = numTotalVerts - coordIndex - 2; + newFace.v3 = numTotalVerts - coordIndex - 1; + this.faces.Add(newFace); + } + } + else + { + if (this.numOuterVerts < this.numHollowVerts) + { + Face newFace = new Face(); + int j = 0; // j is the index for outer vertices + int maxJ = this.numOuterVerts - 1; + for (int i = 0; i < this.numHollowVerts; i++) // i is the index for inner vertices + { + if (j < maxJ) + if (angles.angles[j + 1].angle - hollowAngles.angles[i].angle < hollowAngles.angles[i].angle - angles.angles[j].angle + 0.000001f) + { + newFace.v1 = numTotalVerts - i - 1; + newFace.v2 = j; + newFace.v3 = j + 1; + + this.faces.Add(newFace); + j += 1; + } + + newFace.v1 = j; + newFace.v2 = numTotalVerts - i - 2; + newFace.v3 = numTotalVerts - i - 1; + + this.faces.Add(newFace); + } + } + else // numHollowVerts < numOuterVerts + { + Face newFace = new Face(); + int j = 0; // j is the index for inner vertices + int maxJ = this.numHollowVerts - 1; + for (int i = 0; i < this.numOuterVerts; i++) + { + if (j < maxJ) + if (hollowAngles.angles[j + 1].angle - angles.angles[i].angle < angles.angles[i].angle - hollowAngles.angles[j].angle + 0.000001f) + { + newFace.v1 = i; + newFace.v2 = numTotalVerts - j - 2; + newFace.v3 = numTotalVerts - j - 1; + + this.faces.Add(newFace); + j += 1; + } + + newFace.v1 = numTotalVerts - j - 1; + newFace.v2 = i; + newFace.v3 = i + 1; + + this.faces.Add(newFace); + } + } + } + } + + if (calcVertexNormals) + { + foreach (Coord hc in hollowCoords) + { + this.coords.Add(hc); + hollowCoordIndices.Add(this.coords.Count - 1); + } + } + else + this.coords.AddRange(hollowCoords); + + if (this.calcVertexNormals) + { + this.vertexNormals.AddRange(hollowNormals); + this.us.AddRange(hollowUs); + + } + } + + if (simpleFace && createFaces) + { + if (sides == 3) + this.faces.Add(new Face(0, 1, 2)); + else if (sides == 4) + { + this.faces.Add(new Face(0, 1, 2)); + this.faces.Add(new Face(0, 2, 3)); + } + } + + if (calcVertexNormals && hasProfileCut) + { + int lastOuterVertIndex = this.numOuterVerts - 1; + + if (hasHollow) + { + this.cut1CoordIndices.Add(0); + this.cut1CoordIndices.Add(this.coords.Count - 1); + + this.cut2CoordIndices.Add(lastOuterVertIndex + 1); + this.cut2CoordIndices.Add(lastOuterVertIndex); + + this.cutNormal1.X = this.coords[0].Y - this.coords[this.coords.Count - 1].Y; + this.cutNormal1.Y = -(this.coords[0].X - this.coords[this.coords.Count - 1].X); + + this.cutNormal2.X = this.coords[lastOuterVertIndex + 1].Y - this.coords[lastOuterVertIndex].Y; + this.cutNormal2.Y = -(this.coords[lastOuterVertIndex + 1].X - this.coords[lastOuterVertIndex].X); + } + + else + { + this.cut1CoordIndices.Add(0); + this.cut1CoordIndices.Add(1); + + this.cut2CoordIndices.Add(lastOuterVertIndex); + this.cut2CoordIndices.Add(0); + + this.cutNormal1.X = this.vertexNormals[1].Y; + this.cutNormal1.Y = -this.vertexNormals[1].X; + + this.cutNormal2.X = -this.vertexNormals[this.vertexNormals.Count - 2].Y; + this.cutNormal2.Y = this.vertexNormals[this.vertexNormals.Count - 2].X; + + } + this.cutNormal1.Normalize(); + this.cutNormal2.Normalize(); + } + + this.MakeFaceUVs(); + + hollowCoords = null; + hollowNormals = null; + hollowUs = null; + + if (calcVertexNormals) + { // calculate prim face numbers + + // face number order is top, outer, hollow, bottom, start cut, end cut + // I know it's ugly but so is the whole concept of prim face numbers + + int faceNum = 1; // start with outer faces + this.outerFaceNumber = faceNum; + + int startVert = hasProfileCut && !hasHollow ? 1 : 0; + if (startVert > 0) + this.faceNumbers.Add(-1); + for (int i = 0; i < this.numOuterVerts - 1; i++) + this.faceNumbers.Add(sides < 5 && i <= sides ? faceNum++ : faceNum); + + this.faceNumbers.Add(hasProfileCut ? -1 : faceNum++); + + if (sides > 4 && (hasHollow || hasProfileCut)) + faceNum++; + + if (sides < 5 && (hasHollow || hasProfileCut) && this.numOuterVerts < sides) + faceNum++; + + if (hasHollow) + { + for (int i = 0; i < this.numHollowVerts; i++) + this.faceNumbers.Add(faceNum); + + this.hollowFaceNumber = faceNum++; + } + + this.bottomFaceNumber = faceNum++; + + if (hasHollow && hasProfileCut) + this.faceNumbers.Add(faceNum++); + + for (int i = 0; i < this.faceNumbers.Count; i++) + if (this.faceNumbers[i] == -1) + this.faceNumbers[i] = faceNum++; + + this.numPrimFaces = faceNum; + } + + } + + public void MakeFaceUVs() + { + this.faceUVs = new List(); + foreach (Coord c in this.coords) + this.faceUVs.Add(new UVCoord(1.0f - (0.5f + c.X), 1.0f - (0.5f - c.Y))); + } + + public Profile Copy() + { + return this.Copy(true); + } + + public Profile Copy(bool needFaces) + { + Profile copy = new Profile(); + + copy.coords.AddRange(this.coords); + copy.faceUVs.AddRange(this.faceUVs); + + if (needFaces) + copy.faces.AddRange(this.faces); + if ((copy.calcVertexNormals = this.calcVertexNormals) == true) + { + copy.vertexNormals.AddRange(this.vertexNormals); + copy.faceNormal = this.faceNormal; + copy.cutNormal1 = this.cutNormal1; + copy.cutNormal2 = this.cutNormal2; + copy.us.AddRange(this.us); + copy.faceNumbers.AddRange(this.faceNumbers); + + copy.cut1CoordIndices = new List(this.cut1CoordIndices); + copy.cut2CoordIndices = new List(this.cut2CoordIndices); + copy.hollowCoordIndices = new List(this.hollowCoordIndices); + copy.outerCoordIndices = new List(this.outerCoordIndices); + } + copy.numOuterVerts = this.numOuterVerts; + copy.numHollowVerts = this.numHollowVerts; + + return copy; + } + + public void AddPos(Coord v) + { + this.AddPos(v.X, v.Y, v.Z); + } + + public void AddPos(float x, float y, float z) + { + int i; + int numVerts = this.coords.Count; + Coord vert; + + for (i = 0; i < numVerts; i++) + { + vert = this.coords[i]; + vert.X += x; + vert.Y += y; + vert.Z += z; + this.coords[i] = vert; + } + } + + public void AddRot(Quat q) + { + int i; + int numVerts = this.coords.Count; + + for (i = 0; i < numVerts; i++) + this.coords[i] *= q; + + if (this.calcVertexNormals) + { + int numNormals = this.vertexNormals.Count; + for (i = 0; i < numNormals; i++) + this.vertexNormals[i] *= q; + + this.faceNormal *= q; + this.cutNormal1 *= q; + this.cutNormal2 *= q; + + } + } + + public void Scale(float x, float y) + { + int i; + int numVerts = this.coords.Count; + Coord vert; + + for (i = 0; i < numVerts; i++) + { + vert = this.coords[i]; + vert.X *= x; + vert.Y *= y; + this.coords[i] = vert; + } + } + + /// + /// Changes order of the vertex indices and negates the center vertex normal. Does not alter vertex normals of radial vertices + /// + public void FlipNormals() + { + int i; + int numFaces = this.faces.Count; + Face tmpFace; + int tmp; + + for (i = 0; i < numFaces; i++) + { + tmpFace = this.faces[i]; + tmp = tmpFace.v3; + tmpFace.v3 = tmpFace.v1; + tmpFace.v1 = tmp; + this.faces[i] = tmpFace; + } + + if (this.calcVertexNormals) + { + int normalCount = this.vertexNormals.Count; + if (normalCount > 0) + { + Coord n = this.vertexNormals[normalCount - 1]; + n.Z = -n.Z; + this.vertexNormals[normalCount - 1] = n; + } + } + + this.faceNormal.X = -this.faceNormal.X; + this.faceNormal.Y = -this.faceNormal.Y; + this.faceNormal.Z = -this.faceNormal.Z; + + int numfaceUVs = this.faceUVs.Count; + for (i = 0; i < numfaceUVs; i++) + { + UVCoord uv = this.faceUVs[i]; + uv.V = 1.0f - uv.V; + this.faceUVs[i] = uv; + } + } + + public void AddValue2FaceVertexIndices(int num) + { + int numFaces = this.faces.Count; + Face tmpFace; + for (int i = 0; i < numFaces; i++) + { + tmpFace = this.faces[i]; + tmpFace.v1 += num; + tmpFace.v2 += num; + tmpFace.v3 += num; + + this.faces[i] = tmpFace; + } + } + + public void AddValue2FaceNormalIndices(int num) + { + if (this.calcVertexNormals) + { + int numFaces = this.faces.Count; + Face tmpFace; + for (int i = 0; i < numFaces; i++) + { + tmpFace = this.faces[i]; + tmpFace.n1 += num; + tmpFace.n2 += num; + tmpFace.n3 += num; + + this.faces[i] = tmpFace; + } + } + } + + public void DumpRaw(String path, String name, String title) + { + if (path == null) + return; + String fileName = name + "_" + title + ".raw"; + String completePath = System.IO.Path.Combine(path, fileName); + StreamWriter sw = new StreamWriter(completePath); + + for (int i = 0; i < this.faces.Count; i++) + { + string s = this.coords[this.faces[i].v1].ToString(); + s += " " + this.coords[this.faces[i].v2].ToString(); + s += " " + this.coords[this.faces[i].v3].ToString(); + + sw.WriteLine(s); + } + + sw.Close(); + } + } + + public struct PathNode + { + public Coord position; + public Quat rotation; + public float xScale; + public float yScale; + public float percentOfPath; + } + + public enum PathType { Linear = 0, Circular = 1, Flexible = 2 } + + public class Path + { + public List pathNodes = new List(); + + public float twistBegin = 0.0f; + public float twistEnd = 0.0f; + public float topShearX = 0.0f; + public float topShearY = 0.0f; + public float pathCutBegin = 0.0f; + public float pathCutEnd = 1.0f; + public float dimpleBegin = 0.0f; + public float dimpleEnd = 1.0f; + public float skew = 0.0f; + public float holeSizeX = 1.0f; // called pathScaleX in pbs + public float holeSizeY = 0.25f; + public float taperX = 0.0f; + public float taperY = 0.0f; + public float radius = 0.0f; + public float revolutions = 1.0f; + public int stepsPerRevolution = 24; + + private const float twoPi = 2.0f * (float)Math.PI; + + public void Create(PathType pathType, int steps) + { + if (this.taperX > 0.999f) + this.taperX = 0.999f; + if (this.taperX < -0.999f) + this.taperX = -0.999f; + if (this.taperY > 0.999f) + this.taperY = 0.999f; + if (this.taperY < -0.999f) + this.taperY = -0.999f; + + if (pathType == PathType.Linear || pathType == PathType.Flexible) + { + int step = 0; + + float length = this.pathCutEnd - this.pathCutBegin; + float twistTotal = twistEnd - twistBegin; + float twistTotalAbs = Math.Abs(twistTotal); + if (twistTotalAbs > 0.01f) + steps += (int)(twistTotalAbs * 3.66); // dahlia's magic number + + float start = -0.5f; + float stepSize = length / (float)steps; + float percentOfPathMultiplier = stepSize * 0.999999f; + float xOffset = this.topShearX * this.pathCutBegin; + float yOffset = this.topShearY * this.pathCutBegin; + float zOffset = start; + float xOffsetStepIncrement = this.topShearX * length / steps; + float yOffsetStepIncrement = this.topShearY * length / steps; + + float percentOfPath = this.pathCutBegin; + zOffset += percentOfPath; + + // sanity checks + + bool done = false; + + while (!done) + { + PathNode newNode = new PathNode(); + + newNode.xScale = 1.0f; + if (this.taperX == 0.0f) + newNode.xScale = 1.0f; + else if (this.taperX > 0.0f) + newNode.xScale = 1.0f - percentOfPath * this.taperX; + else newNode.xScale = 1.0f + (1.0f - percentOfPath) * this.taperX; + + newNode.yScale = 1.0f; + if (this.taperY == 0.0f) + newNode.yScale = 1.0f; + else if (this.taperY > 0.0f) + newNode.yScale = 1.0f - percentOfPath * this.taperY; + else newNode.yScale = 1.0f + (1.0f - percentOfPath) * this.taperY; + + float twist = twistBegin + twistTotal * percentOfPath; + + newNode.rotation = new Quat(new Coord(0.0f, 0.0f, 1.0f), twist); + newNode.position = new Coord(xOffset, yOffset, zOffset); + newNode.percentOfPath = percentOfPath; + + pathNodes.Add(newNode); + + if (step < steps) + { + step += 1; + percentOfPath += percentOfPathMultiplier; + xOffset += xOffsetStepIncrement; + yOffset += yOffsetStepIncrement; + zOffset += stepSize; + if (percentOfPath > this.pathCutEnd) + done = true; + } + else done = true; + } + } // end of linear path code + + else // pathType == Circular + { + float twistTotal = twistEnd - twistBegin; + + // if the profile has a lot of twist, add more layers otherwise the layers may overlap + // and the resulting mesh may be quite inaccurate. This method is arbitrary and doesn't + // accurately match the viewer + float twistTotalAbs = Math.Abs(twistTotal); + if (twistTotalAbs > 0.01f) + { + if (twistTotalAbs > Math.PI * 1.5f) + steps *= 2; + if (twistTotalAbs > Math.PI * 3.0f) + steps *= 2; + } + + float yPathScale = this.holeSizeY * 0.5f; + float pathLength = this.pathCutEnd - this.pathCutBegin; + float totalSkew = this.skew * 2.0f * pathLength; + float skewStart = this.pathCutBegin * 2.0f * this.skew - this.skew; + float xOffsetTopShearXFactor = this.topShearX * (0.25f + 0.5f * (0.5f - this.holeSizeY)); + float yShearCompensation = 1.0f + Math.Abs(this.topShearY) * 0.25f; + + // It's not quite clear what pushY (Y top shear) does, but subtracting it from the start and end + // angles appears to approximate it's effects on path cut. Likewise, adding it to the angle used + // to calculate the sine for generating the path radius appears to approximate it's effects there + // too, but there are some subtle differences in the radius which are noticeable as the prim size + // increases and it may affect megaprims quite a bit. The effect of the Y top shear parameter on + // the meshes generated with this technique appear nearly identical in shape to the same prims when + // displayed by the viewer. + + float startAngle = (twoPi * this.pathCutBegin * this.revolutions) - this.topShearY * 0.9f; + float endAngle = (twoPi * this.pathCutEnd * this.revolutions) - this.topShearY * 0.9f; + float stepSize = twoPi / this.stepsPerRevolution; + + int step = (int)(startAngle / stepSize); + float angle = startAngle; + + bool done = false; + while (!done) // loop through the length of the path and add the layers + { + PathNode newNode = new PathNode(); + + float xProfileScale = (1.0f - Math.Abs(this.skew)) * this.holeSizeX; + float yProfileScale = this.holeSizeY; + + float percentOfPath = angle / (twoPi * this.revolutions); + float percentOfAngles = (angle - startAngle) / (endAngle - startAngle); + + if (this.taperX > 0.01f) + xProfileScale *= 1.0f - percentOfPath * this.taperX; + else if (this.taperX < -0.01f) + xProfileScale *= 1.0f + (1.0f - percentOfPath) * this.taperX; + + if (this.taperY > 0.01f) + yProfileScale *= 1.0f - percentOfPath * this.taperY; + else if (this.taperY < -0.01f) + yProfileScale *= 1.0f + (1.0f - percentOfPath) * this.taperY; + + newNode.xScale = xProfileScale; + newNode.yScale = yProfileScale; + + float radiusScale = 1.0f; + if (this.radius > 0.001f) + radiusScale = 1.0f - this.radius * percentOfPath; + else if (this.radius < 0.001f) + radiusScale = 1.0f + this.radius * (1.0f - percentOfPath); + + float twist = twistBegin + twistTotal * percentOfPath; + + float xOffset = 0.5f * (skewStart + totalSkew * percentOfAngles); + xOffset += (float)Math.Sin(angle) * xOffsetTopShearXFactor; + + float yOffset = yShearCompensation * (float)Math.Cos(angle) * (0.5f - yPathScale) * radiusScale; + + float zOffset = (float)Math.Sin(angle + this.topShearY) * (0.5f - yPathScale) * radiusScale; + + newNode.position = new Coord(xOffset, yOffset, zOffset); + + // now orient the rotation of the profile layer relative to it's position on the path + // adding taperY to the angle used to generate the quat appears to approximate the viewer + + newNode.rotation = new Quat(new Coord(1.0f, 0.0f, 0.0f), angle + this.topShearY); + + // next apply twist rotation to the profile layer + if (twistTotal != 0.0f || twistBegin != 0.0f) + newNode.rotation *= new Quat(new Coord(0.0f, 0.0f, 1.0f), twist); + + newNode.percentOfPath = percentOfPath; + + pathNodes.Add(newNode); + + // calculate terms for next iteration + // calculate the angle for the next iteration of the loop + + if (angle >= endAngle - 0.01) + done = true; + else + { + step += 1; + angle = stepSize * step; + if (angle > endAngle) + angle = endAngle; + } + } + } + } + } + + public class PrimMesh + { + public string errorMessage = ""; + private const float twoPi = 2.0f * (float)Math.PI; + + public List coords; + public List normals; + public List faces; + + public List viewerFaces; + + private int sides = 4; + private int hollowSides = 4; + private float profileStart = 0.0f; + private float profileEnd = 1.0f; + private float hollow = 0.0f; + public int twistBegin = 0; + public int twistEnd = 0; + public float topShearX = 0.0f; + public float topShearY = 0.0f; + public float pathCutBegin = 0.0f; + public float pathCutEnd = 1.0f; + public float dimpleBegin = 0.0f; + public float dimpleEnd = 1.0f; + public float skew = 0.0f; + public float holeSizeX = 1.0f; // called pathScaleX in pbs + public float holeSizeY = 0.25f; + public float taperX = 0.0f; + public float taperY = 0.0f; + public float radius = 0.0f; + public float revolutions = 1.0f; + public int stepsPerRevolution = 24; + + private int profileOuterFaceNumber = -1; + private int profileHollowFaceNumber = -1; + + private bool hasProfileCut = false; + private bool hasHollow = false; + public bool calcVertexNormals = false; + private bool normalsProcessed = false; + public bool viewerMode = false; + public bool sphereMode = false; + + public int numPrimFaces = 0; + + /// + /// Human readable string representation of the parameters used to create a mesh. + /// + /// + public string ParamsToDisplayString() + { + string s = ""; + s += "sides..................: " + this.sides.ToString(); + s += "\nhollowSides..........: " + this.hollowSides.ToString(); + s += "\nprofileStart.........: " + this.profileStart.ToString(); + s += "\nprofileEnd...........: " + this.profileEnd.ToString(); + s += "\nhollow...............: " + this.hollow.ToString(); + s += "\ntwistBegin...........: " + this.twistBegin.ToString(); + s += "\ntwistEnd.............: " + this.twistEnd.ToString(); + s += "\ntopShearX............: " + this.topShearX.ToString(); + s += "\ntopShearY............: " + this.topShearY.ToString(); + s += "\npathCutBegin.........: " + this.pathCutBegin.ToString(); + s += "\npathCutEnd...........: " + this.pathCutEnd.ToString(); + s += "\ndimpleBegin..........: " + this.dimpleBegin.ToString(); + s += "\ndimpleEnd............: " + this.dimpleEnd.ToString(); + s += "\nskew.................: " + this.skew.ToString(); + s += "\nholeSizeX............: " + this.holeSizeX.ToString(); + s += "\nholeSizeY............: " + this.holeSizeY.ToString(); + s += "\ntaperX...............: " + this.taperX.ToString(); + s += "\ntaperY...............: " + this.taperY.ToString(); + s += "\nradius...............: " + this.radius.ToString(); + s += "\nrevolutions..........: " + this.revolutions.ToString(); + s += "\nstepsPerRevolution...: " + this.stepsPerRevolution.ToString(); + s += "\nsphereMode...........: " + this.sphereMode.ToString(); + s += "\nhasProfileCut........: " + this.hasProfileCut.ToString(); + s += "\nhasHollow............: " + this.hasHollow.ToString(); + s += "\nviewerMode...........: " + this.viewerMode.ToString(); + + return s; + } + + public int ProfileOuterFaceNumber + { + get { return profileOuterFaceNumber; } + } + + public int ProfileHollowFaceNumber + { + get { return profileHollowFaceNumber; } + } + + public bool HasProfileCut + { + get { return hasProfileCut; } + } + + public bool HasHollow + { + get { return hasHollow; } + } + + + /// + /// Constructs a PrimMesh object and creates the profile for extrusion. + /// + /// + /// + /// + /// + /// + public PrimMesh(int sides, float profileStart, float profileEnd, float hollow, int hollowSides) + { + this.coords = new List(); + this.faces = new List(); + + this.sides = sides; + this.profileStart = profileStart; + this.profileEnd = profileEnd; + this.hollow = hollow; + this.hollowSides = hollowSides; + + if (sides < 3) + this.sides = 3; + if (hollowSides < 3) + this.hollowSides = 3; + if (profileStart < 0.0f) + this.profileStart = 0.0f; + if (profileEnd > 1.0f) + this.profileEnd = 1.0f; + if (profileEnd < 0.02f) + this.profileEnd = 0.02f; + if (profileStart >= profileEnd) + this.profileStart = profileEnd - 0.02f; + if (hollow > 0.99f) + this.hollow = 0.99f; + if (hollow < 0.0f) + this.hollow = 0.0f; + } + + /// + /// Extrudes a profile along a path. + /// + public void Extrude(PathType pathType) + { + bool needEndFaces = false; + + this.coords = new List(); + this.faces = new List(); + + if (this.viewerMode) + { + this.viewerFaces = new List(); + this.calcVertexNormals = true; + } + + if (this.calcVertexNormals) + this.normals = new List(); + + int steps = 1; + + float length = this.pathCutEnd - this.pathCutBegin; + normalsProcessed = false; + + if (this.viewerMode && this.sides == 3) + { + // prisms don't taper well so add some vertical resolution + // other prims may benefit from this but just do prisms for now + if (Math.Abs(this.taperX) > 0.01 || Math.Abs(this.taperY) > 0.01) + steps = (int)(steps * 4.5 * length); + } + + if (this.sphereMode) + this.hasProfileCut = this.profileEnd - this.profileStart < 0.4999f; + else + this.hasProfileCut = this.profileEnd - this.profileStart < 0.9999f; + this.hasHollow = (this.hollow > 0.001f); + + float twistBegin = this.twistBegin / 360.0f * twoPi; + float twistEnd = this.twistEnd / 360.0f * twoPi; + float twistTotal = twistEnd - twistBegin; + float twistTotalAbs = Math.Abs(twistTotal); + if (twistTotalAbs > 0.01f) + steps += (int)(twistTotalAbs * 3.66); // dahlia's magic number + + float hollow = this.hollow; + + if (pathType == PathType.Circular) + { + needEndFaces = false; + if (this.pathCutBegin > float.Epsilon || this.pathCutEnd < 1.0f - float.Epsilon) + needEndFaces = true; + else if (this.taperX > 0.01f || this.taperY > 0.01f) + needEndFaces = true; + else if (Math.Abs(this.skew) > 0.01f) + needEndFaces = true; + else if (Math.Abs(twistTotal) > 0.001f) + needEndFaces = true; + else if (Math.Abs(this.radius) > 0.0005f) + needEndFaces = true; + } + else needEndFaces = true; + + // sanity checks + float initialProfileRot = 0.0f; + if (pathType == PathType.Circular) + { + if (this.sides == 3) + { + initialProfileRot = (float)Math.PI; + if (this.hollowSides == 4) + { + if (hollow > 0.7f) + hollow = 0.7f; + hollow *= 0.707f; + } + else hollow *= 0.5f; + } + else if (this.sides == 4) + { + initialProfileRot = 0.25f * (float)Math.PI; + if (this.hollowSides != 4) + hollow *= 0.707f; + } + else if (this.sides > 4) + { + initialProfileRot = (float)Math.PI; + if (this.hollowSides == 4) + { + if (hollow > 0.7f) + hollow = 0.7f; + hollow /= 0.7f; + } + } + } + else + { + if (this.sides == 3) + { + if (this.hollowSides == 4) + { + if (hollow > 0.7f) + hollow = 0.7f; + hollow *= 0.707f; + } + else hollow *= 0.5f; + } + else if (this.sides == 4) + { + initialProfileRot = 1.25f * (float)Math.PI; + if (this.hollowSides != 4) + hollow *= 0.707f; + } + else if (this.sides == 24 && this.hollowSides == 4) + hollow *= 1.414f; + } + + Profile profile = new Profile(this.sides, this.profileStart, this.profileEnd, hollow, this.hollowSides, true, calcVertexNormals); + this.errorMessage = profile.errorMessage; + + this.numPrimFaces = profile.numPrimFaces; + + int cut1FaceNumber = profile.bottomFaceNumber + 1; + int cut2FaceNumber = cut1FaceNumber + 1; + if (!needEndFaces) + { + cut1FaceNumber -= 2; + cut2FaceNumber -= 2; + } + + profileOuterFaceNumber = profile.outerFaceNumber; + if (!needEndFaces) + profileOuterFaceNumber--; + + if (hasHollow) + { + profileHollowFaceNumber = profile.hollowFaceNumber; + if (!needEndFaces) + profileHollowFaceNumber--; + } + + int cut1Vert = -1; + int cut2Vert = -1; + if (hasProfileCut) + { + cut1Vert = hasHollow ? profile.coords.Count - 1 : 0; + cut2Vert = hasHollow ? profile.numOuterVerts - 1 : profile.numOuterVerts; + } + + if (initialProfileRot != 0.0f) + { + profile.AddRot(new Quat(new Coord(0.0f, 0.0f, 1.0f), initialProfileRot)); + if (viewerMode) + profile.MakeFaceUVs(); + } + + Coord lastCutNormal1 = new Coord(); + Coord lastCutNormal2 = new Coord(); + float thisV = 0.0f; + float lastV = 0.0f; + + Path path = new Path(); + path.twistBegin = twistBegin; + path.twistEnd = twistEnd; + path.topShearX = topShearX; + path.topShearY = topShearY; + path.pathCutBegin = pathCutBegin; + path.pathCutEnd = pathCutEnd; + path.dimpleBegin = dimpleBegin; + path.dimpleEnd = dimpleEnd; + path.skew = skew; + path.holeSizeX = holeSizeX; + path.holeSizeY = holeSizeY; + path.taperX = taperX; + path.taperY = taperY; + path.radius = radius; + path.revolutions = revolutions; + path.stepsPerRevolution = stepsPerRevolution; + + path.Create(pathType, steps); + + for (int nodeIndex = 0; nodeIndex < path.pathNodes.Count; nodeIndex++) + { + PathNode node = path.pathNodes[nodeIndex]; + Profile newLayer = profile.Copy(); + newLayer.Scale(node.xScale, node.yScale); + + newLayer.AddRot(node.rotation); + newLayer.AddPos(node.position); + + if (needEndFaces && nodeIndex == 0) + { + newLayer.FlipNormals(); + + // add the bottom faces to the viewerFaces list + if (this.viewerMode) + { + Coord faceNormal = newLayer.faceNormal; + ViewerFace newViewerFace = new ViewerFace(profile.bottomFaceNumber); + int numFaces = newLayer.faces.Count; + List faces = newLayer.faces; + + for (int i = 0; i < numFaces; i++) + { + Face face = faces[i]; + newViewerFace.v1 = newLayer.coords[face.v1]; + newViewerFace.v2 = newLayer.coords[face.v2]; + newViewerFace.v3 = newLayer.coords[face.v3]; + + newViewerFace.coordIndex1 = face.v1; + newViewerFace.coordIndex2 = face.v2; + newViewerFace.coordIndex3 = face.v3; + + newViewerFace.n1 = faceNormal; + newViewerFace.n2 = faceNormal; + newViewerFace.n3 = faceNormal; + + newViewerFace.uv1 = newLayer.faceUVs[face.v1]; + newViewerFace.uv2 = newLayer.faceUVs[face.v2]; + newViewerFace.uv3 = newLayer.faceUVs[face.v3]; + + if (pathType == PathType.Linear) + { + newViewerFace.uv1.Flip(); + newViewerFace.uv2.Flip(); + newViewerFace.uv3.Flip(); + } + + this.viewerFaces.Add(newViewerFace); + } + } + } // if (nodeIndex == 0) + + // append this layer + + int coordsLen = this.coords.Count; + newLayer.AddValue2FaceVertexIndices(coordsLen); + + this.coords.AddRange(newLayer.coords); + + if (this.calcVertexNormals) + { + newLayer.AddValue2FaceNormalIndices(this.normals.Count); + this.normals.AddRange(newLayer.vertexNormals); + } + + if (needEndFaces) + { + if (nodeIndex == 0 || nodeIndex == path.pathNodes.Count - 1) + this.faces.AddRange(newLayer.faces); + } + + // fill faces between layers + + int numVerts = newLayer.coords.Count; + Face newFace1 = new Face(); + Face newFace2 = new Face(); + + thisV = 1.0f - node.percentOfPath; + + if (nodeIndex > 0) + { + int startVert = coordsLen + 1; + int endVert = this.coords.Count; + + if (sides < 5 || this.hasProfileCut || this.hasHollow) + startVert--; + + for (int i = startVert; i < endVert; i++) + { + int iNext = i + 1; + if (i == endVert - 1) + iNext = startVert; + + int whichVert = i - startVert; + + newFace1.v1 = i; + newFace1.v2 = i - numVerts; + newFace1.v3 = iNext; + + newFace1.n1 = newFace1.v1; + newFace1.n2 = newFace1.v2; + newFace1.n3 = newFace1.v3; + this.faces.Add(newFace1); + + newFace2.v1 = iNext; + newFace2.v2 = i - numVerts; + newFace2.v3 = iNext - numVerts; + + newFace2.n1 = newFace2.v1; + newFace2.n2 = newFace2.v2; + newFace2.n3 = newFace2.v3; + this.faces.Add(newFace2); + + if (this.viewerMode) + { + // add the side faces to the list of viewerFaces here + + int primFaceNum = profile.faceNumbers[whichVert]; + if (!needEndFaces) + primFaceNum -= 1; + + ViewerFace newViewerFace1 = new ViewerFace(primFaceNum); + ViewerFace newViewerFace2 = new ViewerFace(primFaceNum); + + int uIndex = whichVert; + if (!hasHollow && sides > 4 && uIndex < newLayer.us.Count - 1) + { + uIndex++; + } + + float u1 = newLayer.us[uIndex]; + float u2 = 1.0f; + if (uIndex < (int)newLayer.us.Count - 1) + u2 = newLayer.us[uIndex + 1]; + + if (whichVert == cut1Vert || whichVert == cut2Vert) + { + u1 = 0.0f; + u2 = 1.0f; + } + else if (sides < 5) + { + if (whichVert < profile.numOuterVerts) + { // boxes and prisms have one texture face per side of the prim, so the U values have to be scaled + // to reflect the entire texture width + u1 *= sides; + u2 *= sides; + u2 -= (int)u1; + u1 -= (int)u1; + if (u2 < 0.1f) + u2 = 1.0f; + } + } + + if (this.sphereMode) + { + if (whichVert != cut1Vert && whichVert != cut2Vert) + { + u1 = u1 * 2.0f - 1.0f; + u2 = u2 * 2.0f - 1.0f; + + if (whichVert >= newLayer.numOuterVerts) + { + u1 -= hollow; + u2 -= hollow; + } + + } + } + + newViewerFace1.uv1.U = u1; + newViewerFace1.uv2.U = u1; + newViewerFace1.uv3.U = u2; + + newViewerFace1.uv1.V = thisV; + newViewerFace1.uv2.V = lastV; + newViewerFace1.uv3.V = thisV; + + newViewerFace2.uv1.U = u2; + newViewerFace2.uv2.U = u1; + newViewerFace2.uv3.U = u2; + + newViewerFace2.uv1.V = thisV; + newViewerFace2.uv2.V = lastV; + newViewerFace2.uv3.V = lastV; + + newViewerFace1.v1 = this.coords[newFace1.v1]; + newViewerFace1.v2 = this.coords[newFace1.v2]; + newViewerFace1.v3 = this.coords[newFace1.v3]; + + newViewerFace2.v1 = this.coords[newFace2.v1]; + newViewerFace2.v2 = this.coords[newFace2.v2]; + newViewerFace2.v3 = this.coords[newFace2.v3]; + + newViewerFace1.coordIndex1 = newFace1.v1; + newViewerFace1.coordIndex2 = newFace1.v2; + newViewerFace1.coordIndex3 = newFace1.v3; + + newViewerFace2.coordIndex1 = newFace2.v1; + newViewerFace2.coordIndex2 = newFace2.v2; + newViewerFace2.coordIndex3 = newFace2.v3; + + // profile cut faces + if (whichVert == cut1Vert) + { + newViewerFace1.primFaceNumber = cut1FaceNumber; + newViewerFace2.primFaceNumber = cut1FaceNumber; + newViewerFace1.n1 = newLayer.cutNormal1; + newViewerFace1.n2 = newViewerFace1.n3 = lastCutNormal1; + + newViewerFace2.n1 = newViewerFace2.n3 = newLayer.cutNormal1; + newViewerFace2.n2 = lastCutNormal1; + } + else if (whichVert == cut2Vert) + { + newViewerFace1.primFaceNumber = cut2FaceNumber; + newViewerFace2.primFaceNumber = cut2FaceNumber; + newViewerFace1.n1 = newLayer.cutNormal2; + newViewerFace1.n2 = lastCutNormal2; + newViewerFace1.n3 = lastCutNormal2; + + newViewerFace2.n1 = newLayer.cutNormal2; + newViewerFace2.n3 = newLayer.cutNormal2; + newViewerFace2.n2 = lastCutNormal2; + } + + else // outer and hollow faces + { + if ((sides < 5 && whichVert < newLayer.numOuterVerts) || (hollowSides < 5 && whichVert >= newLayer.numOuterVerts)) + { // looks terrible when path is twisted... need vertex normals here + newViewerFace1.CalcSurfaceNormal(); + newViewerFace2.CalcSurfaceNormal(); + } + else + { + newViewerFace1.n1 = this.normals[newFace1.n1]; + newViewerFace1.n2 = this.normals[newFace1.n2]; + newViewerFace1.n3 = this.normals[newFace1.n3]; + + newViewerFace2.n1 = this.normals[newFace2.n1]; + newViewerFace2.n2 = this.normals[newFace2.n2]; + newViewerFace2.n3 = this.normals[newFace2.n3]; + } + } + + this.viewerFaces.Add(newViewerFace1); + this.viewerFaces.Add(newViewerFace2); + + } + } + } + + lastCutNormal1 = newLayer.cutNormal1; + lastCutNormal2 = newLayer.cutNormal2; + lastV = thisV; + + if (needEndFaces && nodeIndex == path.pathNodes.Count - 1 && viewerMode) + { + // add the top faces to the viewerFaces list here + Coord faceNormal = newLayer.faceNormal; + ViewerFace newViewerFace = new ViewerFace(0); + int numFaces = newLayer.faces.Count; + List faces = newLayer.faces; + + for (int i = 0; i < numFaces; i++) + { + Face face = faces[i]; + newViewerFace.v1 = newLayer.coords[face.v1 - coordsLen]; + newViewerFace.v2 = newLayer.coords[face.v2 - coordsLen]; + newViewerFace.v3 = newLayer.coords[face.v3 - coordsLen]; + + newViewerFace.coordIndex1 = face.v1 - coordsLen; + newViewerFace.coordIndex2 = face.v2 - coordsLen; + newViewerFace.coordIndex3 = face.v3 - coordsLen; + + newViewerFace.n1 = faceNormal; + newViewerFace.n2 = faceNormal; + newViewerFace.n3 = faceNormal; + + newViewerFace.uv1 = newLayer.faceUVs[face.v1 - coordsLen]; + newViewerFace.uv2 = newLayer.faceUVs[face.v2 - coordsLen]; + newViewerFace.uv3 = newLayer.faceUVs[face.v3 - coordsLen]; + + if (pathType == PathType.Linear) + { + newViewerFace.uv1.Flip(); + newViewerFace.uv2.Flip(); + newViewerFace.uv3.Flip(); + } + + this.viewerFaces.Add(newViewerFace); + } + } + + + } // for (int nodeIndex = 0; nodeIndex < path.pathNodes.Count; nodeIndex++) + + } + + + /// + /// DEPRICATED - use Extrude(PathType.Linear) instead + /// Extrudes a profile along a straight line path. Used for prim types box, cylinder, and prism. + /// + /// + public void ExtrudeLinear() + { + this.Extrude(PathType.Linear); + } + + + /// + /// DEPRICATED - use Extrude(PathType.Circular) instead + /// Extrude a profile into a circular path prim mesh. Used for prim types torus, tube, and ring. + /// + /// + public void ExtrudeCircular() + { + this.Extrude(PathType.Circular); + } + + + private Coord SurfaceNormal(Coord c1, Coord c2, Coord c3) + { + Coord edge1 = new Coord(c2.X - c1.X, c2.Y - c1.Y, c2.Z - c1.Z); + Coord edge2 = new Coord(c3.X - c1.X, c3.Y - c1.Y, c3.Z - c1.Z); + + Coord normal = Coord.Cross(edge1, edge2); + + normal.Normalize(); + + return normal; + } + + private Coord SurfaceNormal(Face face) + { + return SurfaceNormal(this.coords[face.v1], this.coords[face.v2], this.coords[face.v3]); + } + + /// + /// Calculate the surface normal for a face in the list of faces + /// + /// + /// + public Coord SurfaceNormal(int faceIndex) + { + int numFaces = this.faces.Count; + if (faceIndex < 0 || faceIndex >= numFaces) + throw new Exception("faceIndex out of range"); + + return SurfaceNormal(this.faces[faceIndex]); + } + + /// + /// Duplicates a PrimMesh object. All object properties are copied by value, including lists. + /// + /// + public PrimMesh Copy() + { + PrimMesh copy = new PrimMesh(this.sides, this.profileStart, this.profileEnd, this.hollow, this.hollowSides); + copy.twistBegin = this.twistBegin; + copy.twistEnd = this.twistEnd; + copy.topShearX = this.topShearX; + copy.topShearY = this.topShearY; + copy.pathCutBegin = this.pathCutBegin; + copy.pathCutEnd = this.pathCutEnd; + copy.dimpleBegin = this.dimpleBegin; + copy.dimpleEnd = this.dimpleEnd; + copy.skew = this.skew; + copy.holeSizeX = this.holeSizeX; + copy.holeSizeY = this.holeSizeY; + copy.taperX = this.taperX; + copy.taperY = this.taperY; + copy.radius = this.radius; + copy.revolutions = this.revolutions; + copy.stepsPerRevolution = this.stepsPerRevolution; + copy.calcVertexNormals = this.calcVertexNormals; + copy.normalsProcessed = this.normalsProcessed; + copy.viewerMode = this.viewerMode; + copy.numPrimFaces = this.numPrimFaces; + copy.errorMessage = this.errorMessage; + + copy.coords = new List(this.coords); + copy.faces = new List(this.faces); + copy.viewerFaces = new List(this.viewerFaces); + copy.normals = new List(this.normals); + + return copy; + } + + /// + /// Calculate surface normals for all of the faces in the list of faces in this mesh + /// + public void CalcNormals() + { + if (normalsProcessed) + return; + + normalsProcessed = true; + + int numFaces = faces.Count; + + if (!this.calcVertexNormals) + this.normals = new List(); + + for (int i = 0; i < numFaces; i++) + { + Face face = faces[i]; + + this.normals.Add(SurfaceNormal(i).Normalize()); + + int normIndex = normals.Count - 1; + face.n1 = normIndex; + face.n2 = normIndex; + face.n3 = normIndex; + + this.faces[i] = face; + } + } + + /// + /// Adds a value to each XYZ vertex coordinate in the mesh + /// + /// + /// + /// + public void AddPos(float x, float y, float z) + { + int i; + int numVerts = this.coords.Count; + Coord vert; + + for (i = 0; i < numVerts; i++) + { + vert = this.coords[i]; + vert.X += x; + vert.Y += y; + vert.Z += z; + this.coords[i] = vert; + } + + if (this.viewerFaces != null) + { + int numViewerFaces = this.viewerFaces.Count; + + for (i = 0; i < numViewerFaces; i++) + { + ViewerFace v = this.viewerFaces[i]; + v.AddPos(x, y, z); + this.viewerFaces[i] = v; + } + } + } + + /// + /// Rotates the mesh + /// + /// + public void AddRot(Quat q) + { + int i; + int numVerts = this.coords.Count; + + for (i = 0; i < numVerts; i++) + this.coords[i] *= q; + + if (this.normals != null) + { + int numNormals = this.normals.Count; + for (i = 0; i < numNormals; i++) + this.normals[i] *= q; + } + + if (this.viewerFaces != null) + { + int numViewerFaces = this.viewerFaces.Count; + + for (i = 0; i < numViewerFaces; i++) + { + ViewerFace v = this.viewerFaces[i]; + v.v1 *= q; + v.v2 *= q; + v.v3 *= q; + + v.n1 *= q; + v.n2 *= q; + v.n3 *= q; + this.viewerFaces[i] = v; + } + } + } + + public VertexIndexer GetVertexIndexer() + { + if (this.viewerMode && this.viewerFaces.Count > 0) + return new VertexIndexer(this); + return null; + } + + /// + /// Scales the mesh + /// + /// + /// + /// + public void Scale(float x, float y, float z) + { + int i; + int numVerts = this.coords.Count; + //Coord vert; + + Coord m = new Coord(x, y, z); + for (i = 0; i < numVerts; i++) + this.coords[i] *= m; + + if (this.viewerFaces != null) + { + int numViewerFaces = this.viewerFaces.Count; + for (i = 0; i < numViewerFaces; i++) + { + ViewerFace v = this.viewerFaces[i]; + v.v1 *= m; + v.v2 *= m; + v.v3 *= m; + this.viewerFaces[i] = v; + } + + } + + } + + /// + /// Dumps the mesh to a Blender compatible "Raw" format file + /// + /// + /// + /// + public void DumpRaw(String path, String name, String title) + { + if (path == null) + return; + String fileName = name + "_" + title + ".raw"; + String completePath = System.IO.Path.Combine(path, fileName); + StreamWriter sw = new StreamWriter(completePath); + + for (int i = 0; i < this.faces.Count; i++) + { + string s = this.coords[this.faces[i].v1].ToString(); + s += " " + this.coords[this.faces[i].v2].ToString(); + s += " " + this.coords[this.faces[i].v3].ToString(); + + sw.WriteLine(s); + } + + sw.Close(); + } + } +} diff --git a/PrimMesher/Properties/AssemblyInfo.cs b/PrimMesher/Properties/AssemblyInfo.cs new file mode 100644 index 00000000..1dec5445 --- /dev/null +++ b/PrimMesher/Properties/AssemblyInfo.cs @@ -0,0 +1,13 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("ef69232f-7e8c-4efa-9ce6-d4e9743aac66")] diff --git a/PrimMesher/SculptMap.cs b/PrimMesher/SculptMap.cs new file mode 100644 index 00000000..502f6f44 --- /dev/null +++ b/PrimMesher/SculptMap.cs @@ -0,0 +1,193 @@ +/* + * Copyright (c) Contributors + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +// to build without references to System.Drawing, comment this out +#define SYSTEM_DRAWING + +using System; +using System.Collections.Generic; +using System.Text; + +#if SYSTEM_DRAWING +using System.Drawing; +using System.Drawing.Imaging; + +namespace PrimMesher +{ + public class SculptMap + { + public int width; + public int height; + public byte[] redBytes; + public byte[] greenBytes; + public byte[] blueBytes; + + public SculptMap() + { + } + + public SculptMap(Bitmap bm, int lod) + { + int bmW = bm.Width; + int bmH = bm.Height; + + if (bmW == 0 || bmH == 0) + throw new Exception("SculptMap: bitmap has no data"); + + int numLodPixels = lod * 2 * lod * 2; // (32 * 2)^2 = 64^2 pixels for default sculpt map image + + bool needsScaling = false; + + bool smallMap = bmW * bmH <= lod * lod; + + width = bmW; + height = bmH; + while (width * height > numLodPixels) + { + width >>= 1; + height >>= 1; + needsScaling = true; + } + + try + { + if (needsScaling) + bm = ScaleImage(bm, width, height, + System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor); + } + + catch (Exception e) + { + throw new Exception("Exception in ScaleImage(): e: " + e.ToString()); + } + + if (width * height > lod * lod) + { + width >>= 1; + height >>= 1; + } + + int numBytes = smallMap ? width * height : (width + 1) * (height + 1); + redBytes = new byte[numBytes]; + greenBytes = new byte[numBytes]; + blueBytes = new byte[numBytes]; + + int byteNdx = 0; + + try + { + if (smallMap) + for (int y = 0; y < height; y++) + { + for (int x = 0; x < width; x++) + { + Color c = bm.GetPixel(x, y); + + redBytes[byteNdx] = c.R; + greenBytes[byteNdx] = c.G; + blueBytes[byteNdx] = c.B; + + ++byteNdx; + } + } + else + for (int y = 0; y <= height; y++) + { + for (int x = 0; x <= width; x++) + { + Color c = bm.GetPixel(x < width ? x * 2 : x * 2 - 1, + y < height ? y * 2 : y * 2 - 1); + + redBytes[byteNdx] = c.R; + greenBytes[byteNdx] = c.G; + blueBytes[byteNdx] = c.B; + + ++byteNdx; + } + } + } + catch (Exception e) + { + throw new Exception("Caught exception processing byte arrays in SculptMap(): e: " + e.ToString()); + } + + if (!smallMap) + { + width++; + height++; + } + } + + public List> ToRows(bool mirror) + { + int numRows = height; + int numCols = width; + + List> rows = new List>(numRows); + + float pixScale = 1.0f / 255; + + int rowNdx, colNdx; + int smNdx = 0; + + for (rowNdx = 0; rowNdx < numRows; rowNdx++) + { + List row = new List(numCols); + for (colNdx = 0; colNdx < numCols; colNdx++) + { + if (mirror) + row.Add(new Coord(-(redBytes[smNdx] * pixScale - 0.5f), (greenBytes[smNdx] * pixScale - 0.5f), blueBytes[smNdx] * pixScale - 0.5f)); + else + row.Add(new Coord(redBytes[smNdx] * pixScale - 0.5f, greenBytes[smNdx] * pixScale - 0.5f, blueBytes[smNdx] * pixScale - 0.5f)); + + ++smNdx; + } + rows.Add(row); + } + return rows; + } + + private Bitmap ScaleImage(Bitmap srcImage, int destWidth, int destHeight, + System.Drawing.Drawing2D.InterpolationMode interpMode) + { + Bitmap scaledImage = new Bitmap(srcImage, destWidth, destHeight); + scaledImage.SetResolution(96.0f, 96.0f); + + Graphics grPhoto = Graphics.FromImage(scaledImage); + grPhoto.InterpolationMode = interpMode; + + grPhoto.DrawImage(srcImage, + new Rectangle(0, 0, destWidth, destHeight), + new Rectangle(0, 0, srcImage.Width, srcImage.Height), + GraphicsUnit.Pixel); + + grPhoto.Dispose(); + return scaledImage; + } + } +} +#endif diff --git a/PrimMesher/SculptMesh.cs b/PrimMesher/SculptMesh.cs new file mode 100644 index 00000000..c396eef4 --- /dev/null +++ b/PrimMesher/SculptMesh.cs @@ -0,0 +1,646 @@ +/* + * Copyright (c) Contributors + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +// to build without references to System.Drawing, comment this out +#define SYSTEM_DRAWING + +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; + +#if SYSTEM_DRAWING +using System.Drawing; +using System.Drawing.Imaging; +#endif + +namespace PrimMesher +{ + + public class SculptMesh + { + public List coords; + public List faces; + + public List viewerFaces; + public List normals; + public List uvs; + + public enum SculptType { sphere = 1, torus = 2, plane = 3, cylinder = 4 }; + +#if SYSTEM_DRAWING + + public SculptMesh SculptMeshFromFile(string fileName, SculptType sculptType, int lod, bool viewerMode) + { + Bitmap bitmap = (Bitmap)Bitmap.FromFile(fileName); + SculptMesh sculptMesh = new SculptMesh(bitmap, sculptType, lod, viewerMode); + bitmap.Dispose(); + return sculptMesh; + } + + + public SculptMesh(string fileName, int sculptType, int lod, int viewerMode, int mirror, int invert) + { + Bitmap bitmap = (Bitmap)Bitmap.FromFile(fileName); + _SculptMesh(bitmap, (SculptType)sculptType, lod, viewerMode != 0, mirror != 0, invert != 0); + bitmap.Dispose(); + } +#endif + + /// + /// ** Experimental ** May disappear from future versions ** not recommeneded for use in applications + /// Construct a sculpt mesh from a 2D array of floats + /// + /// + /// + /// + /// + /// + /// + public SculptMesh(float[,] zMap, float xBegin, float xEnd, float yBegin, float yEnd, bool viewerMode) + { + float xStep, yStep; + float uStep, vStep; + + int numYElements = zMap.GetLength(0); + int numXElements = zMap.GetLength(1); + + try + { + xStep = (xEnd - xBegin) / (float)(numXElements - 1); + yStep = (yEnd - yBegin) / (float)(numYElements - 1); + + uStep = 1.0f / (numXElements - 1); + vStep = 1.0f / (numYElements - 1); + } + catch (DivideByZeroException) + { + return; + } + + coords = new List(); + faces = new List(); + normals = new List(); + uvs = new List(); + + viewerFaces = new List(); + + int p1, p2, p3, p4; + + int x, y; + int xStart = 0, yStart = 0; + + for (y = yStart; y < numYElements; y++) + { + int rowOffset = y * numXElements; + + for (x = xStart; x < numXElements; x++) + { + /* + * p1-----p2 + * | \ f2 | + * | \ | + * | f1 \| + * p3-----p4 + */ + + p4 = rowOffset + x; + p3 = p4 - 1; + + p2 = p4 - numXElements; + p1 = p3 - numXElements; + + Coord c = new Coord(xBegin + x * xStep, yBegin + y * yStep, zMap[y, x]); + this.coords.Add(c); + if (viewerMode) + { + this.normals.Add(new Coord()); + this.uvs.Add(new UVCoord(uStep * x, 1.0f - vStep * y)); + } + + if (y > 0 && x > 0) + { + Face f1, f2; + + if (viewerMode) + { + f1 = new Face(p1, p4, p3, p1, p4, p3); + f1.uv1 = p1; + f1.uv2 = p4; + f1.uv3 = p3; + + f2 = new Face(p1, p2, p4, p1, p2, p4); + f2.uv1 = p1; + f2.uv2 = p2; + f2.uv3 = p4; + } + else + { + f1 = new Face(p1, p4, p3); + f2 = new Face(p1, p2, p4); + } + + this.faces.Add(f1); + this.faces.Add(f2); + } + } + } + + if (viewerMode) + calcVertexNormals(SculptType.plane, numXElements, numYElements); + } + +#if SYSTEM_DRAWING + public SculptMesh(Bitmap sculptBitmap, SculptType sculptType, int lod, bool viewerMode) + { + _SculptMesh(sculptBitmap, sculptType, lod, viewerMode, false, false); + } + + public SculptMesh(Bitmap sculptBitmap, SculptType sculptType, int lod, bool viewerMode, bool mirror, bool invert) + { + _SculptMesh(sculptBitmap, sculptType, lod, viewerMode, mirror, invert); + } +#endif + + public SculptMesh(List> rows, SculptType sculptType, bool viewerMode, bool mirror, bool invert) + { + _SculptMesh(rows, sculptType, viewerMode, mirror, invert); + } + +#if SYSTEM_DRAWING + /// + /// converts a bitmap to a list of lists of coords, while scaling the image. + /// the scaling is done in floating point so as to allow for reduced vertex position + /// quantization as the position will be averaged between pixel values. this routine will + /// likely fail if the bitmap width and height are not powers of 2. + /// + /// + /// + /// + /// + private List> bitmap2Coords(Bitmap bitmap, int scale, bool mirror) + { + int numRows = bitmap.Height / scale; + int numCols = bitmap.Width / scale; + List> rows = new List>(numRows); + + float pixScale = 1.0f / (scale * scale); + pixScale /= 255; + + int imageX, imageY = 0; + + int rowNdx, colNdx; + + for (rowNdx = 0; rowNdx < numRows; rowNdx++) + { + List row = new List(numCols); + for (colNdx = 0; colNdx < numCols; colNdx++) + { + imageX = colNdx * scale; + int imageYStart = rowNdx * scale; + int imageYEnd = imageYStart + scale; + int imageXEnd = imageX + scale; + float rSum = 0.0f; + float gSum = 0.0f; + float bSum = 0.0f; + for (; imageX < imageXEnd; imageX++) + { + for (imageY = imageYStart; imageY < imageYEnd; imageY++) + { + Color c = bitmap.GetPixel(imageX, imageY); + if (c.A != 255) + { + bitmap.SetPixel(imageX, imageY, Color.FromArgb(255, c.R, c.G, c.B)); + c = bitmap.GetPixel(imageX, imageY); + } + rSum += c.R; + gSum += c.G; + bSum += c.B; + } + } + if (mirror) + row.Add(new Coord(-(rSum * pixScale - 0.5f), gSum * pixScale - 0.5f, bSum * pixScale - 0.5f)); + else + row.Add(new Coord(rSum * pixScale - 0.5f, gSum * pixScale - 0.5f, bSum * pixScale - 0.5f)); + + } + rows.Add(row); + } + return rows; + } + + private List> bitmap2CoordsSampled(Bitmap bitmap, int scale, bool mirror) + { + int numRows = bitmap.Height / scale; + int numCols = bitmap.Width / scale; + List> rows = new List>(numRows); + + float pixScale = 1.0f / 256.0f; + + int imageX, imageY = 0; + + int rowNdx, colNdx; + + for (rowNdx = 0; rowNdx <= numRows; rowNdx++) + { + List row = new List(numCols); + imageY = rowNdx * scale; + if (rowNdx == numRows) imageY--; + for (colNdx = 0; colNdx <= numCols; colNdx++) + { + imageX = colNdx * scale; + if (colNdx == numCols) imageX--; + + Color c = bitmap.GetPixel(imageX, imageY); + if (c.A != 255) + { + bitmap.SetPixel(imageX, imageY, Color.FromArgb(255, c.R, c.G, c.B)); + c = bitmap.GetPixel(imageX, imageY); + } + + if (mirror) + row.Add(new Coord(-(c.R * pixScale - 0.5f), c.G * pixScale - 0.5f, c.B * pixScale - 0.5f)); + else + row.Add(new Coord(c.R * pixScale - 0.5f, c.G * pixScale - 0.5f, c.B * pixScale - 0.5f)); + + } + rows.Add(row); + } + return rows; + } + + + void _SculptMesh(Bitmap sculptBitmap, SculptType sculptType, int lod, bool viewerMode, bool mirror, bool invert) + { + _SculptMesh(new SculptMap(sculptBitmap, lod).ToRows(mirror), sculptType, viewerMode, mirror, invert); + } +#endif + + void _SculptMesh(List> rows, SculptType sculptType, bool viewerMode, bool mirror, bool invert) + { + coords = new List(); + faces = new List(); + normals = new List(); + uvs = new List(); + + sculptType = (SculptType)(((int)sculptType) & 0x07); + + if (mirror) + invert = !invert; + + viewerFaces = new List(); + + int width = rows[0].Count; + + int p1, p2, p3, p4; + + int imageX, imageY; + + if (sculptType != SculptType.plane) + { + if (rows.Count % 2 == 0) + { + for (int rowNdx = 0; rowNdx < rows.Count; rowNdx++) + rows[rowNdx].Add(rows[rowNdx][0]); + } + else + { + int lastIndex = rows[0].Count - 1; + + for (int i = 0; i < rows.Count; i++) + rows[i][0] = rows[i][lastIndex]; + } + } + + Coord topPole = rows[0][width / 2]; + Coord bottomPole = rows[rows.Count - 1][width / 2]; + + if (sculptType == SculptType.sphere) + { + if (rows.Count % 2 == 0) + { + int count = rows[0].Count; + List topPoleRow = new List(count); + List bottomPoleRow = new List(count); + + for (int i = 0; i < count; i++) + { + topPoleRow.Add(topPole); + bottomPoleRow.Add(bottomPole); + } + rows.Insert(0, topPoleRow); + rows.Add(bottomPoleRow); + } + else + { + int count = rows[0].Count; + + List topPoleRow = rows[0]; + List bottomPoleRow = rows[rows.Count - 1]; + + for (int i = 0; i < count; i++) + { + topPoleRow[i] = topPole; + bottomPoleRow[i] = bottomPole; + } + } + } + + if (sculptType == SculptType.torus) + rows.Add(rows[0]); + + int coordsDown = rows.Count; + int coordsAcross = rows[0].Count; + int lastColumn = coordsAcross - 1; + + float widthUnit = 1.0f / (coordsAcross - 1); + float heightUnit = 1.0f / (coordsDown - 1); + + for (imageY = 0; imageY < coordsDown; imageY++) + { + int rowOffset = imageY * coordsAcross; + + for (imageX = 0; imageX < coordsAcross; imageX++) + { + /* + * p1-----p2 + * | \ f2 | + * | \ | + * | f1 \| + * p3-----p4 + */ + + p4 = rowOffset + imageX; + p3 = p4 - 1; + + p2 = p4 - coordsAcross; + p1 = p3 - coordsAcross; + + this.coords.Add(rows[imageY][imageX]); + if (viewerMode) + { + this.normals.Add(new Coord()); + this.uvs.Add(new UVCoord(widthUnit * imageX, heightUnit * imageY)); + } + + if (imageY > 0 && imageX > 0) + { + Face f1, f2; + + if (viewerMode) + { + if (invert) + { + f1 = new Face(p1, p4, p3, p1, p4, p3); + f1.uv1 = p1; + f1.uv2 = p4; + f1.uv3 = p3; + + f2 = new Face(p1, p2, p4, p1, p2, p4); + f2.uv1 = p1; + f2.uv2 = p2; + f2.uv3 = p4; + } + else + { + f1 = new Face(p1, p3, p4, p1, p3, p4); + f1.uv1 = p1; + f1.uv2 = p3; + f1.uv3 = p4; + + f2 = new Face(p1, p4, p2, p1, p4, p2); + f2.uv1 = p1; + f2.uv2 = p4; + f2.uv3 = p2; + } + } + else + { + if (invert) + { + f1 = new Face(p1, p4, p3); + f2 = new Face(p1, p2, p4); + } + else + { + f1 = new Face(p1, p3, p4); + f2 = new Face(p1, p4, p2); + } + } + + this.faces.Add(f1); + this.faces.Add(f2); + } + } + } + + if (viewerMode) + calcVertexNormals(sculptType, coordsAcross, coordsDown); + } + + /// + /// Duplicates a SculptMesh object. All object properties are copied by value, including lists. + /// + /// + public SculptMesh Copy() + { + return new SculptMesh(this); + } + + public SculptMesh(SculptMesh sm) + { + coords = new List(sm.coords); + faces = new List(sm.faces); + viewerFaces = new List(sm.viewerFaces); + normals = new List(sm.normals); + uvs = new List(sm.uvs); + } + + private void calcVertexNormals(SculptType sculptType, int xSize, int ySize) + { // compute vertex normals by summing all the surface normals of all the triangles sharing + // each vertex and then normalizing + int numFaces = this.faces.Count; + for (int i = 0; i < numFaces; i++) + { + Face face = this.faces[i]; + Coord surfaceNormal = face.SurfaceNormal(this.coords); + this.normals[face.n1] += surfaceNormal; + this.normals[face.n2] += surfaceNormal; + this.normals[face.n3] += surfaceNormal; + } + + int numNormals = this.normals.Count; + for (int i = 0; i < numNormals; i++) + this.normals[i] = this.normals[i].Normalize(); + + if (sculptType != SculptType.plane) + { // blend the vertex normals at the cylinder seam + for (int y = 0; y < ySize; y++) + { + int rowOffset = y * xSize; + + this.normals[rowOffset] = this.normals[rowOffset + xSize - 1] = (this.normals[rowOffset] + this.normals[rowOffset + xSize - 1]).Normalize(); + } + } + + foreach (Face face in this.faces) + { + ViewerFace vf = new ViewerFace(0); + vf.v1 = this.coords[face.v1]; + vf.v2 = this.coords[face.v2]; + vf.v3 = this.coords[face.v3]; + + vf.coordIndex1 = face.v1; + vf.coordIndex2 = face.v2; + vf.coordIndex3 = face.v3; + + vf.n1 = this.normals[face.n1]; + vf.n2 = this.normals[face.n2]; + vf.n3 = this.normals[face.n3]; + + vf.uv1 = this.uvs[face.uv1]; + vf.uv2 = this.uvs[face.uv2]; + vf.uv3 = this.uvs[face.uv3]; + + this.viewerFaces.Add(vf); + } + } + + /// + /// Adds a value to each XYZ vertex coordinate in the mesh + /// + /// + /// + /// + public void AddPos(float x, float y, float z) + { + int i; + int numVerts = this.coords.Count; + Coord vert; + + for (i = 0; i < numVerts; i++) + { + vert = this.coords[i]; + vert.X += x; + vert.Y += y; + vert.Z += z; + this.coords[i] = vert; + } + + if (this.viewerFaces != null) + { + int numViewerFaces = this.viewerFaces.Count; + + for (i = 0; i < numViewerFaces; i++) + { + ViewerFace v = this.viewerFaces[i]; + v.AddPos(x, y, z); + this.viewerFaces[i] = v; + } + } + } + + /// + /// Rotates the mesh + /// + /// + public void AddRot(Quat q) + { + int i; + int numVerts = this.coords.Count; + + for (i = 0; i < numVerts; i++) + this.coords[i] *= q; + + int numNormals = this.normals.Count; + for (i = 0; i < numNormals; i++) + this.normals[i] *= q; + + if (this.viewerFaces != null) + { + int numViewerFaces = this.viewerFaces.Count; + + for (i = 0; i < numViewerFaces; i++) + { + ViewerFace v = this.viewerFaces[i]; + v.v1 *= q; + v.v2 *= q; + v.v3 *= q; + + v.n1 *= q; + v.n2 *= q; + v.n3 *= q; + + this.viewerFaces[i] = v; + } + } + } + + public void Scale(float x, float y, float z) + { + int i; + int numVerts = this.coords.Count; + + Coord m = new Coord(x, y, z); + for (i = 0; i < numVerts; i++) + this.coords[i] *= m; + + if (this.viewerFaces != null) + { + int numViewerFaces = this.viewerFaces.Count; + for (i = 0; i < numViewerFaces; i++) + { + ViewerFace v = this.viewerFaces[i]; + v.v1 *= m; + v.v2 *= m; + v.v3 *= m; + this.viewerFaces[i] = v; + } + } + } + + public void DumpRaw(String path, String name, String title) + { + if (path == null) + return; + String fileName = name + "_" + title + ".raw"; + String completePath = System.IO.Path.Combine(path, fileName); + StreamWriter sw = new StreamWriter(completePath); + + for (int i = 0; i < this.faces.Count; i++) + { + string s = this.coords[this.faces[i].v1].ToString(); + s += " " + this.coords[this.faces[i].v2].ToString(); + s += " " + this.coords[this.faces[i].v3].ToString(); + + sw.WriteLine(s); + } + + sw.Close(); + } + } +} diff --git a/PrimMesher/VertexIndexer.cs b/PrimMesher/VertexIndexer.cs new file mode 100644 index 00000000..f8ba3e6e --- /dev/null +++ b/PrimMesher/VertexIndexer.cs @@ -0,0 +1,184 @@ +/* + * Copyright (c) Contributors + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +using System; +using System.Collections.Generic; + +namespace PrimMesher +{ + public struct ViewerVertex + { + public Coord v; + public Coord n; + public UVCoord uv; + + public ViewerVertex(Coord coord, Coord normal, UVCoord uv) + { + this.v = coord; + this.n = normal; + this.uv = uv; + } + } + + public struct ViewerPolygon + { + public int v1; + public int v2; + public int v3; + + public ViewerPolygon(int v1, int v2, int v3) + { + this.v1 = v1; + this.v2 = v2; + this.v3 = v3; + } + } + + public class VertexIndexer + { + public List> viewerVertices; + public List> viewerPolygons; + public int numPrimFaces; + private int[][] viewerVertIndices; + + public VertexIndexer() + { + } + + bool IsValidFace(ViewerFace vf) + { + if (Math.Abs(vf.n1.X) + Math.Abs(vf.n1.Y) + Math.Abs(vf.n1.Z) < 0.2f) + return false; + if (Math.Abs(vf.n2.X) + Math.Abs(vf.n2.Y) + Math.Abs(vf.n2.Z) < 0.2f) + return false; + if (Math.Abs(vf.n3.X) + Math.Abs(vf.n3.Y) + Math.Abs(vf.n3.Z) < 0.2f) + return false; + + return true; + } + + public VertexIndexer(PrimMesh primMesh) + { + int maxPrimFaceNumber = 0; + + int[] validFaces = new int[9], invalidFaces = new int[9]; + for (int i = 0; i < 9; i++) + { + validFaces[i] = -1; + invalidFaces[i] = 0; + } + int numValidFaces = 0; + + foreach (ViewerFace vf in primMesh.viewerFaces) + { + if (maxPrimFaceNumber < vf.primFaceNumber) + maxPrimFaceNumber = vf.primFaceNumber; + + if (!IsValidFace(vf)) + invalidFaces[vf.primFaceNumber]++; + } + + this.numPrimFaces = maxPrimFaceNumber + 1; + for (int i = 0; i < this.numPrimFaces; i++) + if (invalidFaces[i] == 0) + validFaces[i] = numValidFaces++; + + int[] numViewerVerts = new int[numPrimFaces]; + int[] numVertsPerPrimFace = new int[numPrimFaces]; + + for (int i = 0; i < numPrimFaces; i++) + { + numViewerVerts[i] = 0; + numVertsPerPrimFace[i] = 0; + } + + foreach (ViewerFace vf in primMesh.viewerFaces) + numVertsPerPrimFace[vf.primFaceNumber] += 3; + + this.viewerVertices = new List>(numPrimFaces); + this.viewerPolygons = new List>(numPrimFaces); + this.viewerVertIndices = new int[numPrimFaces][]; + + // create index lists + for (int primFaceNumber = 0; primFaceNumber < numPrimFaces; primFaceNumber++) + { + //set all indices to -1 to indicate an invalid index + int[] vertIndices = new int[primMesh.coords.Count]; + for (int i = 0; i < primMesh.coords.Count; i++) + vertIndices[i] = -1; + viewerVertIndices[primFaceNumber] = vertIndices; + + viewerVertices.Add(new List(numVertsPerPrimFace[primFaceNumber])); + viewerPolygons.Add(new List()); + } + + this.numPrimFaces = numValidFaces; + + // populate the index lists + foreach (ViewerFace vf in primMesh.viewerFaces) + { + if (invalidFaces[vf.primFaceNumber] != 0) + continue; + + int v1, v2, v3; + + int[] vertIndices = viewerVertIndices[validFaces[vf.primFaceNumber]]; + List viewerVerts = viewerVertices[validFaces[vf.primFaceNumber]]; + + // add the vertices + if (vertIndices[vf.coordIndex1] < 0) + { + viewerVerts.Add(new ViewerVertex(vf.v1, vf.n1, vf.uv1)); + v1 = viewerVerts.Count - 1; + vertIndices[vf.coordIndex1] = v1; + } + else v1 = vertIndices[vf.coordIndex1]; + + if (vertIndices[vf.coordIndex2] < 0) + { + viewerVerts.Add(new ViewerVertex(vf.v2, vf.n2, vf.uv2)); + v2 = viewerVerts.Count - 1; + vertIndices[vf.coordIndex2] = v2; + } + else v2 = vertIndices[vf.coordIndex2]; + + if (vertIndices[vf.coordIndex3] < 0) + { + viewerVerts.Add(new ViewerVertex(vf.v3, vf.n3, vf.uv3)); + v3 = viewerVerts.Count - 1; + vertIndices[vf.coordIndex3] = v3; + } + else v3 = vertIndices[vf.coordIndex3]; + + if (v1 != v2 && v1 != v3 && v2 != v3) + viewerPolygons[validFaces[vf.primFaceNumber]].Add(new ViewerPolygon(v1, v2, v3)); + } + + } + } +} diff --git a/prebuild.xml b/prebuild.xml index be8d6f0f..5a8bef01 100644 --- a/prebuild.xml +++ b/prebuild.xml @@ -65,6 +65,27 @@ + + + + ../bin/ + + + + + ../bin/ + + + + ../bin/ + + + + + + + + diff --git a/prebuildCoreLib.xml b/prebuildCoreLib.xml index b35a8d40..91b062e5 100755 --- a/prebuildCoreLib.xml +++ b/prebuildCoreLib.xml @@ -65,6 +65,27 @@ + + + + ../bin/ + + + + + ../bin/ + + + + ../bin/ + + + + + + + + diff --git a/runprebuild.sh b/runprebuild.sh index bfd172e5..68c83eb1 100755 --- a/runprebuild.sh +++ b/runprebuild.sh @@ -3,14 +3,14 @@ case "$1" in 'clean') - dotnet bin/prebuild.dll /file prebuild.xml /clean + dotnet bin/prebuild.dll /file prebuildCoreLib.xml /clean ;; 'autoclean') - echo y|dotnet bin/prebuild.dll /file prebuild.xml /clean + echo y|dotnet bin/prebuild.dll /file prebuildCoreLib.xml /clean ;; From 850324b92cdc0cee9eb2eebf2c32c48fd50bcd3b Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Sun, 22 Jun 2025 15:44:12 +0100 Subject: [PATCH 130/149] update CsJ2K to 3.0 and butcher to our needes, including some lkalif and hurliman changes --- CSJ2K/AssemblyInfo.cs | 67 - CSJ2K/Color/ColorSpace.cs | 3 +- CSJ2K/Color/ColorSpaceException.cs | 1 - CSJ2K/Color/ColorSpaceMapper.cs | 904 ++++---- CSJ2K/Color/EnumeratedColorSpaceMapper.cs | 2 +- CSJ2K/Color/EsRgbColorSpaceMapper.cs | 2 +- CSJ2K/Color/SYccColorSpaceMapper.cs | 2 +- CSJ2K/Color/boxes/ChannelDefinitionBox.cs | 7 +- CSJ2K/Color/boxes/ComponentMappingBox.cs | 3 +- CSJ2K/Color/boxes/JP2Box.cs | 20 +- CSJ2K/Icc/ICCProfile.cs | 1918 +++++++++-------- CSJ2K/Icc/ICCProfileException.cs | 1 - CSJ2K/Icc/ICCProfileInvalidException.cs | 1 - CSJ2K/Icc/ICCProfileNotFoundException.cs | 1 - CSJ2K/Icc/ICCProfiler.cs | 4 +- .../Icc/Lut/MatrixBasedTransformException.cs | 1 - CSJ2K/Icc/Lut/MonochromeTransformException.cs | 1 - CSJ2K/Icc/Tags/ICCTag.cs | 14 +- CSJ2K/Icc/Tags/ICCTagTable.cs | 13 +- CSJ2K/Icc/Tags/ICCTextDescriptionType.cs | 2 +- CSJ2K/Icc/Tags/ICCTextType.cs | 2 +- CSJ2K/Icc/Tags/ICCXYZType.cs | 2 +- CSJ2K/Icc/Types/ICCDateTime.cs | 2 +- CSJ2K/Icc/Types/ICCProfileHeader.cs | 6 +- CSJ2K/Icc/Types/ICCProfileVersion.cs | 2 +- CSJ2K/Icc/Types/XYZNumber.cs | 2 +- CSJ2K/J2KEncoder.cs | 232 -- CSJ2K/J2kImage.cs | 1521 ++++++++++--- CSJ2K/Util/EndianBinaryReader.cs | 4 +- CSJ2K/Util/EndianBinaryWriter.cs | 4 +- CSJ2K/Util/SupportClass.cs | 293 +-- CSJ2K/j2k/IntegerSpec.cs | 6 +- CSJ2K/j2k/JJ2KExceptionHandler.cs | 10 +- CSJ2K/j2k/ModuleSpec.cs | 35 +- CSJ2K/j2k/NoNextElementException.cs | 3 +- .../CorruptedCodestreamException.cs | 1 - CSJ2K/j2k/codestream/HeaderInfo.cs | 39 +- CSJ2K/j2k/codestream/Markers.cs | 6 +- .../codestream/reader/BitstreamReaderAgent.cs | 6 +- .../reader/FileBitstreamReaderAgent.cs | 130 +- CSJ2K/j2k/codestream/reader/HeaderDecoder.cs | 46 +- CSJ2K/j2k/codestream/reader/PktDecoder.cs | 33 +- .../j2k/codestream/writer/BitOutputBuffer.cs | 534 ++--- .../codestream/writer/FileCodestreamWriter.cs | 44 +- CSJ2K/j2k/codestream/writer/HeaderEncoder.cs | 38 +- CSJ2K/j2k/codestream/writer/PktEncoder.cs | 2 +- CSJ2K/j2k/decoder/DecoderSpecs.cs | 6 +- CSJ2K/j2k/entropy/CBlkSizeSpec.cs | 6 +- CSJ2K/j2k/entropy/PrecinctSizeSpec.cs | 37 +- CSJ2K/j2k/entropy/Progression.cs | 2 +- CSJ2K/j2k/entropy/ProgressionSpec.cs | 9 +- .../j2k/entropy/decoder/StdEntropyDecoder.cs | 2 +- .../j2k/entropy/encoder/EBCOTRateAllocator.cs | 38 +- CSJ2K/j2k/entropy/encoder/MQCoder.cs | 4 +- .../entropy/encoder/PostCompRateAllocator.cs | 12 +- CSJ2K/j2k/entropy/encoder/StdEntropyCoder.cs | 479 +--- .../j2k/fileformat/reader/FileFormatReader.cs | 27 +- .../j2k/fileformat/writer/FileFormatWriter.cs | 29 +- CSJ2K/j2k/image/BlkImgDataSrc.cs | 289 +-- CSJ2K/j2k/image/ImgDataConverter.cs | 787 +++---- CSJ2K/j2k/image/ImgDataJoiner.cs | 1395 ++++++------ CSJ2K/j2k/image/Tiler.cs | 1444 +++++++------ .../image/forwcomptransf/ForwCompTransf.cs | 30 +- CSJ2K/j2k/image/input/ImgReader.cs | 12 +- CSJ2K/j2k/image/input/ImgReaderGDI.cs | 403 ---- CSJ2K/j2k/image/input/ImgReaderPGM.cs | 14 +- CSJ2K/j2k/image/input/ImgReaderPGX.cs | 67 +- CSJ2K/j2k/image/input/ImgReaderPPM.cs | 14 +- .../j2k/image/invcomptransf/InvCompTransf.cs | 1559 +++++++------- CSJ2K/j2k/image/output/ImgWriterPGM.cs | 33 +- CSJ2K/j2k/image/output/ImgWriterPGX.cs | 31 +- CSJ2K/j2k/image/output/ImgWriterPPM.cs | 33 +- CSJ2K/j2k/io/BEBufferedRandomAccessFile.cs | 149 +- CSJ2K/j2k/io/BufferedRandomAccessFile.cs | 114 +- CSJ2K/j2k/quantization/GuardBitsSpec.cs | 2 +- CSJ2K/j2k/quantization/QuantStepSizeSpec.cs | 2 +- CSJ2K/j2k/roi/encoder/ROIScaler.cs | 21 +- CSJ2K/j2k/util/ArrayUtil.cs | 135 +- CSJ2K/j2k/util/CodestreamManipulator.cs | 62 +- CSJ2K/j2k/util/FacilityManager.cs | 280 +-- CSJ2K/j2k/util/ISRandomAccessIO.cs | 6 +- CSJ2K/j2k/util/MathUtil.cs | 39 +- CSJ2K/j2k/util/MsgLogger.cs | 135 -- CSJ2K/j2k/util/ParameterList.cs | 17 +- CSJ2K/j2k/util/StreamMsgLogger.cs | 413 ++-- CSJ2K/j2k/util/StringFormatException.cs | 1 - CSJ2K/j2k/util/ThreadPool.cs | 648 ------ CSJ2K/j2k/wavelet/Subband.cs | 4 +- CSJ2K/j2k/wavelet/WTDecompSpec.cs | 20 +- CSJ2K/j2k/wavelet/analysis/ForwWTFull.cs | 4 +- CSJ2K/j2k/wavelet/analysis/ForwardWT.cs | 6 +- CSJ2K/j2k/wavelet/analysis/SubbandAn.cs | 8 +- CSJ2K/j2k/wavelet/synthesis/InvWTFull.cs | 23 +- CSJ2K/j2k/wavelet/synthesis/InverseWT.cs | 165 +- prebuildCoreLib.xml | 1 + 95 files changed, 7036 insertions(+), 7951 deletions(-) delete mode 100644 CSJ2K/AssemblyInfo.cs delete mode 100644 CSJ2K/J2KEncoder.cs delete mode 100644 CSJ2K/j2k/image/input/ImgReaderGDI.cs delete mode 100644 CSJ2K/j2k/util/MsgLogger.cs delete mode 100644 CSJ2K/j2k/util/ThreadPool.cs diff --git a/CSJ2K/AssemblyInfo.cs b/CSJ2K/AssemblyInfo.cs deleted file mode 100644 index c4e1d7a2..00000000 --- a/CSJ2K/AssemblyInfo.cs +++ /dev/null @@ -1,67 +0,0 @@ -using System; -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -[assembly: CLSCompliantAttribute(true)] - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. - -// TODO: Review the values of the assembly attributes - -[assembly: AssemblyTitle("CSJ2K")] -[assembly: AssemblyDescription("JPEG2000 decoding library")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("CSJ2K")] -[assembly: AssemblyCopyright("")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Revision -// Build Number -// -// You can specify all the values or you can default the Revision and Build Numbers -// by using the '*' as shown below: - -[assembly: AssemblyVersion("1.0.0.0")] - -// -// In order to sign your assembly you must specify a key to use. Refer to the -// Microsoft .NET Framework documentation for more information on assembly signing. -// -// Use the attributes below to control which key is used for signing. -// -// Notes: -// (*) If no key is specified, the assembly is not signed. -// (*) KeyName refers to a key that has been installed in the Crypto Service -// Provider (CSP) on your machine. KeyFile refers to a file which contains -// a key. -// (*) If the KeyFile and the KeyName values are both specified, the -// following processing occurs: -// (1) If the KeyName can be found in the CSP, that key is used. -// (2) If the KeyName does not exist and the KeyFile does exist, the key -// in the KeyFile is installed into the CSP and used. -// (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility. -// When specifying the KeyFile, the location of the KeyFile should be -// relative to the project output directory which is -// %Project Directory%\obj\. For example, if your KeyFile is -// located in the project directory, you would specify the AssemblyKeyFile -// attribute as [assembly: AssemblyKeyFile("..\..\mykey.snk")] -// (*) Delay Signing is an advanced option - see the Microsoft .NET Framework -// documentation for more information on this. -// - -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyDelaySign(false)] -[assembly: AssemblyKeyFile("")] -[assembly: AssemblyKeyName("")] - - -[assembly: ComVisibleAttribute(false)] diff --git a/CSJ2K/Color/ColorSpace.cs b/CSJ2K/Color/ColorSpace.cs index 20c4892b..f9023cb0 100644 --- a/CSJ2K/Color/ColorSpace.cs +++ b/CSJ2K/Color/ColorSpace.cs @@ -321,7 +321,8 @@ public override System.String ToString() /// public virtual bool debugging() { - return pl.Get("colorspace_debug") != null && pl.Get("colorspace_debug").ToUpper().Equals("on".ToUpper()); + string tmp; + return pl.TryGetValue("colorspace_debug", out tmp) && tmp.ToUpper().Equals("ON"); } diff --git a/CSJ2K/Color/ColorSpaceException.cs b/CSJ2K/Color/ColorSpaceException.cs index 6fb401ee..6026192c 100644 --- a/CSJ2K/Color/ColorSpaceException.cs +++ b/CSJ2K/Color/ColorSpaceException.cs @@ -21,7 +21,6 @@ namespace CSJ2K.Color /// Bruce A. Kern /// - [Serializable] public class ColorSpaceException:System.Exception { diff --git a/CSJ2K/Color/ColorSpaceMapper.cs b/CSJ2K/Color/ColorSpaceMapper.cs index 58f9acd1..3a28d310 100644 --- a/CSJ2K/Color/ColorSpaceMapper.cs +++ b/CSJ2K/Color/ColorSpaceMapper.cs @@ -10,252 +10,281 @@ using CSJ2K.j2k.image; using CSJ2K.j2k.util; using CSJ2K.Icc; + namespace CSJ2K.Color { - - /// This is the base class for all modules in the colorspace and icc - /// profiling steps of the decoding chain. It is responsible for the - /// allocation and iniitialization of all working storage. It provides - /// several utilities which are of generic use in preparing DataBlks - /// for use and provides default implementations for the getCompData - /// and getInternCompData methods. - /// - /// - /// - /// - /// 1.0 - /// - /// Bruce A. Kern - /// - public abstract class ColorSpaceMapper:ImgDataAdapter, BlkImgDataSrc - { - private void InitBlock() - { - computed = new ComputedComponents(this); - } - /// Returns the parameters that are used in this class and implementing - /// classes. It returns a 2D String array. Each of the 1D arrays is for a - /// different option, and they have 3 elements. The first element is the - /// option name, the second one is the synopsis and the third one is a long - /// description of what the parameter is. The synopsis or description may - /// be 'null', in which case it is assumed that there is no synopsis or - /// description of the option, respectively. Null may be returned if no - /// options are supported. - /// - /// - /// the options name, their synopsis and their explanation, or null - /// if no options are supported. - /// - /// - public static System.String[][] ParameterInfo - { - get - { - return pinfo; - } - - } - /// Arrange for the input DataBlk to receive an - /// appropriately sized and typed data buffer - /// - /// input DataBlk - /// - /// - /// - protected internal static DataBlk InternalBuffer - { - set - { - switch (value.DataType) - { - - - case DataBlk.TYPE_INT: - if (value.Data == null || ((int[]) value.Data).Length < value.w * value.h) - value.Data = new int[value.w * value.h]; - break; - - - case DataBlk.TYPE_FLOAT: - if (value.Data == null || ((float[]) value.Data).Length < value.w * value.h) - { - value.Data = new float[value.w * value.h]; - } - break; - - - default: - throw new System.ArgumentException("Invalid output datablock" + " type"); - - } - } - - } - - /// The prefix for ICC Profiler options - public const char OPT_PREFIX = 'I'; - - /// Platform dependant end of line String. - //UPGRADE_NOTE: Final was removed from the declaration of 'eol '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" - protected internal static readonly System.String eol = System.Environment.NewLine; - - // Temporary data buffers needed during profiling. - protected internal DataBlkInt[] inInt; // Integer input data. - protected internal DataBlkFloat[] inFloat; // Floating point input data. - protected internal DataBlkInt[] workInt; // Input data shifted to zero-offset - protected internal DataBlkFloat[] workFloat; // Input data shifted to zero-offset. - protected internal int[][] dataInt; // Points to input data. - protected internal float[][] dataFloat; // Points to input data. - protected internal float[][] workDataFloat; // References working data pixels. - protected internal int[][] workDataInt; // References working data pixels. - - - /* input data parameters by component */ - protected internal int[] shiftValueArray = null; - protected internal int[] maxValueArray = null; - protected internal int[] fixedPtBitsArray = null; - - /// The list of parameters that are accepted for ICC profiling. - //UPGRADE_NOTE: Final was removed from the declaration of 'pinfo'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" - private static readonly System.String[][] pinfo = new System.String[][]{new System.String[]{"IcolorSpacedebug", null, "Print debugging messages during colorspace mapping.", "off"}}; - - /// Parameter Specs - protected internal ParameterList pl = null; - - /// ColorSpace info - protected internal ColorSpace csMap = null; - - /// Number of image components - protected internal int ncomps = 0; - - /// The image source. - protected internal BlkImgDataSrc src = null; - - /// The image source data per component. - protected internal DataBlk[] srcBlk = null; - - - //UPGRADE_NOTE: Field 'EnclosingInstance' was added to class 'ComputedComponents' to access its enclosing instance. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1019'" - protected internal class ComputedComponents - { - private void InitBlock(ColorSpaceMapper enclosingInstance) - { - this.enclosingInstance = enclosingInstance; - } - private ColorSpaceMapper enclosingInstance; - public ColorSpaceMapper Enclosing_Instance - { - get - { - return enclosingInstance; - } - - } - //private int tIdx = - 1; - private int h = - 1; - private int w = - 1; - private int ulx = - 1; - private int uly = - 1; - private int offset = - 1; - private int scanw = - 1; - - public ComputedComponents(ColorSpaceMapper enclosingInstance) - { - InitBlock(enclosingInstance); - clear(); - } - - public ComputedComponents(ColorSpaceMapper enclosingInstance, DataBlk db) - { - InitBlock(enclosingInstance); - set_Renamed(db); - } - - public virtual void set_Renamed(DataBlk db) - { - h = db.h; - w = db.w; - ulx = db.ulx; - uly = db.uly; - offset = db.offset; - scanw = db.scanw; - } - - public virtual void clear() - { - h = w = ulx = uly = offset = scanw = - 1; - } - - public bool Equals(ComputedComponents cc) - { - return (h == cc.h && w == cc.w && ulx == cc.ulx && uly == cc.uly && offset == cc.offset && scanw == cc.scanw); - } - - /* end class ComputedComponents */ - } - - //UPGRADE_NOTE: The initialization of 'computed' was moved to method 'InitBlock'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'" - protected internal ComputedComponents computed; - - /// Copy the DataBlk geometry from source to target - /// DataBlk and assure that the target has an appropriate - /// data buffer. - /// - /// has its geometry set. - /// - /// used to get the new geometric parameters. - /// - protected internal static void copyGeometry(DataBlk tgt, DataBlk src) - { - tgt.offset = 0; - tgt.h = src.h; - tgt.w = src.w; - tgt.ulx = src.ulx; - tgt.uly = src.uly; - tgt.scanw = src.w; - - // Create data array if necessary - - InternalBuffer = tgt; - } - - - /// Factory method for creating instances of this class. - /// -- source of image data - /// - /// -- provides colorspace info - /// - /// ColorSpaceMapper instance - /// - /// profile access exception - /// - public static BlkImgDataSrc createInstance(BlkImgDataSrc src, ColorSpace csMap) - { - - // Check parameters - csMap.pl.checkList(OPT_PREFIX, CSJ2K.j2k.util.ParameterList.toNameArray(pinfo)); - - // Perform ICCProfiling or ColorSpace tranfsormation. - if (csMap.Method == ColorSpace.MethodEnum.ICC_PROFILED) - { - return ICCProfiler.createInstance(src, csMap); - } - else - { - ColorSpace.CSEnum colorspace = csMap.getColorSpace(); - - if (colorspace == ColorSpace.CSEnum.sRGB) - { - return EnumeratedColorSpaceMapper.createInstance(src, csMap); - } - else if (colorspace == ColorSpace.CSEnum.GreyScale) - { - return EnumeratedColorSpaceMapper.createInstance(src, csMap); - } - else if (colorspace == ColorSpace.CSEnum.sYCC) - { - return SYccColorSpaceMapper.createInstance(src, csMap); - } + + /// This is the base class for all modules in the colorspace and icc + /// profiling steps of the decoding chain. It is responsible for the + /// allocation and iniitialization of all working storage. It provides + /// several utilities which are of generic use in preparing DataBlks + /// for use and provides default implementations for the getCompData + /// and getInternCompData methods. + /// + /// + /// + /// + /// 1.0 + /// + /// Bruce A. Kern + /// + public abstract class ColorSpaceMapper : ImgDataAdapter, BlkImgDataSrc + { + private void InitBlock() + { + computed = new ComputedComponents(this); + } + + /// Returns the parameters that are used in this class and implementing + /// classes. It returns a 2D String array. Each of the 1D arrays is for a + /// different option, and they have 3 elements. The first element is the + /// option name, the second one is the synopsis and the third one is a long + /// description of what the parameter is. The synopsis or description may + /// be 'null', in which case it is assumed that there is no synopsis or + /// description of the option, respectively. Null may be returned if no + /// options are supported. + /// + /// + /// the options name, their synopsis and their explanation, or null + /// if no options are supported. + /// + /// + public static System.String[][] ParameterInfo + { + get + { + return pinfo; + } + + } + + /// Arrange for the input DataBlk to receive an + /// appropriately sized and typed data buffer + /// + /// input DataBlk + /// + /// + /// + protected internal static DataBlk InternalBuffer + { + set + { + switch (value.DataType) + { + + + case DataBlk.TYPE_INT: + if (value.Data == null || ((int[])value.Data).Length < value.w * value.h) value.Data = new int[value.w * value.h]; + break; + + + case DataBlk.TYPE_FLOAT: + if (value.Data == null || ((float[])value.Data).Length < value.w * value.h) + { + value.Data = new float[value.w * value.h]; + } + break; + + + default: + throw new System.ArgumentException("Invalid output datablock" + " type"); + + } + } + + } + + /// The prefix for ICC Profiler options + public const char OPT_PREFIX = 'I'; + + /// Platform dependant end of line String. + //UPGRADE_NOTE: Final was removed from the declaration of 'eol '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" + protected internal static readonly System.String eol = System.Environment.NewLine; + + // Temporary data buffers needed during profiling. + protected internal DataBlkInt[] inInt; // Integer input data. + + protected internal DataBlkFloat[] inFloat; // Floating point input data. + + protected internal DataBlkInt[] workInt; // Input data shifted to zero-offset + + protected internal DataBlkFloat[] workFloat; // Input data shifted to zero-offset. + + protected internal int[][] dataInt; // Points to input data. + + protected internal float[][] dataFloat; // Points to input data. + + protected internal float[][] workDataFloat; // References working data pixels. + + protected internal int[][] workDataInt; // References working data pixels. + + + /* input data parameters by component */ + + protected internal int[] shiftValueArray = null; + + protected internal int[] maxValueArray = null; + + protected internal int[] fixedPtBitsArray = null; + + /// The list of parameters that are accepted for ICC profiling. + //UPGRADE_NOTE: Final was removed from the declaration of 'pinfo'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" + private static readonly System.String[][] pinfo = new System.String[][] + { + new System.String[] + { + "IcolorSpacedebug", null, + "Print debugging messages during colorspace mapping.", + "off" + } + }; + + /// Parameter Specs + protected internal ParameterList pl = null; + + /// ColorSpace info + protected internal ColorSpace csMap = null; + + /// Number of image components + protected internal int ncomps = 0; + + /// The image source. + protected internal BlkImgDataSrc src = null; + + /// The image source data per component. + protected internal DataBlk[] srcBlk = null; + + + //UPGRADE_NOTE: Field 'EnclosingInstance' was added to class 'ComputedComponents' to access its enclosing instance. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1019'" + protected internal class ComputedComponents + { + private void InitBlock(ColorSpaceMapper enclosingInstance) + { + this.enclosingInstance = enclosingInstance; + } + + private ColorSpaceMapper enclosingInstance; + + public ColorSpaceMapper Enclosing_Instance + { + get + { + return enclosingInstance; + } + + } + + //private int tIdx = - 1; + private int h = -1; + + private int w = -1; + + private int ulx = -1; + + private int uly = -1; + + private int offset = -1; + + private int scanw = -1; + + public ComputedComponents(ColorSpaceMapper enclosingInstance) + { + InitBlock(enclosingInstance); + clear(); + } + + public ComputedComponents(ColorSpaceMapper enclosingInstance, DataBlk db) + { + InitBlock(enclosingInstance); + set_Renamed(db); + } + + public virtual void set_Renamed(DataBlk db) + { + h = db.h; + w = db.w; + ulx = db.ulx; + uly = db.uly; + offset = db.offset; + scanw = db.scanw; + } + + public virtual void clear() + { + h = w = ulx = uly = offset = scanw = -1; + } + + public bool Equals(ComputedComponents cc) + { + return (h == cc.h && w == cc.w && ulx == cc.ulx && uly == cc.uly && offset == cc.offset + && scanw == cc.scanw); + } + + /* end class ComputedComponents */ + } + + //UPGRADE_NOTE: The initialization of 'computed' was moved to method 'InitBlock'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'" + protected internal ComputedComponents computed; + + /// Copy the DataBlk geometry from source to target + /// DataBlk and assure that the target has an appropriate + /// data buffer. + /// + /// has its geometry set. + /// + /// used to get the new geometric parameters. + /// + protected internal static void copyGeometry(DataBlk tgt, DataBlk src) + { + tgt.offset = 0; + tgt.h = src.h; + tgt.w = src.w; + tgt.ulx = src.ulx; + tgt.uly = src.uly; + tgt.scanw = src.w; + + // Create data array if necessary + + InternalBuffer = tgt; + } + + + /// Factory method for creating instances of this class. + /// -- source of image data + /// + /// -- provides colorspace info + /// + /// ColorSpaceMapper instance + /// + /// profile access exception + /// + public static BlkImgDataSrc createInstance(BlkImgDataSrc src, ColorSpace csMap) + { + + // Check parameters + csMap.pl.checkList(OPT_PREFIX, CSJ2K.j2k.util.ParameterList.toNameArray(pinfo)); + + // Perform ICCProfiling or ColorSpace tranfsormation. + if (csMap.Method == ColorSpace.MethodEnum.ICC_PROFILED) + { + return ICCProfiler.createInstance(src, csMap); + } + else + { + ColorSpace.CSEnum colorspace = csMap.getColorSpace(); + + if (colorspace == ColorSpace.CSEnum.sRGB) + { + return EnumeratedColorSpaceMapper.createInstance(src, csMap); + } + else if (colorspace == ColorSpace.CSEnum.GreyScale) + { + return EnumeratedColorSpaceMapper.createInstance(src, csMap); + } + else if (colorspace == ColorSpace.CSEnum.sYCC) + { + return SYccColorSpaceMapper.createInstance(src, csMap); + } if (colorspace == ColorSpace.CSEnum.esRGB) { return EsRgbColorSpaceMapper.createInstance(src, csMap); @@ -268,185 +297,212 @@ public static BlkImgDataSrc createInstance(BlkImgDataSrc src, ColorSpace csMap) { throw new ColorSpaceException("Bad color space specification in image"); } - } - } - - /// Ctor which creates an ICCProfile for the image and initializes - /// all data objects (input, working, and output). - /// - /// - /// -- Source of image data - /// - /// -- provides colorspace info - /// - /// - protected internal ColorSpaceMapper(BlkImgDataSrc src, ColorSpace csMap):base(src) - { - InitBlock(); - this.src = src; - this.csMap = csMap; - initialize(); - /* end ColorSpaceMapper ctor */ - } - - /// General utility used by ctors - private void initialize() - { - - this.pl = csMap.pl; - this.ncomps = src.NumComps; - - shiftValueArray = new int[ncomps]; - maxValueArray = new int[ncomps]; - fixedPtBitsArray = new int[ncomps]; - - srcBlk = new DataBlk[ncomps]; - inInt = new DataBlkInt[ncomps]; - inFloat = new DataBlkFloat[ncomps]; - workInt = new DataBlkInt[ncomps]; - workFloat = new DataBlkFloat[ncomps]; - dataInt = new int[ncomps][]; - dataFloat = new float[ncomps][]; - workDataInt = new int[ncomps][]; - workDataFloat = new float[ncomps][]; - dataInt = new int[ncomps][]; - dataFloat = new float[ncomps][]; - - - /* For each component, get a reference to the pixel data and + } + } + + /// Ctor which creates an ICCProfile for the image and initializes + /// all data objects (input, working, and output). + /// + /// + /// -- Source of image data + /// + /// -- provides colorspace info + /// + /// + protected internal ColorSpaceMapper(BlkImgDataSrc src, ColorSpace csMap) + : base(src) + { + InitBlock(); + this.src = src; + this.csMap = csMap; + initialize(); + /* end ColorSpaceMapper ctor */ + } + + /// General utility used by ctors + private void initialize() + { + + this.pl = csMap.pl; + this.ncomps = src.NumComps; + + shiftValueArray = new int[ncomps]; + maxValueArray = new int[ncomps]; + fixedPtBitsArray = new int[ncomps]; + + srcBlk = new DataBlk[ncomps]; + inInt = new DataBlkInt[ncomps]; + inFloat = new DataBlkFloat[ncomps]; + workInt = new DataBlkInt[ncomps]; + workFloat = new DataBlkFloat[ncomps]; + dataInt = new int[ncomps][]; + dataFloat = new float[ncomps][]; + workDataInt = new int[ncomps][]; + workDataFloat = new float[ncomps][]; + dataInt = new int[ncomps][]; + dataFloat = new float[ncomps][]; + + + /* For each component, get a reference to the pixel data and * set up working DataBlks for both integer and float output. */ - for (int i = 0; i < ncomps; ++i) - { - - shiftValueArray[i] = 1 << (src.getNomRangeBits(i) - 1); - maxValueArray[i] = (1 << src.getNomRangeBits(i)) - 1; - fixedPtBitsArray[i] = src.getFixedPoint(i); - - inInt[i] = new DataBlkInt(); - inFloat[i] = new DataBlkFloat(); - workInt[i] = new DataBlkInt(); - workInt[i].progressive = inInt[i].progressive; - workFloat[i] = new DataBlkFloat(); - workFloat[i].progressive = inFloat[i].progressive; - } - } - - /// Returns the number of bits, referred to as the "range bits", - /// corresponding to the nominal range of the data in the specified - /// component. If this number is b then for unsigned data the - /// nominal range is between 0 and 2^b-1, and for signed data it is between - /// -2^(b-1) and 2^(b-1)-1. For floating point data this value is not - /// applicable. - /// - /// - /// The index of the component. - /// - /// - /// The number of bits corresponding to the nominal range of the - /// data. Fro floating-point data this value is not applicable and the - /// return value is undefined. - /// - public virtual int getFixedPoint(int c) - { - return src.getFixedPoint(c); - } - - /// Returns, in the blk argument, a block of image data containing the - /// specifed rectangular area, in the specified component. The data is - /// returned, as a copy of the internal data, therefore the returned data - /// can be modified "in place". - /// - ///

The rectangular area to return is specified by the 'ulx', 'uly', 'w' - /// and 'h' members of the 'blk' argument, relative to the current - /// tile. These members are not modified by this method. The 'offset' of - /// the returned data is 0, and the 'scanw' is the same as the block's - /// width. See the 'DataBlk' class. - /// - ///

This method, in general, is less efficient than the - /// 'getInternCompData()' method since, in general, it copies the - /// data. However if the array of returned data is to be modified by the - /// caller then this method is preferable. - /// - ///

If the data array in 'blk' is 'null', then a new one is created. If - /// the data array is not 'null' then it is reused, and it must be large - /// enough to contain the block's data. Otherwise an 'ArrayStoreException' - /// or an 'IndexOutOfBoundsException' is thrown by the Java system. - /// - ///

The returned data may have its 'progressive' attribute set. In this - /// case the returned data is only an approximation of the "final" data. - /// - ///

- /// Its coordinates and dimensions specify the area to return, - /// relative to the current tile. If it contains a non-null data array, - /// then it must be large enough. If it contains a null data array a new - /// one is created. Some fields in this object are modified to return the - /// data. - /// - /// - /// The index of the component from which to get the data. - /// - /// - /// - /// - /// - public virtual DataBlk getCompData(DataBlk out_Renamed, int c) - { - return src.getCompData(out_Renamed, c); - } - - /// Returns, in the blk argument, a block of image data containing the - /// specifed rectangular area, in the specified component. The data is - /// returned, as a reference to the internal data, if any, instead of as a - /// copy, therefore the returned data should not be modified. - /// - ///

The rectangular area to return is specified by the 'ulx', 'uly', 'w' - /// and 'h' members of the 'blk' argument, relative to the current - /// tile. These members are not modified by this method. The 'offset' and - /// 'scanw' of the returned data can be arbitrary. See the 'DataBlk' class. - /// - ///

This method, in general, is more efficient than the 'getCompData()' - /// method since it may not copy the data. However if the array of returned - /// data is to be modified by the caller then the other method is probably - /// preferable. - /// - ///

If possible, the data in the returned 'DataBlk' should be the - /// internal data itself, instead of a copy, in order to increase the data - /// transfer efficiency. However, this depends on the particular - /// implementation (it may be more convenient to just return a copy of the - /// data). This is the reason why the returned data should not be modified. - /// - ///

If the data array in blk is null, then a new one - /// is created if necessary. The implementation of this interface may - /// choose to return the same array or a new one, depending on what is more - /// efficient. Therefore, the data array in blk prior to the - /// method call should not be considered to contain the returned data, a - /// new array may have been created. Instead, get the array from - /// blk after the method has returned. - /// - ///

The returned data may have its 'progressive' attribute set. In this - /// case the returned data is only an approximation of the "final" data. - /// - ///

- /// Its coordinates and dimensions specify the area to return, - /// relative to the current tile. Some fields in this object are modified - /// to return the data. - /// - /// - /// The index of the component from which to get the data. - /// - /// - /// The requested DataBlk - /// - /// - /// - /// - /// - public virtual DataBlk getInternCompData(DataBlk out_Renamed, int c) - { - return src.getInternCompData(out_Renamed, c); - } - - /* end class ColorSpaceMapper */ - } -} \ No newline at end of file + for (int i = 0; i < ncomps; ++i) + { + + shiftValueArray[i] = 1 << (src.getNomRangeBits(i) - 1); + maxValueArray[i] = (1 << src.getNomRangeBits(i)) - 1; + fixedPtBitsArray[i] = src.getFixedPoint(i); + + inInt[i] = new DataBlkInt(); + inFloat[i] = new DataBlkFloat(); + workInt[i] = new DataBlkInt(); + workInt[i].progressive = inInt[i].progressive; + workFloat[i] = new DataBlkFloat(); + workFloat[i].progressive = inFloat[i].progressive; + } + } + + /// Returns the number of bits, referred to as the "range bits", + /// corresponding to the nominal range of the data in the specified + /// component. If this number is b then for unsigned data the + /// nominal range is between 0 and 2^b-1, and for signed data it is between + /// -2^(b-1) and 2^(b-1)-1. For floating point data this value is not + /// applicable. + /// + /// + /// The index of the component. + /// + /// + /// The number of bits corresponding to the nominal range of the + /// data. Fro floating-point data this value is not applicable and the + /// return value is undefined. + /// + public virtual int getFixedPoint(int c) + { + return src.getFixedPoint(c); + } + + /// Returns, in the blk argument, a block of image data containing the + /// specifed rectangular area, in the specified component. The data is + /// returned, as a copy of the internal data, therefore the returned data + /// can be modified "in place". + /// + ///

The rectangular area to return is specified by the 'ulx', 'uly', 'w' + /// and 'h' members of the 'blk' argument, relative to the current + /// tile. These members are not modified by this method. The 'offset' of + /// the returned data is 0, and the 'scanw' is the same as the block's + /// width. See the 'DataBlk' class. + /// + ///

This method, in general, is less efficient than the + /// 'getInternCompData()' method since, in general, it copies the + /// data. However if the array of returned data is to be modified by the + /// caller then this method is preferable. + /// + ///

If the data array in 'blk' is 'null', then a new one is created. If + /// the data array is not 'null' then it is reused, and it must be large + /// enough to contain the block's data. Otherwise an 'ArrayStoreException' + /// or an 'IndexOutOfBoundsException' is thrown by the Java system. + /// + ///

The returned data may have its 'progressive' attribute set. In this + /// case the returned data is only an approximation of the "final" data. + /// + ///

+ /// Its coordinates and dimensions specify the area to return, + /// relative to the current tile. If it contains a non-null data array, + /// then it must be large enough. If it contains a null data array a new + /// one is created. Some fields in this object are modified to return the + /// data. + /// + /// + /// The index of the component from which to get the data. + /// + /// + /// + /// + /// + public virtual DataBlk getCompData(DataBlk out_Renamed, int c) + { + return src.getCompData(out_Renamed, c); + } + + /// Closes the underlying file or network connection from where the + /// image data is being read. + /// + /// + /// If an I/O error occurs. + /// + public void close() + { + // Do nothing. + } + + /// Returns true if the data read was originally signed in the specified + /// component, false if not. + /// + /// + /// The index of the component, from 0 to C-1. + /// + /// + /// true if the data was originally signed, false if not. + /// + /// + public bool isOrigSigned(int c) + { + return false; + } + + /// Returns, in the blk argument, a block of image data containing the + /// specifed rectangular area, in the specified component. The data is + /// returned, as a reference to the internal data, if any, instead of as a + /// copy, therefore the returned data should not be modified. + /// + ///

The rectangular area to return is specified by the 'ulx', 'uly', 'w' + /// and 'h' members of the 'blk' argument, relative to the current + /// tile. These members are not modified by this method. The 'offset' and + /// 'scanw' of the returned data can be arbitrary. See the 'DataBlk' class. + /// + ///

This method, in general, is more efficient than the 'getCompData()' + /// method since it may not copy the data. However if the array of returned + /// data is to be modified by the caller then the other method is probably + /// preferable. + /// + ///

If possible, the data in the returned 'DataBlk' should be the + /// internal data itself, instead of a copy, in order to increase the data + /// transfer efficiency. However, this depends on the particular + /// implementation (it may be more convenient to just return a copy of the + /// data). This is the reason why the returned data should not be modified. + /// + ///

If the data array in blk is null, then a new one + /// is created if necessary. The implementation of this interface may + /// choose to return the same array or a new one, depending on what is more + /// efficient. Therefore, the data array in blk prior to the + /// method call should not be considered to contain the returned data, a + /// new array may have been created. Instead, get the array from + /// blk after the method has returned. + /// + ///

The returned data may have its 'progressive' attribute set. In this + /// case the returned data is only an approximation of the "final" data. + /// + ///

+ /// Its coordinates and dimensions specify the area to return, + /// relative to the current tile. Some fields in this object are modified + /// to return the data. + /// + /// + /// The index of the component from which to get the data. + /// + /// + /// The requested DataBlk + /// + /// + /// + /// + /// + public virtual DataBlk getInternCompData(DataBlk out_Renamed, int c) + { + return src.getInternCompData(out_Renamed, c); + } + + /* end class ColorSpaceMapper */ + } +} diff --git a/CSJ2K/Color/EnumeratedColorSpaceMapper.cs b/CSJ2K/Color/EnumeratedColorSpaceMapper.cs index d2739e41..c5163b6a 100644 --- a/CSJ2K/Color/EnumeratedColorSpaceMapper.cs +++ b/CSJ2K/Color/EnumeratedColorSpaceMapper.cs @@ -14,7 +14,7 @@ using DataBlkFloat = CSJ2K.j2k.image.DataBlkFloat; using ImgDataAdapter = CSJ2K.j2k.image.ImgDataAdapter; using FacilityManager = CSJ2K.j2k.util.FacilityManager; -using MsgLogger = CSJ2K.j2k.util.MsgLogger; + namespace CSJ2K.Color { diff --git a/CSJ2K/Color/EsRgbColorSpaceMapper.cs b/CSJ2K/Color/EsRgbColorSpaceMapper.cs index 8ba6a34f..2e412fc6 100644 --- a/CSJ2K/Color/EsRgbColorSpaceMapper.cs +++ b/CSJ2K/Color/EsRgbColorSpaceMapper.cs @@ -14,7 +14,7 @@ using DataBlkFloat = CSJ2K.j2k.image.DataBlkFloat; using ImgDataAdapter = CSJ2K.j2k.image.ImgDataAdapter; using FacilityManager = CSJ2K.j2k.util.FacilityManager; -using MsgLogger = CSJ2K.j2k.util.MsgLogger; + namespace CSJ2K.Color { diff --git a/CSJ2K/Color/SYccColorSpaceMapper.cs b/CSJ2K/Color/SYccColorSpaceMapper.cs index 18e26251..9a839695 100644 --- a/CSJ2K/Color/SYccColorSpaceMapper.cs +++ b/CSJ2K/Color/SYccColorSpaceMapper.cs @@ -14,7 +14,7 @@ using DataBlkFloat = CSJ2K.j2k.image.DataBlkFloat; using ImgDataAdapter = CSJ2K.j2k.image.ImgDataAdapter; using FacilityManager = CSJ2K.j2k.util.FacilityManager; -using MsgLogger = CSJ2K.j2k.util.MsgLogger; + namespace CSJ2K.Color { diff --git a/CSJ2K/Color/boxes/ChannelDefinitionBox.cs b/CSJ2K/Color/boxes/ChannelDefinitionBox.cs index 467ed977..46e0b7fc 100644 --- a/CSJ2K/Color/boxes/ChannelDefinitionBox.cs +++ b/CSJ2K/Color/boxes/ChannelDefinitionBox.cs @@ -7,6 +7,7 @@ /// *************************************************************************** ///
using System; +using System.Collections.Generic; using ColorSpaceException = CSJ2K.Color.ColorSpaceException; using ICCProfile = CSJ2K.Icc.ICCProfile; using ParameterList = CSJ2K.j2k.util.ParameterList; @@ -37,7 +38,7 @@ public int NDefs } private int ndefs; - private System.Collections.Hashtable definitions = System.Collections.Hashtable.Synchronized(new System.Collections.Hashtable()); + private System.Collections.Generic.Dictionary definitions = new Dictionary(); /// Construct a ChannelDefinitionBox from an input image. /// RandomAccessIO jp2 image @@ -78,7 +79,7 @@ private void readBox() /* Return the channel association. */ public int getCn(int asoc) { - System.Collections.IEnumerator keys = definitions.Keys.GetEnumerator(); + System.Collections.Generic.IEnumerator keys = definitions.Keys.GetEnumerator(); //UPGRADE_TODO: Method 'java.util.Enumeration.hasMoreElements' was converted to 'System.Collections.IEnumerator.MoveNext' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationhasMoreElements'" while (keys.MoveNext()) { @@ -111,7 +112,7 @@ public override System.String ToString() System.Text.StringBuilder rep = new System.Text.StringBuilder("[ChannelDefinitionBox ").Append(eol).Append(" "); rep.Append("ndefs= ").Append(System.Convert.ToString(ndefs)); - System.Collections.IEnumerator keys = definitions.Keys.GetEnumerator(); + System.Collections.Generic.IEnumerator keys = definitions.Keys.GetEnumerator(); //UPGRADE_TODO: Method 'java.util.Enumeration.hasMoreElements' was converted to 'System.Collections.IEnumerator.MoveNext' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationhasMoreElements'" while (keys.MoveNext()) { diff --git a/CSJ2K/Color/boxes/ComponentMappingBox.cs b/CSJ2K/Color/boxes/ComponentMappingBox.cs index 631f3fee..7fe695f8 100644 --- a/CSJ2K/Color/boxes/ComponentMappingBox.cs +++ b/CSJ2K/Color/boxes/ComponentMappingBox.cs @@ -7,6 +7,7 @@ /// *************************************************************************** ///
using System; +using System.Collections.Generic; using ColorSpaceException = CSJ2K.Color.ColorSpaceException; using ICCProfile = CSJ2K.Icc.ICCProfile; using ParameterList = CSJ2K.j2k.util.ParameterList; @@ -37,7 +38,7 @@ public int NChannels } private int nChannels; - private System.Collections.ArrayList map = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10)); + private System.Collections.Generic.List map = new List(10); /// Construct a ComponentMappingBox from an input image. /// RandomAccessIO jp2 image diff --git a/CSJ2K/Color/boxes/JP2Box.cs b/CSJ2K/Color/boxes/JP2Box.cs index e1c0d160..87a09a64 100644 --- a/CSJ2K/Color/boxes/JP2Box.cs +++ b/CSJ2K/Color/boxes/JP2Box.cs @@ -7,6 +7,7 @@ /// *************************************************************************** ///
using System; +using System.Collections.Generic; using ColorSpaceException = CSJ2K.Color.ColorSpaceException; using FileFormatBoxes = CSJ2K.j2k.fileformat.FileFormatBoxes; using ICCProfile = CSJ2K.Icc.ICCProfile; @@ -48,18 +49,6 @@ public static System.String getTypeString(int t) /// offset to start of data in box protected internal int dataStart; - public JP2Box() - { - try - { - throw new ColorSpaceException("JP2Box empty ctor called!!"); - } - catch (ColorSpaceException e) - { - SupportClass.WriteStackTrace(e, Console.Error); throw e; - } - } - /// Construct a JP2Box from an input image. /// RandomAccessIO jp2 image /// @@ -93,11 +82,10 @@ public virtual System.String getTypeString() /// JP2 Box structure analysis help - [Serializable] - protected internal class BoxType:System.Collections.Hashtable + protected internal class BoxType:System.Collections.Generic.Dictionary { - - private static System.Collections.Hashtable map = System.Collections.Hashtable.Synchronized(new System.Collections.Hashtable()); + + private static System.Collections.Generic.Dictionary map = new Dictionary(); private static void put(int type, System.String desc) { diff --git a/CSJ2K/Icc/ICCProfile.cs b/CSJ2K/Icc/ICCProfile.cs index 701371f7..44c640a8 100644 --- a/CSJ2K/Icc/ICCProfile.cs +++ b/CSJ2K/Icc/ICCProfile.cs @@ -1,4 +1,5 @@ -/// ************************************************************************** +/// +/// ************************************************************************** /// /// $Id: ICCProfile.java,v 1.1 2002/07/25 14:56:55 grosbois Exp $ /// @@ -6,952 +7,989 @@ /// $Date $ /// *************************************************************************** /// -using System; -using System.Text; -using ParameterList = CSJ2K.j2k.util.ParameterList; -using DecoderSpecs = CSJ2K.j2k.decoder.DecoderSpecs; -using BitstreamReaderAgent = CSJ2K.j2k.codestream.reader.BitstreamReaderAgent; -using ColorSpace = CSJ2K.Color.ColorSpace; -using ColorSpaceException = CSJ2K.Color.ColorSpaceException; -using ICCProfileHeader = CSJ2K.Icc.Types.ICCProfileHeader; -using ICCTag = CSJ2K.Icc.Tags.ICCTag; -using ICCTagTable = CSJ2K.Icc.Tags.ICCTagTable; -using ICCCurveType = CSJ2K.Icc.Tags.ICCCurveType; -using ICCXYZType = CSJ2K.Icc.Tags.ICCXYZType; -using XYZNumber = CSJ2K.Icc.Types.XYZNumber; -using ICCProfileVersion = CSJ2K.Icc.Types.ICCProfileVersion; -using ICCDateTime = CSJ2K.Icc.Types.ICCDateTime; -using FileFormatBoxes = CSJ2K.j2k.fileformat.FileFormatBoxes; -using RandomAccessIO = CSJ2K.j2k.io.RandomAccessIO; -using FacilityManager = CSJ2K.j2k.util.FacilityManager; -using MsgLogger = CSJ2K.j2k.util.MsgLogger; + namespace CSJ2K.Icc { - - /// This class models the ICCProfile file. This file is a binary file which is divided - /// into two parts, an ICCProfileHeader followed by an ICCTagTable. The header is a - /// straightforward list of descriptive parameters such as profile size, version, date and various - /// more esoteric parameters. The tag table is a structured list of more complexly aggragated data - /// describing things such as ICC curves, copyright information, descriptive text blocks, etc. - /// - /// Classes exist to model the header and tag table and their various constituent parts the developer - /// is refered to these for further information on the structure and contents of the header and tag table. - /// - /// - /// - /// - /// - /// - /// 1.0 - /// - /// Bruce A. Kern - /// - - public abstract class ICCProfile - { - private int ProfileSize - { - get - { - return header.dwProfileSize; - } - - set - { - header.dwProfileSize = value; - } - - } - private int CMMTypeSignature - { - get - { - return header.dwCMMTypeSignature; - } - - set - { - header.dwCMMTypeSignature = value; - } - - } - private int ProfileClass - { - get - { - return header.dwProfileClass; - } - - set - { - header.dwProfileClass = value; - } - - } - private int ColorSpaceType - { - get - { - return header.dwColorSpaceType; - } - - set - { - header.dwColorSpaceType = value; - } - - } - private int PCSType - { - get - { - return header.dwPCSType; - } - - set - { - header.dwPCSType = value; - } - - } - private int ProfileSignature - { - get - { - return header.dwProfileSignature; - } - - set - { - header.dwProfileSignature = value; - } - - } - private int PlatformSignature - { - get - { - return header.dwPlatformSignature; - } - - set - { - header.dwPlatformSignature = value; - } - - } - private int CMMFlags - { - get - { - return header.dwCMMFlags; - } - - set - { - header.dwCMMFlags = value; - } - - } - private int DeviceManufacturer - { - get - { - return header.dwDeviceManufacturer; - } - - set - { - header.dwDeviceManufacturer = value; - } - - } - private int DeviceModel - { - get - { - return header.dwDeviceModel; - } - - set - { - header.dwDeviceModel = value; - } - - } - private int DeviceAttributes1 - { - get - { - return header.dwDeviceAttributes1; - } - - set - { - header.dwDeviceAttributes1 = value; - } - - } - private int DeviceAttributesReserved - { - get - { - return header.dwDeviceAttributesReserved; - } - - set - { - header.dwDeviceAttributesReserved = value; - } - - } - private int RenderingIntent - { - get - { - return header.dwRenderingIntent; - } - - set - { - header.dwRenderingIntent = value; - } - - } - private int CreatorSig - { - get - { - return header.dwCreatorSig; - } - - set - { - header.dwCreatorSig = value; - } - - } - private ICCProfileVersion ProfileVersion - { - get - { - return header.profileVersion; - } - - set - { - header.profileVersion = value; - } - - } - private XYZNumber PCSIlluminant - { - set - { - header.PCSIlluminant = value; - } - - } - private ICCDateTime DateTime - { - set - { - header.dateTime = value; - } - - } - /// Access the profile header - /// ICCProfileHeader - /// - virtual public ICCProfileHeader Header - { - get - { - return header; - } - - } - /// Access the profile tag table - /// ICCTagTable - /// - virtual public ICCTagTable TagTable - { - get - { - return tags; - } - - } - - //UPGRADE_NOTE: Final was removed from the declaration of 'eol '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" - private static readonly System.String eol = System.Environment.NewLine; - - /// Gray index. - // Renamed for convenience: - public const int GRAY = 0; - /// RGB index. - public const int RED = 0; - /// RGB index. - public const int GREEN = 1; - /// RGB index. - public const int BLUE = 2; - - /// Size of native type - public const int boolean_size = 1; - /// Size of native type - public const int byte_size = 1; - /// Size of native type - public const int char_size = 2; - /// Size of native type - public const int short_size = 2; - /// Size of native type - public const int int_size = 4; - /// Size of native type - public const int float_size = 4; - /// Size of native type - public const int long_size = 8; - /// Size of native type - public const int double_size = 8; - - /* Bit twiddling constant for integral types. */ public const int BITS_PER_BYTE = 8; - /* Bit twiddling constant for integral types. */ public const int BITS_PER_SHORT = 16; - /* Bit twiddling constant for integral types. */ public const int BITS_PER_INT = 32; - /* Bit twiddling constant for integral types. */ public const int BITS_PER_LONG = 64; - /* Bit twiddling constant for integral types. */ public const int BYTES_PER_SHORT = 2; - /* Bit twiddling constant for integral types. */ public const int BYTES_PER_INT = 4; - /* Bit twiddling constant for integral types. */ public const int BYTES_PER_LONG = 8; - - /* JP2 Box structure analysis help */ - - [Serializable] - private class BoxType:System.Collections.Hashtable - { - - private static System.Collections.Hashtable map = System.Collections.Hashtable.Synchronized(new System.Collections.Hashtable()); - - public static void put(int type, System.String desc) - { - map[(System.Int32) type] = desc; - } - - public static System.String get_Renamed(int type) - { - return (System.String) map[(System.Int32) type]; - } - - public static System.String colorSpecMethod(int meth) - { - switch (meth) - { - - case 2: return "Restricted ICC Profile"; - - case 1: return "Enumerated Color Space"; - - default: return "Undefined Color Spec Method"; - - } - } - static BoxType() - { - { - put(CSJ2K.j2k.fileformat.FileFormatBoxes.BITS_PER_COMPONENT_BOX, "BITS_PER_COMPONENT_BOX"); - put(CSJ2K.j2k.fileformat.FileFormatBoxes.CAPTURE_RESOLUTION_BOX, "CAPTURE_RESOLUTION_BOX"); - put(CSJ2K.j2k.fileformat.FileFormatBoxes.CHANNEL_DEFINITION_BOX, "CHANNEL_DEFINITION_BOX"); - put(CSJ2K.j2k.fileformat.FileFormatBoxes.COLOUR_SPECIFICATION_BOX, "COLOUR_SPECIFICATION_BOX"); - put(CSJ2K.j2k.fileformat.FileFormatBoxes.COMPONENT_MAPPING_BOX, "COMPONENT_MAPPING_BOX"); - put(CSJ2K.j2k.fileformat.FileFormatBoxes.CONTIGUOUS_CODESTREAM_BOX, "CONTIGUOUS_CODESTREAM_BOX"); - put(CSJ2K.j2k.fileformat.FileFormatBoxes.DEFAULT_DISPLAY_RESOLUTION_BOX, "DEFAULT_DISPLAY_RESOLUTION_BOX"); - put(CSJ2K.j2k.fileformat.FileFormatBoxes.FILE_TYPE_BOX, "FILE_TYPE_BOX"); - put(CSJ2K.j2k.fileformat.FileFormatBoxes.IMAGE_HEADER_BOX, "IMAGE_HEADER_BOX"); - put(CSJ2K.j2k.fileformat.FileFormatBoxes.INTELLECTUAL_PROPERTY_BOX, "INTELLECTUAL_PROPERTY_BOX"); - put(CSJ2K.j2k.fileformat.FileFormatBoxes.JP2_HEADER_BOX, "JP2_HEADER_BOX"); - put(CSJ2K.j2k.fileformat.FileFormatBoxes.JP2_SIGNATURE_BOX, "JP2_SIGNATURE_BOX"); - put(CSJ2K.j2k.fileformat.FileFormatBoxes.PALETTE_BOX, "PALETTE_BOX"); - put(CSJ2K.j2k.fileformat.FileFormatBoxes.RESOLUTION_BOX, "RESOLUTION_BOX"); - put(CSJ2K.j2k.fileformat.FileFormatBoxes.URL_BOX, "URL_BOX"); - put(CSJ2K.j2k.fileformat.FileFormatBoxes.UUID_BOX, "UUID_BOX"); - put(CSJ2K.j2k.fileformat.FileFormatBoxes.UUID_INFO_BOX, "UUID_INFO_BOX"); - put(CSJ2K.j2k.fileformat.FileFormatBoxes.UUID_LIST_BOX, "UUID_LIST_BOX"); - put(CSJ2K.j2k.fileformat.FileFormatBoxes.XML_BOX, "XML_BOX"); - } - } - } - - - /// Creates an int from a 4 character String - /// string representation of an integer - /// - /// the integer which is denoted by the input String. - /// - public static int getIntFromString(System.String fourChar) - { - byte[] bytes = SupportClass.ToByteArray(fourChar); - return getInt(bytes, 0); - } - /// Create an XYZNumber from byte [] input - /// array containing the XYZNumber representation - /// - /// start of the rep in the array - /// - /// the created XYZNumber - /// - public static XYZNumber getXYZNumber(byte[] data, int offset) - { - int x, y, z; + using System; + using System.Collections.Generic; + using System.IO; + using System.Text; + + using ParameterList = CSJ2K.j2k.util.ParameterList; + using ColorSpace = CSJ2K.Color.ColorSpace; + using ICCProfileHeader = CSJ2K.Icc.Types.ICCProfileHeader; + using ICCTag = CSJ2K.Icc.Tags.ICCTag; + using ICCTagTable = CSJ2K.Icc.Tags.ICCTagTable; + using ICCCurveType = CSJ2K.Icc.Tags.ICCCurveType; + using ICCXYZType = CSJ2K.Icc.Tags.ICCXYZType; + using XYZNumber = CSJ2K.Icc.Types.XYZNumber; + using ICCProfileVersion = CSJ2K.Icc.Types.ICCProfileVersion; + using ICCDateTime = CSJ2K.Icc.Types.ICCDateTime; + using FacilityManager = CSJ2K.j2k.util.FacilityManager; + + + /// This class models the ICCProfile file. This file is a binary file which is divided + /// into two parts, an ICCProfileHeader followed by an ICCTagTable. The header is a + /// straightforward list of descriptive parameters such as profile size, version, date and various + /// more esoteric parameters. The tag table is a structured list of more complexly aggragated data + /// describing things such as ICC curves, copyright information, descriptive text blocks, etc. + /// + /// Classes exist to model the header and tag table and their various constituent parts the developer + /// is refered to these for further information on the structure and contents of the header and tag table. + /// + /// + /// + /// + /// + /// + /// 1.0 + /// + /// Bruce A. Kern + /// + + public abstract class ICCProfile + { + private int ProfileSize + { + get + { + return header.dwProfileSize; + } + + set + { + header.dwProfileSize = value; + } + + } + + private int CMMTypeSignature + { + get + { + return header.dwCMMTypeSignature; + } + + set + { + header.dwCMMTypeSignature = value; + } + + } + + private int ProfileClass + { + get + { + return header.dwProfileClass; + } + + set + { + header.dwProfileClass = value; + } + + } + + private int ColorSpaceType + { + get + { + return header.dwColorSpaceType; + } + + set + { + header.dwColorSpaceType = value; + } + + } + + private int PCSType + { + get + { + return header.dwPCSType; + } + + set + { + header.dwPCSType = value; + } + + } + + private int ProfileSignature + { + get + { + return header.dwProfileSignature; + } + + set + { + header.dwProfileSignature = value; + } + + } + + private int PlatformSignature + { + get + { + return header.dwPlatformSignature; + } + + set + { + header.dwPlatformSignature = value; + } + + } + + private int CMMFlags + { + get + { + return header.dwCMMFlags; + } + + set + { + header.dwCMMFlags = value; + } + + } + + private int DeviceManufacturer + { + get + { + return header.dwDeviceManufacturer; + } + + set + { + header.dwDeviceManufacturer = value; + } + + } + + private int DeviceModel + { + get + { + return header.dwDeviceModel; + } + + set + { + header.dwDeviceModel = value; + } + + } + + private int DeviceAttributes1 + { + get + { + return header.dwDeviceAttributes1; + } + + set + { + header.dwDeviceAttributes1 = value; + } + + } + + private int DeviceAttributesReserved + { + get + { + return header.dwDeviceAttributesReserved; + } + + set + { + header.dwDeviceAttributesReserved = value; + } + + } + + private int RenderingIntent + { + get + { + return header.dwRenderingIntent; + } + + set + { + header.dwRenderingIntent = value; + } + + } + + private int CreatorSig + { + get + { + return header.dwCreatorSig; + } + + set + { + header.dwCreatorSig = value; + } + + } + + private ICCProfileVersion ProfileVersion + { + get + { + return header.profileVersion; + } + + set + { + header.profileVersion = value; + } + + } + + private XYZNumber PCSIlluminant + { + set + { + header.PCSIlluminant = value; + } + + } + + private ICCDateTime DateTime + { + set + { + header.dateTime = value; + } + + } + + /// Access the profile header + /// ICCProfileHeader + /// + public virtual ICCProfileHeader Header + { + get + { + return header; + } + + } + + /// Access the profile tag table + /// ICCTagTable + /// + public virtual ICCTagTable TagTable + { + get + { + return tags; + } + + } + + private static readonly string eol = System.Environment.NewLine; + + /// Gray index. + // Renamed for convenience: + public const int GRAY = 0; + + /// RGB index. + public const int RED = 0; + + /// RGB index. + public const int GREEN = 1; + + /// RGB index. + public const int BLUE = 2; + + /// Size of native type + public const int boolean_size = 1; + + /// Size of native type + public const int byte_size = 1; + + /// Size of native type + public const int char_size = 2; + + /// Size of native type + public const int short_size = 2; + + /// Size of native type + public const int int_size = 4; + + /// Size of native type + public const int float_size = 4; + + /// Size of native type + public const int long_size = 8; + + /// Size of native type + public const int double_size = 8; + + /* Bit twiddling constant for integral types. */ + + public const int BITS_PER_BYTE = 8; + + /* Bit twiddling constant for integral types. */ + + public const int BITS_PER_SHORT = 16; + + /* Bit twiddling constant for integral types. */ + + public const int BITS_PER_INT = 32; + + /* Bit twiddling constant for integral types. */ + + public const int BITS_PER_LONG = 64; + + /* Bit twiddling constant for integral types. */ + + public const int BYTES_PER_SHORT = 2; + + /* Bit twiddling constant for integral types. */ + + public const int BYTES_PER_INT = 4; + + /* Bit twiddling constant for integral types. */ + + public const int BYTES_PER_LONG = 8; + + /* JP2 Box structure analysis help */ + + private class BoxType : System.Collections.Generic.Dictionary + { + + private static Dictionary map = + new Dictionary(); + + public static void put(int type, string desc) + { + map[type] = desc; + } + + public static string get_Renamed(int type) + { + return map[type]; + } + + public static string colorSpecMethod(int meth) + { + switch (meth) + { + + case 2: + return "Restricted ICC Profile"; + + case 1: + return "Enumerated Color Space"; + + default: + return "Undefined Color Spec Method"; + + } + } + + static BoxType() + { + { + put(CSJ2K.j2k.fileformat.FileFormatBoxes.BITS_PER_COMPONENT_BOX, "BITS_PER_COMPONENT_BOX"); + put(CSJ2K.j2k.fileformat.FileFormatBoxes.CAPTURE_RESOLUTION_BOX, "CAPTURE_RESOLUTION_BOX"); + put(CSJ2K.j2k.fileformat.FileFormatBoxes.CHANNEL_DEFINITION_BOX, "CHANNEL_DEFINITION_BOX"); + put(CSJ2K.j2k.fileformat.FileFormatBoxes.COLOUR_SPECIFICATION_BOX, "COLOUR_SPECIFICATION_BOX"); + put(CSJ2K.j2k.fileformat.FileFormatBoxes.COMPONENT_MAPPING_BOX, "COMPONENT_MAPPING_BOX"); + put(CSJ2K.j2k.fileformat.FileFormatBoxes.CONTIGUOUS_CODESTREAM_BOX, "CONTIGUOUS_CODESTREAM_BOX"); + put( + CSJ2K.j2k.fileformat.FileFormatBoxes.DEFAULT_DISPLAY_RESOLUTION_BOX, + "DEFAULT_DISPLAY_RESOLUTION_BOX"); + put(CSJ2K.j2k.fileformat.FileFormatBoxes.FILE_TYPE_BOX, "FILE_TYPE_BOX"); + put(CSJ2K.j2k.fileformat.FileFormatBoxes.IMAGE_HEADER_BOX, "IMAGE_HEADER_BOX"); + put(CSJ2K.j2k.fileformat.FileFormatBoxes.INTELLECTUAL_PROPERTY_BOX, "INTELLECTUAL_PROPERTY_BOX"); + put(CSJ2K.j2k.fileformat.FileFormatBoxes.JP2_HEADER_BOX, "JP2_HEADER_BOX"); + put(CSJ2K.j2k.fileformat.FileFormatBoxes.JP2_SIGNATURE_BOX, "JP2_SIGNATURE_BOX"); + put(CSJ2K.j2k.fileformat.FileFormatBoxes.PALETTE_BOX, "PALETTE_BOX"); + put(CSJ2K.j2k.fileformat.FileFormatBoxes.RESOLUTION_BOX, "RESOLUTION_BOX"); + put(CSJ2K.j2k.fileformat.FileFormatBoxes.URL_BOX, "URL_BOX"); + put(CSJ2K.j2k.fileformat.FileFormatBoxes.UUID_BOX, "UUID_BOX"); + put(CSJ2K.j2k.fileformat.FileFormatBoxes.UUID_INFO_BOX, "UUID_INFO_BOX"); + put(CSJ2K.j2k.fileformat.FileFormatBoxes.UUID_LIST_BOX, "UUID_LIST_BOX"); + put(CSJ2K.j2k.fileformat.FileFormatBoxes.XML_BOX, "XML_BOX"); + } + } + } + + + /// Creates an int from a 4 character String + /// string representation of an integer + /// + /// the integer which is denoted by the input String. + /// + public static int getIntFromString(string fourChar) + { + byte[] bytes = SupportClass.ToByteArray(fourChar); + return getInt(bytes, 0); + } + + /// Create an XYZNumber from byte [] input + /// array containing the XYZNumber representation + /// + /// start of the rep in the array + /// + /// the created XYZNumber + /// + public static XYZNumber getXYZNumber(byte[] data, int offset) + { + int x, y, z; x = ICCProfile.getInt(data, offset); y = ICCProfile.getInt(data, offset + int_size); z = ICCProfile.getInt(data, offset + 2 * int_size); - return new XYZNumber(x, y, z); - } - - /// Create an ICCProfileVersion from byte [] input - /// array containing the ICCProfileVersion representation - /// - /// start of the rep in the array - /// - /// the created ICCProfileVersion - /// - public static ICCProfileVersion getICCProfileVersion(byte[] data, int offset) - { - byte major = data[offset]; - byte minor = data[offset + byte_size]; - byte resv1 = data[offset + 2 * byte_size]; - byte resv2 = data[offset + 3 * byte_size]; - return new ICCProfileVersion(major, minor, resv1, resv2); - } - - /// Create an ICCDateTime from byte [] input - /// array containing the ICCProfileVersion representation - /// - /// start of the rep in the array - /// - /// the created ICCProfileVersion - /// - public static ICCDateTime getICCDateTime(byte[] data, int offset) - { + return new XYZNumber(x, y, z); + } + + /// Create an ICCProfileVersion from byte [] input + /// array containing the ICCProfileVersion representation + /// + /// start of the rep in the array + /// + /// the created ICCProfileVersion + /// + public static ICCProfileVersion getICCProfileVersion(byte[] data, int offset) + { + byte major = data[offset]; + byte minor = data[offset + byte_size]; + byte resv1 = data[offset + 2 * byte_size]; + byte resv2 = data[offset + 3 * byte_size]; + return new ICCProfileVersion(major, minor, resv1, resv2); + } + + /// Create an ICCDateTime from byte [] input + /// array containing the ICCProfileVersion representation + /// + /// start of the rep in the array + /// + /// the created ICCProfileVersion + /// + public static ICCDateTime getICCDateTime(byte[] data, int offset) + { short wYear = ICCProfile.getShort(data, offset); // Number of the actual year (i.e. 1994) short wMonth = ICCProfile.getShort(data, offset + ICCProfile.short_size); // Number of the month (1-12) short wDay = ICCProfile.getShort(data, offset + 2 * ICCProfile.short_size); // Number of the day short wHours = ICCProfile.getShort(data, offset + 3 * ICCProfile.short_size); // Number of hours (0-23) short wMinutes = ICCProfile.getShort(data, offset + 4 * ICCProfile.short_size); // Number of minutes (0-59) short wSeconds = ICCProfile.getShort(data, offset + 5 * ICCProfile.short_size); // Number of seconds (0-59) - return new ICCDateTime(wYear, wMonth, wDay, wHours, wMinutes, wSeconds); - } - - - /// Create a String from a byte []. Optionally swap adjacent byte - /// pairs. Intended to be used to create integer String representations - /// allowing for endian translations. - /// - /// data array - /// - /// start of data in array - /// - /// length of data in array - /// - /// swap adjacent bytes? - /// - /// String rep of data - /// - public static System.String getString(byte[] bfr, int offset, int length, bool swap) - { - - byte[] result = new byte[length]; - int incr = swap?- 1:1; - int start = swap?offset + length - 1:offset; - for (int i = 0, j = start; i < length; ++i) - { - result[i] = bfr[j]; - j += incr; - } - return new System.String(SupportClass.ToCharArray(result)); - } - - /// Create a short from a two byte [], with optional byte swapping. - /// data array - /// - /// start of data in array - /// - /// swap bytes? - /// - /// native type from representation. - /// - public static short getShort(byte[] bfr, int off, bool swap) - { - - int tmp0 = bfr[off] & 0xff; // Clear the sign extended bits in the int. - int tmp1 = bfr[off + 1] & 0xff; - - - return (short) (swap?(tmp1 << BITS_PER_BYTE | tmp0):(tmp0 << BITS_PER_BYTE | tmp1)); - } - - /// Create a short from a two byte []. - /// data array - /// - /// start of data in array - /// - /// native type from representation. - /// - public static short getShort(byte[] bfr, int off) - { - int tmp0 = bfr[off] & 0xff; // Clear the sign extended bits in the int. - int tmp1 = bfr[off + 1] & 0xff; - return (short) (tmp0 << BITS_PER_BYTE | tmp1); - } - - /// Separate bytes in an int into a byte array lsb to msb order. - /// integer to separate - /// - /// byte [] containing separated int. - /// - public static byte[] setInt(int d) - { - return setInt(d, new byte[BYTES_PER_INT]); - } - - /// Separate bytes in an int into a byte array lsb to msb order. - /// Return the result in the provided array - /// - /// integer to separate - /// - /// return output here. - /// - /// reference to output. - /// - public static byte[] setInt(int d, byte[] b) - { - if (b == null) - b = new byte[BYTES_PER_INT]; - for (int i = 0; i < BYTES_PER_INT; ++i) - { - b[i] = (byte) (d & 0x0ff); - d = d >> BITS_PER_BYTE; - } - return b; - } - - /// Separate bytes in a long into a byte array lsb to msb order. - /// long to separate - /// - /// byte [] containing separated int. - /// - public static byte[] setLong(long d) - { - return setLong(d, new byte[BYTES_PER_INT]); - } - - /// Separate bytes in a long into a byte array lsb to msb order. - /// Return the result in the provided array - /// - /// long to separate - /// - /// return output here. - /// - /// reference to output. - /// - public static byte[] setLong(long d, byte[] b) - { - if (b == null) - b = new byte[BYTES_PER_LONG]; - for (int i = 0; i < BYTES_PER_LONG; ++i) - { - b[i] = (byte) (d & 0x0ff); - d = d >> BITS_PER_BYTE; - } - return b; - } - - - /// Create an int from a byte [4], with optional byte swapping. - /// data array - /// - /// start of data in array - /// - /// swap bytes? - /// - /// native type from representation. - /// - public static int getInt(byte[] bfr, int off, bool swap) - { - - int tmp0 = getShort(bfr, off, swap) & 0xffff; // Clear the sign extended bits in the int. - int tmp1 = getShort(bfr, off + 2, swap) & 0xffff; - - return (int) (swap?(tmp1 << BITS_PER_SHORT | tmp0):(tmp0 << BITS_PER_SHORT | tmp1)); - } - - /// Create an int from a byte [4]. - /// data array - /// - /// start of data in array - /// - /// native type from representation. - /// - public static int getInt(byte[] bfr, int off) - { - - int tmp0 = getShort(bfr, off) & 0xffff; // Clear the sign extended bits in the int. - int tmp1 = getShort(bfr, off + 2) & 0xffff; - - return (int) (tmp0 << BITS_PER_SHORT | tmp1); - } - - /// Create an long from a byte [8]. - /// data array - /// - /// start of data in array - /// - /// native type from representation. - /// - public static long getLong(byte[] bfr, int off) - { - - long tmp0 = getInt(bfr, off) & unchecked((int) 0xffffffff); // Clear the sign extended bits in the int. - long tmp1 = getInt(bfr, off + 4) & unchecked((int) 0xffffffff); - - return (long) (tmp0 << BITS_PER_INT | tmp1); - } - - - /// signature - // Define the set of standard signature and type values - // Because of the endian issues and byte swapping, the profile codes must - // be stored in memory and be addressed by address. As such, only those - // codes required for Restricted ICC use are defined here - - //UPGRADE_NOTE: Final was removed from the declaration of 'kdwProfileSignature '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" - public static readonly int kdwProfileSignature; - /// signature - //UPGRADE_NOTE: Final was removed from the declaration of 'kdwProfileSigReverse '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" - public static readonly int kdwProfileSigReverse; - /// profile type - //UPGRADE_NOTE: Final was removed from the declaration of 'kdwInputProfile '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" - public static readonly int kdwInputProfile; - /// tag type - //UPGRADE_NOTE: Final was removed from the declaration of 'kdwDisplayProfile '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" - public static readonly int kdwDisplayProfile; - /// tag type - //UPGRADE_NOTE: Final was removed from the declaration of 'kdwRGBData '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" - public static readonly int kdwRGBData; - /// tag type - //UPGRADE_NOTE: Final was removed from the declaration of 'kdwGrayData '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" - public static readonly int kdwGrayData; - /// tag type - //UPGRADE_NOTE: Final was removed from the declaration of 'kdwXYZData '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" - public static readonly int kdwXYZData; - /// input type - public const int kMonochromeInput = 0; - /// input type - public const int kThreeCompInput = 1; - - /// tag signature - //UPGRADE_NOTE: Final was removed from the declaration of 'kdwGrayTRCTag '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" - public static readonly int kdwGrayTRCTag; - /// tag signature - //UPGRADE_NOTE: Final was removed from the declaration of 'kdwRedColorantTag '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" - public static readonly int kdwRedColorantTag; - /// tag signature - //UPGRADE_NOTE: Final was removed from the declaration of 'kdwGreenColorantTag '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" - public static readonly int kdwGreenColorantTag; - /// tag signature - //UPGRADE_NOTE: Final was removed from the declaration of 'kdwBlueColorantTag '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" - public static readonly int kdwBlueColorantTag; - /// tag signature - //UPGRADE_NOTE: Final was removed from the declaration of 'kdwRedTRCTag '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" - public static readonly int kdwRedTRCTag; - /// tag signature - //UPGRADE_NOTE: Final was removed from the declaration of 'kdwGreenTRCTag '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" - public static readonly int kdwGreenTRCTag; - /// tag signature - //UPGRADE_NOTE: Final was removed from the declaration of 'kdwBlueTRCTag '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" - public static readonly int kdwBlueTRCTag; - /// tag signature - //UPGRADE_NOTE: Final was removed from the declaration of 'kdwCopyrightTag '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" - public static readonly int kdwCopyrightTag; - /// tag signature - //UPGRADE_NOTE: Final was removed from the declaration of 'kdwMediaWhiteTag '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" - public static readonly int kdwMediaWhiteTag; - /// tag signature - //UPGRADE_NOTE: Final was removed from the declaration of 'kdwProfileDescTag '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" - public static readonly int kdwProfileDescTag; - - - private ICCProfileHeader header = null; - private ICCTagTable tags = null; - private byte[] profile = null; - - //private byte[] data = null; - private ParameterList pl = null; - - private ICCProfile() - { - throw new ICCProfileException("illegal to invoke empty constructor"); - } - - /// ParameterList constructor - /// provides colorspace information - /// - protected internal ICCProfile(ColorSpace csm) - { - this.pl = csm.pl; - profile = csm.ICCProfile; - initProfile(profile); - } - - /// Read the header and tags into memory and verify - /// that the correct type of profile is being used. for encoding. - /// - /// ICCProfile - /// - /// for bad signature and class and bad type - /// - private void initProfile(byte[] data) - { - header = new ICCProfileHeader(data); - tags = ICCTagTable.createInstance(data); - - - // Verify that the data pointed to by icc is indeed a valid profile - // and that it is possibly of one of the Restricted ICC types. The simplest way to check - // this is to verify that the profile signature is correct, that it is an input profile, - // and that the PCS used is XYX. - - // However, a common error in profiles will be to create Monitor profiles rather - // than input profiles. If this is the only error found, it's still useful to let this - // go through with an error written to stderr. - - if (ProfileClass == kdwDisplayProfile) - { - System.String message = "NOTE!! Technically, this profile is a Display profile, not an" + " Input Profile, and thus is not a valid Restricted ICC profile." + " However, it is quite possible that this profile is usable as" + " a Restricted ICC profile, so this code will ignore this state" + " and proceed with processing."; - - FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.WARNING, message); - } - - if ((ProfileSignature != kdwProfileSignature) || ((ProfileClass != kdwInputProfile) && (ProfileClass != kdwDisplayProfile)) || (PCSType != kdwXYZData)) - { - throw new ICCProfileInvalidException(); - } - } - - - /// Provide a suitable string representation for the class - public override System.String ToString() - { - System.Text.StringBuilder rep = new System.Text.StringBuilder("[ICCProfile:"); - System.Text.StringBuilder body = new System.Text.StringBuilder(); - body.Append(eol).Append(header); - body.Append(eol).Append(eol).Append(tags); - rep.Append(ColorSpace.indent(" ", body)); - return rep.Append("]").ToString(); - } - - - /// Create a two character hex representation of a byte - /// byte to represent - /// - /// representation - /// - public static System.String toHexString(byte i) - { - System.String rep = (i >= 0 && i < 16?"0":"") + System.Convert.ToString((int) i, 16); - if (rep.Length > 2) - rep = rep.Substring(rep.Length - 2); - return rep; - } - - /// Create a 4 character hex representation of a short - /// short to represent - /// - /// representation - /// - public static System.String toHexString(short i) - { - System.String rep; - - if (i >= 0 && i < 0x10) - rep = "000" + System.Convert.ToString((int) i, 16); - else if (i >= 0 && i < 0x100) - rep = "00" + System.Convert.ToString((int) i, 16); - else if (i >= 0 && i < 0x1000) - rep = "0" + System.Convert.ToString((int) i, 16); - else - rep = "" + System.Convert.ToString((int) i, 16); - - if (rep.Length > 4) - rep = rep.Substring(rep.Length - 4); - return rep; - } - - - /// Create a 8 character hex representation of a int - /// int to represent - /// - /// representation - /// - public static System.String toHexString(int i) - { - System.String rep; - - if (i >= 0 && i < 0x10) - rep = "0000000" + System.Convert.ToString((int) i, 16); - else if (i >= 0 && i < 0x100) - rep = "000000" + System.Convert.ToString((int) i, 16); - else if (i >= 0 && i < 0x1000) - rep = "00000" + System.Convert.ToString((int) i, 16); - else if (i >= 0 && i < 0x10000) - rep = "0000" + System.Convert.ToString((int) i, 16); - else if (i >= 0 && i < 0x100000) - rep = "000" + System.Convert.ToString((int) i, 16); - else if (i >= 0 && i < 0x1000000) - rep = "00" + System.Convert.ToString((int) i, 16); - else if (i >= 0 && i < 0x10000000) - rep = "0" + System.Convert.ToString((int) i, 16); - else - rep = "" + System.Convert.ToString((int) i, 16); - - if (rep.Length > 8) - rep = rep.Substring(rep.Length - 8); - return rep; - } - - public static System.String ToString(byte[] data) - { - - int i, row, col, rem, rows, cols; - - System.Text.StringBuilder rep = new System.Text.StringBuilder(); - System.Text.StringBuilder rep0 = null; - System.Text.StringBuilder rep1 = null; - System.Text.StringBuilder rep2 = null; - - cols = 16; - rows = data.Length / cols; - rem = data.Length % cols; - - byte[] lbytes = new byte[8]; - for (row = 0, i = 0; row < rows; ++row) - { - rep1 = new System.Text.StringBuilder(); - rep2 = new System.Text.StringBuilder(); - - for (i = 0; i < 8; ++i) - lbytes[i] = 0; - byte[] tbytes = System.Text.ASCIIEncoding.ASCII.GetBytes(System.Convert.ToString(row * 16, 16)); - for (int t = 0, l = lbytes.Length - tbytes.Length; t < tbytes.Length; ++l, ++t) - lbytes[l] = tbytes[t]; - - rep0 = new System.Text.StringBuilder(new System.String(SupportClass.ToCharArray(lbytes))); - - for (col = 0; col < cols; ++col) - { - byte b = data[i++]; - rep1.Append(toHexString(b)).Append(i % 2 == 0?" ":""); - if ((System.Char.IsLetter((char) b) || ((char) b).CompareTo('$') == 0 || ((char) b).CompareTo('_') == 0)) - rep2.Append((char) b); - else - rep2.Append("."); - } - rep.Append(rep0).Append(" : ").Append(rep1).Append(": ").Append(rep2).Append(eol); - } - - rep1 = new System.Text.StringBuilder(); - rep2 = new System.Text.StringBuilder(); - - for (i = 0; i < 8; ++i) - lbytes[i] = 0; - byte[] tbytes2 = System.Text.ASCIIEncoding.ASCII.GetBytes(System.Convert.ToString(row * 16, 16)); - for (int t = 0, l = lbytes.Length - tbytes2.Length; t < tbytes2.Length; ++l, ++t) - lbytes[l] = tbytes2[t]; - - rep0 = new System.Text.StringBuilder(System.Text.ASCIIEncoding.ASCII.GetString(lbytes)); - - for (col = 0; col < rem; ++col) - { - byte b = data[i++]; - rep1.Append(toHexString(b)).Append(i % 2 == 0?" ":""); - if ((System.Char.IsLetter((char) b) || ((char) b).CompareTo('$') == 0 || ((char) b).CompareTo('_') == 0)) - rep2.Append((char) b); - else - rep2.Append("."); - } - for (col = rem; col < 16; ++col) - rep1.Append(" ").Append(col % 2 == 0?" ":""); - - rep.Append(rep0).Append(" : ").Append(rep1).Append(": ").Append(rep2).Append(eol); - - return rep.ToString(); - } - - /// Parse this ICCProfile into a RestrictedICCProfile - /// which is appropriate to the data in this profile. - /// Either a MonochromeInputRestrictedProfile or - /// MatrixBasedRestrictedProfile is returned - /// - /// RestrictedICCProfile - /// - /// no curve data - /// - public virtual RestrictedICCProfile parse() - { - - // The next step is to determine which Restricted ICC type is used by this profile. - // Unfortunately, the only way to do this is to look through the tag table for - // the tags required by the two types. - - // First look for the gray TRC tag. If the profile is indeed an input profile, and this - // tag exists, then the profile is a Monochrome Input profile - - ICCCurveType grayTag = (ICCCurveType) tags[(System.Int32) kdwGrayTRCTag]; - if (grayTag != null) - { - return RestrictedICCProfile.createInstance(grayTag); - } - - // If it wasn't a Monochrome Input profile, look for the Red Colorant tag. If that - // tag is found and the profile is indeed an input profile, then this profile is - // a Three-Component Matrix-Based Input profile - - ICCCurveType rTRCTag = (ICCCurveType) tags[(System.Int32) kdwRedTRCTag]; - - - if (rTRCTag != null) - { - ICCCurveType gTRCTag = (ICCCurveType) tags[(System.Int32) kdwGreenTRCTag]; - ICCCurveType bTRCTag = (ICCCurveType) tags[(System.Int32) kdwBlueTRCTag]; - ICCXYZType rColorantTag = (ICCXYZType) tags[(System.Int32) kdwRedColorantTag]; - ICCXYZType gColorantTag = (ICCXYZType) tags[(System.Int32) kdwGreenColorantTag]; - ICCXYZType bColorantTag = (ICCXYZType) tags[(System.Int32) kdwBlueColorantTag]; - return RestrictedICCProfile.createInstance(rTRCTag, gTRCTag, bTRCTag, rColorantTag, gColorantTag, bColorantTag); - } - - throw new ICCProfileInvalidException("curve data not found in profile"); - } - - /// Output this ICCProfile to a RandomAccessFile - /// output file - /// - //UPGRADE_TODO: Class 'java.io.RandomAccessFile' was converted to 'System.IO.FileStream' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javaioRandomAccessFile'" - public virtual void write(System.IO.FileStream os) - { - Header.write(os); - TagTable.write(os); - } - - - /* end class ICCProfile */ + return new ICCDateTime(wYear, wMonth, wDay, wHours, wMinutes, wSeconds); + } + + + /// Create a String from a byte []. Optionally swap adjacent byte + /// pairs. Intended to be used to create integer String representations + /// allowing for endian translations. + /// + /// data array + /// + /// start of data in array + /// + /// length of data in array + /// + /// swap adjacent bytes? + /// + /// String rep of data + /// + public static string getString(byte[] bfr, int offset, int length, bool swap) + { + + byte[] result = new byte[length]; + int incr = swap ? -1 : 1; + int start = swap ? offset + length - 1 : offset; + for (int i = 0, j = start; i < length; ++i) + { + result[i] = bfr[j]; + j += incr; + } + return new string(SupportClass.ToCharArray(result)); + } + + /// Create a short from a two byte [], with optional byte swapping. + /// data array + /// + /// start of data in array + /// + /// swap bytes? + /// + /// native type from representation. + /// + public static short getShort(byte[] bfr, int off, bool swap) + { + + int tmp0 = bfr[off] & 0xff; // Clear the sign extended bits in the int. + int tmp1 = bfr[off + 1] & 0xff; + + + return (short)(swap ? (tmp1 << BITS_PER_BYTE | tmp0) : (tmp0 << BITS_PER_BYTE | tmp1)); + } + + /// Create a short from a two byte []. + /// data array + /// + /// start of data in array + /// + /// native type from representation. + /// + public static short getShort(byte[] bfr, int off) + { + int tmp0 = bfr[off] & 0xff; // Clear the sign extended bits in the int. + int tmp1 = bfr[off + 1] & 0xff; + return (short)(tmp0 << BITS_PER_BYTE | tmp1); + } + + /// Separate bytes in an int into a byte array lsb to msb order. + /// integer to separate + /// + /// byte [] containing separated int. + /// + public static byte[] setInt(int d) + { + return setInt(d, new byte[BYTES_PER_INT]); + } + + /// Separate bytes in an int into a byte array lsb to msb order. + /// Return the result in the provided array + /// + /// integer to separate + /// + /// return output here. + /// + /// reference to output. + /// + public static byte[] setInt(int d, byte[] b) + { + if (b == null) b = new byte[BYTES_PER_INT]; + for (int i = 0; i < BYTES_PER_INT; ++i) + { + b[i] = (byte)(d & 0x0ff); + d = d >> BITS_PER_BYTE; + } + return b; + } + + /// Separate bytes in a long into a byte array lsb to msb order. + /// long to separate + /// + /// byte [] containing separated int. + /// + public static byte[] setLong(long d) + { + return setLong(d, new byte[BYTES_PER_INT]); + } + + /// Separate bytes in a long into a byte array lsb to msb order. + /// Return the result in the provided array + /// + /// long to separate + /// + /// return output here. + /// + /// reference to output. + /// + public static byte[] setLong(long d, byte[] b) + { + if (b == null) b = new byte[BYTES_PER_LONG]; + for (int i = 0; i < BYTES_PER_LONG; ++i) + { + b[i] = (byte)(d & 0x0ff); + d = d >> BITS_PER_BYTE; + } + return b; + } + + + /// Create an int from a byte [4], with optional byte swapping. + /// data array + /// + /// start of data in array + /// + /// swap bytes? + /// + /// native type from representation. + /// + public static int getInt(byte[] bfr, int off, bool swap) + { + + int tmp0 = getShort(bfr, off, swap) & 0xffff; // Clear the sign extended bits in the int. + int tmp1 = getShort(bfr, off + 2, swap) & 0xffff; + + return swap ? (tmp1 << BITS_PER_SHORT | tmp0) : (tmp0 << BITS_PER_SHORT | tmp1); + } + + /// Create an int from a byte [4]. + /// data array + /// + /// start of data in array + /// + /// native type from representation. + /// + public static int getInt(byte[] bfr, int off) + { + + int tmp0 = getShort(bfr, off) & 0xffff; // Clear the sign extended bits in the int. + int tmp1 = getShort(bfr, off + 2) & 0xffff; + + return tmp0 << BITS_PER_SHORT | tmp1; + } + + /// Create an long from a byte [8]. + /// data array + /// + /// start of data in array + /// + /// native type from representation. + /// + public static long getLong(byte[] bfr, int off) + { + + long tmp0 = getInt(bfr, off) & unchecked((int)0xffffffff); // Clear the sign extended bits in the int. + long tmp1 = getInt(bfr, off + 4) & unchecked((int)0xffffffff); + + return tmp0 << BITS_PER_INT | tmp1; + } + + + /// signature + // Define the set of standard signature and type values + // Because of the endian issues and byte swapping, the profile codes must + // be stored in memory and be addressed by address. As such, only those + // codes required for Restricted ICC use are defined here + + public static readonly int kdwProfileSignature; + + /// signature + public static readonly int kdwProfileSigReverse; + + /// profile type + public static readonly int kdwInputProfile; + + /// tag type + public static readonly int kdwDisplayProfile; + + /// tag type + public static readonly int kdwRGBData; + + /// tag type + public static readonly int kdwGrayData; + + /// tag type + public static readonly int kdwXYZData; + + /// input type + public const int kMonochromeInput = 0; + + /// input type + public const int kThreeCompInput = 1; + + /// tag signature + public static readonly int kdwGrayTRCTag; + + /// tag signature + public static readonly int kdwRedColorantTag; + + /// tag signature + public static readonly int kdwGreenColorantTag; + + /// tag signature + public static readonly int kdwBlueColorantTag; + + /// tag signature + public static readonly int kdwRedTRCTag; + + /// tag signature + public static readonly int kdwGreenTRCTag; + + /// tag signature + public static readonly int kdwBlueTRCTag; + + /// tag signature + public static readonly int kdwCopyrightTag; + + /// tag signature + public static readonly int kdwMediaWhiteTag; + + /// tag signature + public static readonly int kdwProfileDescTag; + + + private ICCProfileHeader header = null; + + private ICCTagTable tags = null; + + private byte[] profile = null; + + //private byte[] data = null; + private ParameterList pl = null; + + private ICCProfile() + { + throw new ICCProfileException("illegal to invoke empty constructor"); + } + + /// ParameterList constructor + /// provides colorspace information + /// + protected internal ICCProfile(ColorSpace csm) + { + this.pl = csm.pl; + profile = csm.ICCProfile; + initProfile(profile); + } + + /// Read the header and tags into memory and verify + /// that the correct type of profile is being used. for encoding. + /// + /// ICCProfile + /// + /// for bad signature and class and bad type + /// + private void initProfile(byte[] data) + { + header = new ICCProfileHeader(data); + tags = ICCTagTable.createInstance(data); + + + // Verify that the data pointed to by icc is indeed a valid profile + // and that it is possibly of one of the Restricted ICC types. The simplest way to check + // this is to verify that the profile signature is correct, that it is an input profile, + // and that the PCS used is XYX. + + // However, a common error in profiles will be to create Monitor profiles rather + // than input profiles. If this is the only error found, it's still useful to let this + // go through with an error written to stderr. + + if (ProfileClass == kdwDisplayProfile) + { + string message = "NOTE!! Technically, this profile is a Display profile, not an" + + " Input Profile, and thus is not a valid Restricted ICC profile." + + " However, it is quite possible that this profile is usable as" + + " a Restricted ICC profile, so this code will ignore this state" + + " and proceed with processing."; + + FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.WARNING, message); + } + + if ((ProfileSignature != kdwProfileSignature) + || ((ProfileClass != kdwInputProfile) && (ProfileClass != kdwDisplayProfile)) || (PCSType != kdwXYZData)) + { + throw new ICCProfileInvalidException(); + } + } + + + /// Provide a suitable string representation for the class + public override string ToString() + { + StringBuilder rep = new StringBuilder("[ICCProfile:"); + StringBuilder body = new StringBuilder(); + body.Append(eol).Append(header); + body.Append(eol).Append(eol).Append(tags); + rep.Append(ColorSpace.indent(" ", body)); + return rep.Append("]").ToString(); + } + + + /// Create a two character hex representation of a byte + /// byte to represent + /// + /// representation + /// + public static string toHexString(byte i) + { + string rep = (i >= 0 && i < 16 ? "0" : "") + System.Convert.ToString((int)i, 16); + if (rep.Length > 2) rep = rep.Substring(rep.Length - 2); + return rep; + } + + /// Create a 4 character hex representation of a short + /// short to represent + /// + /// representation + /// + public static string toHexString(short i) + { + string rep; + + if (i >= 0 && i < 0x10) rep = "000" + System.Convert.ToString((int)i, 16); + else if (i >= 0 && i < 0x100) rep = "00" + System.Convert.ToString((int)i, 16); + else if (i >= 0 && i < 0x1000) rep = "0" + System.Convert.ToString((int)i, 16); + else rep = "" + System.Convert.ToString((int)i, 16); + + if (rep.Length > 4) rep = rep.Substring(rep.Length - 4); + return rep; + } + + + /// Create a 8 character hex representation of a int + /// int to represent + /// + /// representation + /// + public static string toHexString(int i) + { + string rep; + + if (i >= 0 && i < 0x10) rep = "0000000" + Convert.ToString((int)i, 16); + else if (i >= 0 && i < 0x100) rep = "000000" + Convert.ToString((int)i, 16); + else if (i >= 0 && i < 0x1000) rep = "00000" + Convert.ToString((int)i, 16); + else if (i >= 0 && i < 0x10000) rep = "0000" + Convert.ToString((int)i, 16); + else if (i >= 0 && i < 0x100000) rep = "000" + Convert.ToString((int)i, 16); + else if (i >= 0 && i < 0x1000000) rep = "00" + Convert.ToString((int)i, 16); + else if (i >= 0 && i < 0x10000000) rep = "0" + Convert.ToString((int)i, 16); + else rep = "" + Convert.ToString((int)i, 16); + + if (rep.Length > 8) rep = rep.Substring(rep.Length - 8); + return rep; + } + + public static string ToString(byte[] data) + { + + int i, row, col, rem, rows, cols; + + StringBuilder rep = new StringBuilder(); + StringBuilder rep0 = null; + StringBuilder rep1 = null; + StringBuilder rep2 = null; + + cols = 16; + rows = data.Length / cols; + rem = data.Length % cols; + + byte[] lbytes = new byte[8]; + for (row = 0, i = 0; row < rows; ++row) + { + rep1 = new StringBuilder(); + rep2 = new StringBuilder(); + + for (i = 0; i < 8; ++i) lbytes[i] = 0; + byte[] tbytes = Encoding.UTF8.GetBytes(Convert.ToString(row * 16, 16)); + for (int t = 0, l = lbytes.Length - tbytes.Length; t < tbytes.Length; ++l, ++t) lbytes[l] = tbytes[t]; + + rep0 = new StringBuilder(new string(SupportClass.ToCharArray(lbytes))); + + for (col = 0; col < cols; ++col) + { + byte b = data[i++]; + rep1.Append(toHexString(b)).Append(i % 2 == 0 ? " " : ""); + if ((char.IsLetter((char)b) || ((char)b).CompareTo('$') == 0 || ((char)b).CompareTo('_') == 0)) rep2.Append((char)b); + else rep2.Append("."); + } + rep.Append(rep0).Append(" : ").Append(rep1).Append(": ").Append(rep2).Append(eol); + } + + rep1 = new System.Text.StringBuilder(); + rep2 = new System.Text.StringBuilder(); + + for (i = 0; i < 8; ++i) lbytes[i] = 0; + byte[] tbytes2 = System.Text.Encoding.UTF8.GetBytes(System.Convert.ToString(row * 16, 16)); + for (int t = 0, l = lbytes.Length - tbytes2.Length; t < tbytes2.Length; ++l, ++t) lbytes[l] = tbytes2[t]; + + rep0 = new StringBuilder(System.Text.Encoding.UTF8.GetString(lbytes, 0, lbytes.Length)); + + for (col = 0; col < rem; ++col) + { + byte b = data[i++]; + rep1.Append(toHexString(b)).Append(i % 2 == 0 ? " " : ""); + if ((char.IsLetter((char)b) || ((char)b).CompareTo('$') == 0 || ((char)b).CompareTo('_') == 0)) rep2.Append((char)b); + else rep2.Append("."); + } + for (col = rem; col < 16; ++col) rep1.Append(" ").Append(col % 2 == 0 ? " " : ""); + + rep.Append(rep0).Append(" : ").Append(rep1).Append(": ").Append(rep2).Append(eol); + + return rep.ToString(); + } + + /// Parse this ICCProfile into a RestrictedICCProfile + /// which is appropriate to the data in this profile. + /// Either a MonochromeInputRestrictedProfile or + /// MatrixBasedRestrictedProfile is returned + /// + /// RestrictedICCProfile + /// + /// no curve data + /// + public virtual RestrictedICCProfile parse() + { + // The next step is to determine which Restricted ICC type is used by this profile. + // Unfortunately, the only way to do this is to look through the tag table for + // the tags required by the two types. + + // First look for the gray TRC tag. If the profile is indeed an input profile, and this + // tag exists, then the profile is a Monochrome Input profile + ICCTag grayTag; + if (tags.TryGetValue(kdwGrayTRCTag, out grayTag)) + { + return RestrictedICCProfile.createInstance((ICCCurveType)grayTag); + } + + // If it wasn't a Monochrome Input profile, look for the Red Colorant tag. If that + // tag is found and the profile is indeed an input profile, then this profile is + // a Three-Component Matrix-Based Input profile + ICCCurveType rTRCTag = (ICCCurveType)tags[(System.Int32)kdwRedTRCTag]; + + + if (rTRCTag != null) + { + ICCCurveType gTRCTag = (ICCCurveType)tags[kdwGreenTRCTag]; + ICCCurveType bTRCTag = (ICCCurveType)tags[kdwBlueTRCTag]; + ICCXYZType rColorantTag = (ICCXYZType)tags[kdwRedColorantTag]; + ICCXYZType gColorantTag = (ICCXYZType)tags[kdwGreenColorantTag]; + ICCXYZType bColorantTag = (ICCXYZType)tags[kdwBlueColorantTag]; + return RestrictedICCProfile.createInstance( + rTRCTag, + gTRCTag, + bTRCTag, + rColorantTag, + gColorantTag, + bColorantTag); + } + + throw new ICCProfileInvalidException("curve data not found in profile"); + } + + /// Output this ICCProfile to a RandomAccessFile + /// output file + /// + public virtual void write(Stream os) + { + Header.write(os); + TagTable.write(os); + } + + + /* end class ICCProfile */ + static ICCProfile() - { - kdwProfileSignature = GetTagInt("acsp"); - kdwProfileSigReverse = GetTagInt("psca"); - kdwInputProfile = GetTagInt("scnr"); - kdwDisplayProfile = GetTagInt("mntr"); - kdwRGBData = GetTagInt("RGB "); - kdwGrayData = GetTagInt("GRAY"); - kdwXYZData = GetTagInt("XYZ "); - - kdwGrayTRCTag = GetTagInt("kTRC"); + { + kdwProfileSignature = GetTagInt("acsp"); + kdwProfileSigReverse = GetTagInt("psca"); + kdwInputProfile = GetTagInt("scnr"); + kdwDisplayProfile = GetTagInt("mntr"); + kdwRGBData = GetTagInt("RGB "); + kdwGrayData = GetTagInt("GRAY"); + kdwXYZData = GetTagInt("XYZ "); + + kdwGrayTRCTag = GetTagInt("kTRC"); kdwRedColorantTag = GetTagInt("rXYZ"); kdwGreenColorantTag = GetTagInt("gXYZ"); kdwBlueColorantTag = GetTagInt("bXYZ"); @@ -962,12 +1000,12 @@ static ICCProfile() kdwMediaWhiteTag = GetTagInt("wtpt"); kdwProfileDescTag = GetTagInt("desc"); } - static int GetTagInt(string tag) + + private static int GetTagInt(string tag) { - byte[] tagBytes = ASCIIEncoding.ASCII.GetBytes(tag); + byte[] tagBytes = Encoding.UTF8.GetBytes(tag); Array.Reverse(tagBytes); return BitConverter.ToInt32(tagBytes, 0); } - - } -} \ No newline at end of file + } +} diff --git a/CSJ2K/Icc/ICCProfileException.cs b/CSJ2K/Icc/ICCProfileException.cs index 15c68ec6..5e4f67b9 100644 --- a/CSJ2K/Icc/ICCProfileException.cs +++ b/CSJ2K/Icc/ICCProfileException.cs @@ -20,7 +20,6 @@ namespace CSJ2K.Icc /// /// Bruce A. Kern /// - [Serializable] public class ICCProfileException:System.Exception { diff --git a/CSJ2K/Icc/ICCProfileInvalidException.cs b/CSJ2K/Icc/ICCProfileInvalidException.cs index 4b15a02a..6aa02812 100644 --- a/CSJ2K/Icc/ICCProfileInvalidException.cs +++ b/CSJ2K/Icc/ICCProfileInvalidException.cs @@ -21,7 +21,6 @@ namespace CSJ2K.Icc /// Bruce A. Kern /// - [Serializable] public class ICCProfileInvalidException:ICCProfileException { diff --git a/CSJ2K/Icc/ICCProfileNotFoundException.cs b/CSJ2K/Icc/ICCProfileNotFoundException.cs index 0b800b8c..a719fefd 100644 --- a/CSJ2K/Icc/ICCProfileNotFoundException.cs +++ b/CSJ2K/Icc/ICCProfileNotFoundException.cs @@ -21,7 +21,6 @@ namespace CSJ2K.Icc /// Bruce A. Kern /// - [Serializable] public class ICCProfileNotFoundException:ICCProfileException { diff --git a/CSJ2K/Icc/ICCProfiler.cs b/CSJ2K/Icc/ICCProfiler.cs index b1279ff2..fc1c69ef 100644 --- a/CSJ2K/Icc/ICCProfiler.cs +++ b/CSJ2K/Icc/ICCProfiler.cs @@ -373,7 +373,7 @@ public override DataBlk getCompData(DataBlk outblk, int c) FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.ERROR, "matrix transform problem:\n" + e.Message); if (pl.getParameter("debug").Equals("on")) { - SupportClass.WriteStackTrace(e, Console.Error); + SupportClass.WriteStackTrace(e); } else { @@ -387,7 +387,7 @@ public override DataBlk getCompData(DataBlk outblk, int c) FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.ERROR, "monochrome transform problem:\n" + e.Message); if (pl.getParameter("debug").Equals("on")) { - SupportClass.WriteStackTrace(e, Console.Error); + SupportClass.WriteStackTrace(e); } else { diff --git a/CSJ2K/Icc/Lut/MatrixBasedTransformException.cs b/CSJ2K/Icc/Lut/MatrixBasedTransformException.cs index 7e20ef0d..b20f716c 100644 --- a/CSJ2K/Icc/Lut/MatrixBasedTransformException.cs +++ b/CSJ2K/Icc/Lut/MatrixBasedTransformException.cs @@ -20,7 +20,6 @@ namespace CSJ2K.Icc.Lut /// Bruce A. Kern /// - [Serializable] public class MatrixBasedTransformException:System.Exception { diff --git a/CSJ2K/Icc/Lut/MonochromeTransformException.cs b/CSJ2K/Icc/Lut/MonochromeTransformException.cs index febc4b7a..ab32ddaf 100644 --- a/CSJ2K/Icc/Lut/MonochromeTransformException.cs +++ b/CSJ2K/Icc/Lut/MonochromeTransformException.cs @@ -20,7 +20,6 @@ namespace CSJ2K.Icc.Lut /// Bruce A. Kern /// - [Serializable] public class MonochromeTransformException:System.Exception { diff --git a/CSJ2K/Icc/Tags/ICCTag.cs b/CSJ2K/Icc/Tags/ICCTag.cs index 40d96f54..615bac3a 100644 --- a/CSJ2K/Icc/Tags/ICCTag.cs +++ b/CSJ2K/Icc/Tags/ICCTag.cs @@ -209,10 +209,14 @@ public static ICCTag createInstance(int signature, byte[] data, int offset, int return new ICCSignatureType(signature, data, offset, count); else if (type == kdwViewType) return new ICCViewType(signature, data, offset, count); - else if (type == kdwDataType) - return new ICCDataType(signature, data, offset, count); - else - throw new System.ArgumentException("bad tag type: " + System.Text.ASCIIEncoding.ASCII.GetString(BitConverter.GetBytes(type)) + "(" + type + ")"); + else if (type == kdwDataType) + return new ICCDataType(signature, data, offset, count); + else + { + var bytes = BitConverter.GetBytes(type); + throw new System.ArgumentException("bad tag type: " + System.Text.Encoding.UTF8.GetString(bytes, 0, bytes.Length) + + "(" + type + ")"); + } } @@ -269,7 +273,7 @@ static ICCTag() } static int GetTagInt(string tag) { - byte[] tagBytes=ASCIIEncoding.ASCII.GetBytes(tag); + byte[] tagBytes=Encoding.UTF8.GetBytes(tag); Array.Reverse(tagBytes); return BitConverter.ToInt32(tagBytes, 0); } diff --git a/CSJ2K/Icc/Tags/ICCTagTable.cs b/CSJ2K/Icc/Tags/ICCTagTable.cs index 77934631..7af2aedc 100644 --- a/CSJ2K/Icc/Tags/ICCTagTable.cs +++ b/CSJ2K/Icc/Tags/ICCTagTable.cs @@ -7,6 +7,7 @@ /// *************************************************************************** /// using System; +using System.IO; using ColorSpace = CSJ2K.Color.ColorSpace; using ICCProfile = CSJ2K.Icc.ICCProfile; using ICCProfileHeader = CSJ2K.Icc.Types.ICCProfileHeader; @@ -31,8 +32,7 @@ namespace CSJ2K.Icc.Tags /// /// Bruce A. Kern /// - [Serializable] - public class ICCTagTable:System.Collections.Hashtable + public class ICCTagTable:System.Collections.Generic.Dictionary { //UPGRADE_NOTE: Final was removed from the declaration of 'eol '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" private static readonly System.String eol = System.Environment.NewLine; @@ -44,7 +44,7 @@ public class ICCTagTable:System.Collections.Hashtable private static readonly int offTags; //UPGRADE_NOTE: Final was removed from the declaration of 'trios '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" - private System.Collections.ArrayList trios = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10)); + private System.Collections.Generic.List trios = new System.Collections.Generic.List(10); private int tagCount; @@ -127,17 +127,14 @@ protected internal ICCTagTable(byte[] data) } - System.Collections.IEnumerator Enum = trios.GetEnumerator(); + System.Collections.Generic.IEnumerator Enum = trios.GetEnumerator(); //UPGRADE_TODO: Method 'java.util.Enumeration.hasMoreElements' was converted to 'System.Collections.IEnumerator.MoveNext' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationhasMoreElements'" while (Enum.MoveNext()) { //UPGRADE_TODO: Method 'java.util.Enumeration.nextElement' was converted to 'System.Collections.IEnumerator.Current' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationnextElement'" Triplet trio = (Triplet) Enum.Current; ICCTag tag = ICCTag.createInstance(trio.signature, data, trio.offset, trio.count); - System.Object tempObject; - tempObject = this[(System.Int32) tag.signature]; this[(System.Int32) tag.signature] = tag; - System.Object generatedAux2 = tempObject; } } @@ -148,7 +145,7 @@ protected internal ICCTagTable(byte[] data) /// /// //UPGRADE_TODO: Class 'java.io.RandomAccessFile' was converted to 'System.IO.FileStream' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javaioRandomAccessFile'" - public virtual void write(System.IO.FileStream raf) + public virtual void write(System.IO.Stream raf) { int ntags = trios.Count; diff --git a/CSJ2K/Icc/Tags/ICCTextDescriptionType.cs b/CSJ2K/Icc/Tags/ICCTextDescriptionType.cs index 78543b12..c94de4fc 100644 --- a/CSJ2K/Icc/Tags/ICCTextDescriptionType.cs +++ b/CSJ2K/Icc/Tags/ICCTextDescriptionType.cs @@ -62,7 +62,7 @@ protected internal ICCTextDescriptionType(int signature, byte[] data, int offset /// Return the string rep of this tag. public override System.String ToString() { - return "[" + base.ToString() + " \"" + System.Text.ASCIIEncoding.ASCII.GetString(ascii) + "\"]"; + return "[" + base.ToString() + " \"" + System.Text.Encoding.UTF8.GetString(ascii, 0, ascii.Length) + "\"]"; } /* end class ICCTextDescriptionType */ diff --git a/CSJ2K/Icc/Tags/ICCTextType.cs b/CSJ2K/Icc/Tags/ICCTextType.cs index 4fcb7142..999b6d77 100644 --- a/CSJ2K/Icc/Tags/ICCTextType.cs +++ b/CSJ2K/Icc/Tags/ICCTextType.cs @@ -56,7 +56,7 @@ protected internal ICCTextType(int signature, byte[] data, int offset, int lengt /// Return the string rep of this tag. public override System.String ToString() { - return "[" + base.ToString() + " \"" + System.Text.ASCIIEncoding.ASCII.GetString(ascii, 0, ascii.Length) + "\"]"; + return "[" + base.ToString() + " \"" + System.Text.Encoding.UTF8.GetString(ascii, 0, ascii.Length) + "\"]"; } /* end class ICCTextType */ diff --git a/CSJ2K/Icc/Tags/ICCXYZType.cs b/CSJ2K/Icc/Tags/ICCXYZType.cs index 1491c3b9..c732ca83 100644 --- a/CSJ2K/Icc/Tags/ICCXYZType.cs +++ b/CSJ2K/Icc/Tags/ICCXYZType.cs @@ -75,7 +75,7 @@ public override System.String ToString() /// Write to a file. //UPGRADE_TODO: Class 'java.io.RandomAccessFile' was converted to 'System.IO.FileStream' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javaioRandomAccessFile'" - public virtual void write(System.IO.FileStream raf) + public virtual void write(System.IO.Stream raf) { byte[] xb = ICCProfile.setLong(x); byte[] yb = ICCProfile.setLong(y); diff --git a/CSJ2K/Icc/Types/ICCDateTime.cs b/CSJ2K/Icc/Types/ICCDateTime.cs index ae9884bd..ecb5ef18 100644 --- a/CSJ2K/Icc/Types/ICCDateTime.cs +++ b/CSJ2K/Icc/Types/ICCDateTime.cs @@ -51,7 +51,7 @@ public ICCDateTime(short year, short month, short day, short hour, short minute, /// Write an ICCDateTime to a file. //UPGRADE_TODO: Class 'java.io.RandomAccessFile' was converted to 'System.IO.FileStream' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javaioRandomAccessFile'" - public virtual void write(System.IO.FileStream raf) + public virtual void write(System.IO.Stream raf) { System.IO.BinaryWriter temp_BinaryWriter; temp_BinaryWriter = new System.IO.BinaryWriter(raf); diff --git a/CSJ2K/Icc/Types/ICCProfileHeader.cs b/CSJ2K/Icc/Types/ICCProfileHeader.cs index aaaaa4c0..34055639 100644 --- a/CSJ2K/Icc/Types/ICCProfileHeader.cs +++ b/CSJ2K/Icc/Types/ICCProfileHeader.cs @@ -40,10 +40,10 @@ public class ICCProfileHeader * those codes required for Restricted ICC use are defined here. */ /// Profile header signature - private static int kdwProfileSignature = ICCProfile.getInt(System.Text.ASCIIEncoding.ASCII.GetBytes("acsp"), 0); + private static int kdwProfileSignature = ICCProfile.getInt(System.Text.Encoding.UTF8.GetBytes("acsp"), 0); /// Profile header signature - public static int kdwProfileSigReverse = ICCProfile.getInt(System.Text.ASCIIEncoding.ASCII.GetBytes("psca"),0); + public static int kdwProfileSigReverse = ICCProfile.getInt(System.Text.Encoding.UTF8.GetBytes("psca"),0); private const System.String kdwInputProfile = "scnr"; private const System.String kdwDisplayProfile = "mntr"; @@ -177,7 +177,7 @@ public ICCProfileHeader(byte[] data) /// /// //UPGRADE_TODO: Class 'java.io.RandomAccessFile' was converted to 'System.IO.FileStream' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javaioRandomAccessFile'" - public virtual void write(System.IO.FileStream raf) + public virtual void write(System.IO.Stream raf) { raf.Seek(offProfileSize, System.IO.SeekOrigin.Begin); raf.WriteByte((System.Byte) dwProfileSize); diff --git a/CSJ2K/Icc/Types/ICCProfileVersion.cs b/CSJ2K/Icc/Types/ICCProfileVersion.cs index 5616e00f..c94290b7 100644 --- a/CSJ2K/Icc/Types/ICCProfileVersion.cs +++ b/CSJ2K/Icc/Types/ICCProfileVersion.cs @@ -48,7 +48,7 @@ public ICCProfileVersion(byte major, byte minor, byte res1, byte res2) /// Construct from file content. //UPGRADE_TODO: Class 'java.io.RandomAccessFile' was converted to 'System.IO.FileStream' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javaioRandomAccessFile'" - public virtual void write(System.IO.FileStream raf) + public virtual void write(System.IO.Stream raf) { raf.WriteByte(uMajor); raf.WriteByte(uMinor); raf.WriteByte(reserved1); raf.WriteByte(reserved2); } diff --git a/CSJ2K/Icc/Types/XYZNumber.cs b/CSJ2K/Icc/Types/XYZNumber.cs index ffcdbb71..6f505ab7 100644 --- a/CSJ2K/Icc/Types/XYZNumber.cs +++ b/CSJ2K/Icc/Types/XYZNumber.cs @@ -57,7 +57,7 @@ public static double XYZToDouble(int x) /// Write to a file //UPGRADE_TODO: Class 'java.io.RandomAccessFile' was converted to 'System.IO.FileStream' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javaioRandomAccessFile'" - public virtual void write(System.IO.FileStream raf) + public virtual void write(System.IO.Stream raf) { System.IO.BinaryWriter temp_BinaryWriter; temp_BinaryWriter = new System.IO.BinaryWriter(raf); diff --git a/CSJ2K/J2KEncoder.cs b/CSJ2K/J2KEncoder.cs deleted file mode 100644 index 6d86b9c3..00000000 --- a/CSJ2K/J2KEncoder.cs +++ /dev/null @@ -1,232 +0,0 @@ -#region Using Statements -using System; -using System.Collections.Generic; -using System.Drawing; -using System.IO; -using CSJ2K.j2k.quantization.quantizer; -using CSJ2K.j2k.image.forwcomptransf; -using CSJ2K.j2k.codestream.writer; -using CSJ2K.j2k.fileformat.writer; -using CSJ2K.j2k.wavelet.analysis; -using CSJ2K.j2k.entropy.encoder; -using CSJ2K.j2k.entropy; -using CSJ2K.j2k.quantization; -using CSJ2K.j2k.image.input; -using CSJ2K.j2k.roi.encoder; -using CSJ2K.j2k.roi; -using CSJ2K.j2k.codestream; -using CSJ2K.j2k.image; -using CSJ2K.j2k.util; -using CSJ2K.j2k.encoder; -using CSJ2K.j2k; -#endregion - -namespace CSJ2K -{ - public static class J2KEncoder - { - #region Default Encoding Parameters - - private readonly static string[][] pinfo = { - new string[] { "debug", null, - "Print debugging messages when an error is encountered.","off"}, - new string[] { "disable_jp2_extension", "[on|off]", - "JJ2000 automatically adds .jp2 extension when using 'file_format'"+ - "option. This option disables it when on.", "off"}, - new string[] { "file_format", "[on|off]", - "Puts the JPEG 2000 codestream in a JP2 file format wrapper.","off"}, - new string[] { "pph_tile", "[on|off]", - "Packs the packet headers in the tile headers.","off"}, - new string[] { "pph_main", "[on|off]", - "Packs the packet headers in the main header.","off"}, - new string[] { "pfile", "", - "Loads the arguments from the specified file. Arguments that are "+ - "specified on the command line override the ones from the file.\n"+ - "The arguments file is a simple text file with one argument per "+ - "line of the following form:\n" + - " =\n"+ - "If the argument is of boolean type (i.e. its presence turns a "+ - "feature on), then the 'on' value turns it on, while the 'off' "+ - "value turns it off. The argument name does not include the '-' "+ - "or '+' character. Long lines can be broken into several lines "+ - "by terminating them with '\'. Lines starting with '#' are "+ - "considered as comments. This option is not recursive: any 'pfile' "+ - "argument appearing in the file is ignored.",null}, - new string[] { "tile_parts", "", - "This option specifies the maximum number of packets to have in "+ - "one tile-part. 0 means include all packets in first tile-part "+ - "of each tile","0"}, - new string[] { "tiles", " ", - "This option specifies the maximum tile dimensions to use. "+ - "If both dimensions are 0 then no tiling is used.","0 0"}, - new string[] { "ref", " ", - "Sets the origin of the image in the canvas system. It sets the "+ - "coordinate of the top-left corner of the image reference grid, "+ - "with respect to the canvas origin","0 0"}, - new string[] { "tref", " ", - "Sets the origin of the tile partitioning on the reference grid, "+ - "with respect to the canvas origin. The value of 'x' ('y') "+ - "specified can not be larger than the 'x' one specified in the ref "+ - "option.","0 0"}, - new string[] { "rate", "", - "This is the output bitrate of the codestream in bits per pixel."+ - " When equal to -1, no image information (beside quantization "+ - "effects) is discarded during compression.\n"+ - "Note: In the case where '-file_format' option is used, the "+ - "resulting file may have a larger bitrate.","-1"}, - new string[] { "lossless", "[on|off]", - "Specifies a lossless compression for the encoder. This options"+ - " is equivalent to use reversible quantization ('-Qtype "+ - "reversible')"+ - " and 5x3 wavelet filters pair ('-Ffilters w5x3'). Note that "+ - "this option cannot be used with '-rate'. When this option is "+ - "off, the quantization type and the filters pair is defined by "+ - "'-Qtype' and '-Ffilters' respectively.","off"}, - new string[] { "i", " [, [, ... ]]", - "Mandatory argument. This option specifies the name of the input "+ - "image files. If several image files are provided, they have to be"+ - " separated by commas in the command line. Supported formats are "+ - "PGM (raw), PPM (raw) and PGX, "+ - "which is a simple extension of the PGM file format for single "+ - "component data supporting arbitrary bitdepths. If the extension "+ - "is '.pgm', PGM-raw file format is assumed, if the extension is "+ - "'.ppm', PPM-raw file format is assumed, otherwise PGX file "+ - "format is assumed. PGM and PPM files are assumed to be 8 bits "+ - "deep. A multi-component image can be specified by either "+ - "specifying several PPM and/or PGX files, or by specifying one "+ - "PPM file.",null}, - new string[] { "o", "", - "Mandatory argument. This option specifies the name of the output "+ - "file to which the codestream will be written.",null}, - new string[] { "verbose", null, - "Prints information about the obtained bit stream.","on"}, - new string[] { "v", "[on|off]", - "Prints version and copyright information.","off"}, - new string[] { "u", "[on|off]", - "Prints usage information. "+ - "If specified all other arguments (except 'v') are ignored","off"}, - }; - - #endregion Default Encoding Parameters - - private readonly static ParameterList pl; - - static J2KEncoder() - { - pl = new ParameterList(); - string[][] parameters = GetAllParameters(); - for (int i = 0; i < parameters.Length; i++) - { - string[] param = parameters[i]; - pl.Set(param[0], param[3]); - } - - // Custom parameters - pl.Set("Aptype", "layer"); - pl.Set("Qguard_bits", "1"); - pl.Set("Alayers", "sl"); - //pl.Set("lossless", "on"); - } - - public static byte[] EncodeJPEG(Image jpgImage) - { - Tiler imgtiler; - ForwCompTransf fctransf; - ImgDataConverter converter; - EncoderSpecs encSpec; - ForwardWT dwt; - Quantizer quant; - ROIScaler rois; - EntropyCoder ecoder; - PostCompRateAllocator ralloc; - HeaderEncoder headenc; - CodestreamWriter bwriter; - - float rate = Single.MaxValue; - - ImgReaderGDI imgsrc = new ImgReaderGDI(jpgImage); - - imgtiler = new Tiler(imgsrc, 0, 0, 0, 0, jpgImage.Width, jpgImage.Height); - int ntiles = imgtiler.getNumTiles(); - - encSpec = new EncoderSpecs(ntiles, 3, imgsrc, pl); - - fctransf = new ForwCompTransf(imgtiler, encSpec); - converter = new ImgDataConverter(fctransf); - dwt = ForwardWT.createInstance(converter, pl, encSpec); - quant = Quantizer.createInstance(dwt, encSpec); - rois = ROIScaler.createInstance(quant, pl, encSpec); - ecoder = EntropyCoder.createInstance(rois, pl, encSpec.cblks, - encSpec.pss, encSpec.bms, - encSpec.mqrs, encSpec.rts, - encSpec.css, encSpec.sss, - encSpec.lcs, encSpec.tts); - - using (MemoryStream stream = new MemoryStream()) - { - bwriter = new FileCodestreamWriter(stream, Int32.MaxValue); - ralloc = PostCompRateAllocator.createInstance(ecoder, pl, rate, bwriter, encSpec); - - headenc = new HeaderEncoder(imgsrc, new bool[3], dwt, imgtiler, encSpec, rois, ralloc, pl); - ralloc.HeaderEncoder = headenc; - headenc.encodeMainHeader(); - ralloc.initialize(); - headenc.reset(); - headenc.encodeMainHeader(); - bwriter.commitBitstreamHeader(headenc); - - ralloc.runAndWrite(); - bwriter.close(); - - return stream.ToArray(); - } - } - - private static string[][] GetAllParameters() - { - List parameters = new List(); - - string[][] str = pinfo; - for (int i = 0; i < str.Length; i++) - parameters.Add(str[i]); - - str = ForwCompTransf.ParameterInfo; - for (int i = 0; i < str.Length; i++) - parameters.Add(str[i]); - - str = AnWTFilter.ParameterInfo; - for (int i = 0; i < str.Length; i++) - parameters.Add(str[i]); - - str = ForwardWT.ParameterInfo; - for (int i = 0; i < str.Length; i++) - parameters.Add(str[i]); - - str = Quantizer.ParameterInfo; - for (int i = 0; i < str.Length; i++) - parameters.Add(str[i]); - - str = ROIScaler.ParameterInfo; - for (int i = 0; i < str.Length; i++) - parameters.Add(str[i]); - - str = EntropyCoder.ParameterInfo; - for (int i = 0; i < str.Length; i++) - parameters.Add(str[i]); - - str = HeaderEncoder.ParameterInfo; - for (int i = 0; i < str.Length; i++) - parameters.Add(str[i]); - - str = PostCompRateAllocator.ParameterInfo; - for (int i = 0; i < str.Length; i++) - parameters.Add(str[i]); - - str = PktEncoder.ParameterInfo; - for (int i = 0; i < str.Length; i++) - parameters.Add(str[i]); - - return parameters.ToArray(); - } - } -} diff --git a/CSJ2K/J2kImage.cs b/CSJ2K/J2kImage.cs index 82e7fead..acb7eb91 100644 --- a/CSJ2K/J2kImage.cs +++ b/CSJ2K/J2kImage.cs @@ -1,55 +1,70 @@ -#region Using Statements +// Copyright (c) 2007-2016 CSJ2K contributors. +// Licensed under the BSD 3-Clause License. + using System; using System.Collections.Generic; using System.Drawing; using System.Drawing.Imaging; using System.IO; +using System.Linq; +using System.Runtime.CompilerServices; using System.Text; -using CSJ2K; + using CSJ2K.Color; using CSJ2K.Icc; -using CSJ2K.j2k; using CSJ2K.j2k.codestream; using CSJ2K.j2k.codestream.reader; +using CSJ2K.j2k.codestream.writer; using CSJ2K.j2k.decoder; +using CSJ2K.j2k.encoder; using CSJ2K.j2k.entropy.decoder; +using CSJ2K.j2k.entropy.encoder; using CSJ2K.j2k.fileformat.reader; +using CSJ2K.j2k.fileformat.writer; using CSJ2K.j2k.image; +using CSJ2K.j2k.image.forwcomptransf; +using CSJ2K.j2k.image.input; using CSJ2K.j2k.image.invcomptransf; using CSJ2K.j2k.io; using CSJ2K.j2k.quantization.dequantizer; +using CSJ2K.j2k.quantization.quantizer; using CSJ2K.j2k.roi; +using CSJ2K.j2k.roi.encoder; using CSJ2K.j2k.util; +using CSJ2K.j2k.wavelet.analysis; using CSJ2K.j2k.wavelet.synthesis; -#endregion +using CSJ2K.Util; + namespace CSJ2K { + public class J2kImage { + #region Static Decoder Methods - public static Image FromFile(string filename) + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static PortableImage FromFile(string filename, ParameterList parameters = null) { - Stream stream = new FileStream(filename, FileMode.Open, FileAccess.Read); - Image img = FromStream(stream); - stream.Close(); - return (img); + using (var stream = FileStreamFactory.New(filename, "r")) + { + return PortableImageFromStream(stream, parameters); + } } - public static Image FromBytes(byte[] j2kdata) + + public static PortableImage PortableImageFromBytes(byte[] j2kdata, ParameterList parameters = null) { - return FromStream(new MemoryStream(j2kdata)); + using MemoryStream stream = new(j2kdata); + return PortableImageFromStream(stream, parameters); } - public static Image FromStream(Stream stream) + public static PortableImage PortableImageFromStream(Stream stream, ParameterList parameters = null) { RandomAccessIO in_stream = new ISRandomAccessIO(stream); - // Initialize default parameters - ParameterList defpl = GetDefaultParameterList(decoder_pinfo); - - // Create parameter list using defaults - ParameterList pl = new ParameterList(defpl); + var pl = parameters ?? new ParameterList(GetDefaultDecoderParameterList(decoder_pinfo)); // **** File Format **** // If the codestream is wrapped in the jp2 fileformat, Read the @@ -75,7 +90,7 @@ public static Image FromStream(Stream stream) } catch (EndOfStreamException e) { - throw new ApplicationException("Codestream too short or bad header, unable to decode.", e); + throw new InvalidOperationException("Codestream too short or bad header, unable to decode.", e); } int nCompCod = hd.NumComps; @@ -93,17 +108,15 @@ public static Image FromStream(Stream stream) BitstreamReaderAgent breader; try { - breader = BitstreamReaderAgent. - createInstance(in_stream, hd, pl, decSpec, - false, hi); + breader = BitstreamReaderAgent.createInstance(in_stream, hd, pl, decSpec, false, hi); } catch (IOException e) { - throw new ApplicationException("Error while reading bit stream header or parsing packets.", e); + throw new InvalidOperationException("Error while reading bit stream header or parsing packets.", e); } catch (ArgumentException e) { - throw new ApplicationException("Cannot instantiate bit stream reader.", e); + throw new InvalidOperationException("Cannot instantiate bit stream reader.", e); } // **** Entropy decoder **** @@ -114,7 +127,7 @@ public static Image FromStream(Stream stream) } catch (ArgumentException e) { - throw new ApplicationException("Cannot instantiate entropy decoder.", e); + throw new InvalidOperationException("Cannot instantiate entropy decoder.", e); } // **** ROI de-scaler **** @@ -125,7 +138,7 @@ public static Image FromStream(Stream stream) } catch (ArgumentException e) { - throw new ApplicationException("Cannot instantiate roi de-scaler.", e); + throw new InvalidOperationException("Cannot instantiate roi de-scaler.", e); } // **** Dequantizer **** @@ -136,7 +149,7 @@ public static Image FromStream(Stream stream) } catch (ArgumentException e) { - throw new ApplicationException("Cannot instantiate dequantizer.", e); + throw new InvalidOperationException("Cannot instantiate dequantizer.", e); } // **** Inverse wavelet transform *** @@ -148,7 +161,7 @@ public static Image FromStream(Stream stream) } catch (ArgumentException e) { - throw new ApplicationException("Cannot instantiate inverse wavelet transform.", e); + throw new InvalidOperationException("Cannot instantiate inverse wavelet transform.", e); } int res = breader.ImgRes; @@ -174,15 +187,16 @@ public static Image FromStream(Stream stream) } catch (ArgumentException e) { - throw new ApplicationException("Could not instantiate ICC profiler.", e); + throw new InvalidOperationException("Could not instantiate ICC profiler.", e); } catch (ColorSpaceException e) { - throw new ApplicationException("Error processing ColorSpace information.", e); + throw new InvalidOperationException("Error processing ColorSpace information.", e); } } else - { // Skip colorspace mapping + { + // Skip colorspace mapping color = ictransf; } @@ -193,24 +207,271 @@ public static Image FromStream(Stream stream) { decodedImage = ictransf; } - int numComps = decodedImage.NumComps; - int bytesPerPixel = numComps; // Assuming 8-bit components + var numComps = decodedImage.NumComps; + var imgWidth = decodedImage.ImgWidth; // **** Copy to Bitmap **** - PixelFormat pixelFormat; - switch (numComps) + + var bitsUsed = new int[numComps]; + for (var j = 0; j < numComps; ++j) bitsUsed[j] = decodedImage.getNomRangeBits(numComps - 1 - j); + + int limitedNumComps = numComps > 4 ? 4 : numComps; + var dst = new PortableImage(imgWidth, decodedImage.ImgHeight, limitedNumComps, bitsUsed); + + Coord numTiles = decodedImage.getNumTiles(null); + + int tIdx = 0; + + for (int y = 0; y < numTiles.y; y++) + { + // Loop on horizontal tiles + for (int x = 0; x < numTiles.x; x++, tIdx++) + { + decodedImage.setTile(x, y); + + int height = decodedImage.getTileCompHeight(tIdx, 0); + int width = decodedImage.getTileCompWidth(tIdx, 0); + + int tOffx = decodedImage.getCompULX(0) + - (int)Math.Ceiling(decodedImage.ImgULX / (double)decodedImage.getCompSubsX(0)); + + int tOffy = decodedImage.getCompULY(0) + - (int)Math.Ceiling(decodedImage.ImgULY / (double)decodedImage.getCompSubsY(0)); + + DataBlkInt[] db = new DataBlkInt[numComps]; + int[] ls = new int[numComps]; + int[] mv = new int[numComps]; + int[] fb = new int[numComps]; + for (int i = 0; i < numComps; i++) + { + db[i] = new DataBlkInt(); + ls[i] = 1 << (decodedImage.getNomRangeBits(0) - 1); + mv[i] = (1 << decodedImage.getNomRangeBits(0)) - 1; + fb[i] = decodedImage.getFixedPoint(0); + } + for (int l = 0; l < height; l++) + { + for (int i = numComps - 1; i >= 0; i--) + { + db[i].ulx = 0; + db[i].uly = l; + db[i].w = width; + db[i].h = 1; + decodedImage.getInternCompData(db[i], i); + } + + int[] k = new int[numComps]; + int witdhMinus1 = width - 1; + for (int i = 0; i < numComps; i++) k[i] = db[i].offset + witdhMinus1; + + var rowvalues = new int[width * numComps]; + + for (int i = width - 1; i >= 0; i--) + { + int[] tmp = new int[numComps]; + for (int j = numComps - 1; j >= 0; j--) + { + tmp[j] = (db[j].data_array[k[j]--] >> fb[j]) + ls[j]; + tmp[j] = (tmp[j] < 0) ? 0 : ((tmp[j] > mv[j]) ? mv[j] : tmp[j]); + } + var offset = i * limitedNumComps; + switch (numComps) + { + case 1: + rowvalues[offset + 0] = tmp[0]; + break; + case 3: + rowvalues[offset + 0] = tmp[2]; + rowvalues[offset + 1] = tmp[1]; + rowvalues[offset + 2] = tmp[0]; + break; + case 4: + case 5: + rowvalues[offset + 0] = tmp[2]; + rowvalues[offset + 1] = tmp[1]; + rowvalues[offset + 2] = tmp[0]; + rowvalues[offset + 3] = tmp[3]; + break; + default: + throw new InvalidOperationException($"Invalid number of components: {numComps}"); + } + } + + dst.FillRow(tOffx, tOffy + l, imgWidth, rowvalues); + } + } + } + + return dst; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Image FromBytes(byte[] j2kdata, ParameterList parameters = null) + { + using MemoryStream stream = new(j2kdata); + return FromStream(stream, parameters); + } + + public static Image FromStream(Stream stream, ParameterList parameters = null) + { + RandomAccessIO in_stream = new ISRandomAccessIO(stream); + + var pl = parameters ?? new ParameterList(GetDefaultDecoderParameterList(decoder_pinfo)); + + // **** File Format **** + // If the codestream is wrapped in the jp2 fileformat, Read the + // file format wrapper + FileFormatReader ff = new FileFormatReader(in_stream); + ff.readFileFormat(); + if (ff.JP2FFUsed) + in_stream.seek(ff.FirstCodeStreamPos); + + // +----------------------------+ + // | Instantiate decoding chain | + // +----------------------------+ + + // **** Header decoder **** + // Instantiate header decoder and read main header + HeaderInfo hi = new HeaderInfo(); + HeaderDecoder hd; + try + { + hd = new HeaderDecoder(in_stream, pl, hi); + } + catch (EndOfStreamException e) { - case 1: - pixelFormat = PixelFormat.Format24bppRgb; break; - case 3: - pixelFormat = PixelFormat.Format24bppRgb; break; - case 4: - case 5: - pixelFormat = PixelFormat.Format32bppArgb; break; - default: - throw new ApplicationException("Unsupported PixelFormat. " + numComps + " components."); + throw new InvalidOperationException("Codestream too short or bad header, unable to decode.", e); } + int nCompCod = hd.NumComps; + int nTiles = hi.sizValue.NumTiles; + DecoderSpecs decSpec = hd.DecoderSpecs; + + // Get demixed bitdepths + int[] depth = new int[nCompCod]; + for (int i = 0; i < nCompCod; i++) + { + depth[i] = hd.getOriginalBitDepth(i); + } + + // **** Bit stream reader **** + BitstreamReaderAgent breader; + try + { + breader = BitstreamReaderAgent.createInstance(in_stream, hd, pl, decSpec, false, hi); + } + catch (IOException e) + { + throw new InvalidOperationException("Error while reading bit stream header or parsing packets.", e); + } + catch (ArgumentException e) + { + throw new InvalidOperationException("Cannot instantiate bit stream reader.", e); + } + + // **** Entropy decoder **** + EntropyDecoder entdec; + try + { + entdec = hd.createEntropyDecoder(breader, pl); + } + catch (ArgumentException e) + { + throw new InvalidOperationException("Cannot instantiate entropy decoder.", e); + } + + // **** ROI de-scaler **** + ROIDeScaler roids; + try + { + roids = hd.createROIDeScaler(entdec, pl, decSpec); + } + catch (ArgumentException e) + { + throw new InvalidOperationException("Cannot instantiate roi de-scaler.", e); + } + + // **** Dequantizer **** + Dequantizer deq; + try + { + deq = hd.createDequantizer(roids, depth, decSpec); + } + catch (ArgumentException e) + { + throw new InvalidOperationException("Cannot instantiate dequantizer.", e); + } + + // **** Inverse wavelet transform *** + InverseWT invWT; + try + { + // full page inverse wavelet transform + invWT = InverseWT.createInstance(deq, decSpec); + } + catch (ArgumentException e) + { + throw new InvalidOperationException("Cannot instantiate inverse wavelet transform.", e); + } + + int res = breader.ImgRes; + invWT.ImgResLevel = res; + + // **** Data converter **** (after inverse transform module) + ImgDataConverter converter = new ImgDataConverter(invWT, 0); + + // **** Inverse component transformation **** + InvCompTransf ictransf = new InvCompTransf(converter, decSpec, depth, pl); + + // **** Color space mapping **** + BlkImgDataSrc color; + if (ff.JP2FFUsed && pl.getParameter("nocolorspace").Equals("off")) + { + try + { + ColorSpace csMap = new ColorSpace(in_stream, hd, pl); + BlkImgDataSrc channels = hd.createChannelDefinitionMapper(ictransf, csMap); + BlkImgDataSrc resampled = hd.createResampler(channels, csMap); + BlkImgDataSrc palettized = hd.createPalettizedColorSpaceMapper(resampled, csMap); + color = hd.createColorSpaceMapper(palettized, csMap); + } + catch (ArgumentException e) + { + throw new InvalidOperationException("Could not instantiate ICC profiler.", e); + } + catch (ColorSpaceException e) + { + throw new InvalidOperationException("Error processing ColorSpace information.", e); + } + } + else + { + // Skip colorspace mapping + color = ictransf; + } + + // This is the last image in the decoding chain and should be + // assigned by the last transformation: + BlkImgDataSrc decodedImage = color; + if (color == null) + { + decodedImage = ictransf; + } + var numComps = decodedImage.NumComps; + var imgWidth = decodedImage.ImgWidth; + + int bytesPerPixel = numComps; // Assuming 8-bit components + + // **** Copy to Bitmap **** + var pixelFormat = numComps switch + { + 1 => PixelFormat.Format24bppRgb, + 3 => PixelFormat.Format24bppRgb, + 4 => PixelFormat.Format32bppArgb, + 5 => PixelFormat.Format32bppArgb, + _ => throw new ApplicationException("Unsupported PixelFormat. " + numComps + " components."), + }; + Bitmap dst = new Bitmap(decodedImage.ImgWidth, decodedImage.ImgHeight, pixelFormat); Coord numTiles = decodedImage.getNumTiles(null); @@ -227,13 +488,11 @@ public static Image FromStream(Stream stream) int height = decodedImage.getTileCompHeight(tIdx, 0); int width = decodedImage.getTileCompWidth(tIdx, 0); - int tOffx = decodedImage.getCompULX(0) - - (int)Math.Ceiling(decodedImage.ImgULX / - (double)decodedImage.getCompSubsX(0)); + int tOffx = decodedImage.getCompULX(0) + - (int)Math.Ceiling(decodedImage.ImgULX / (double)decodedImage.getCompSubsX(0)); - int tOffy = decodedImage.getCompULY(0) - - (int)Math.Ceiling(decodedImage.ImgULY / - (double)decodedImage.getCompSubsY(0)); + int tOffy = decodedImage.getCompULY(0) + - (int)Math.Ceiling(decodedImage.ImgULY / (double)decodedImage.getCompSubsY(0)); DataBlkInt[] db = new DataBlkInt[numComps]; int[] ls = new int[numComps]; @@ -256,8 +515,15 @@ public static Image FromStream(Stream stream) db[i].h = 1; decodedImage.getInternCompData(db[i], i); } + int[] k = new int[numComps]; - for (int i = numComps - 1; i >= 0; i--) k[i] = db[i].offset + width - 1; + int witdhMinus1 = width - 1; + for (int i = 0; i < numComps; i++) k[i] = db[i].offset + witdhMinus1; + + if(bytesPerPixel > 4) + bytesPerPixel = 4; + else if(bytesPerPixel < 3) + bytesPerPixel = 3; int outputBytesPerPixel = Math.Max(3, Math.Min(4, bytesPerPixel)); byte[] rowvalues = new byte[width * outputBytesPerPixel]; @@ -269,10 +535,6 @@ public static Image FromStream(Stream stream) { tmp[j] = (db[j].data_array[k[j]--] >> fb[j]) + ls[j]; tmp[j] = (tmp[j] < 0) ? 0 : ((tmp[j] > mv[j]) ? mv[j] : tmp[j]); - - if (decodedImage.getNomRangeBits(j) != 8) - tmp[j] = (int)Math.Round(((double)tmp[j] / Math.Pow(2D, (double)decodedImage.getNomRangeBits(j))) * 255D); - } int offset = i * outputBytesPerPixel; switch (numComps) @@ -294,11 +556,12 @@ public static Image FromStream(Stream stream) rowvalues[offset + 2] = (byte)tmp[0]; rowvalues[offset + 3] = (byte)tmp[3]; break; + default: + throw new InvalidOperationException($"Invalid number of components: {numComps}"); } } - BitmapData dstdata = dst.LockBits( - new System.Drawing.Rectangle(tOffx, tOffy + l, width, 1), + BitmapData dstdata = dst.LockBits(new Rectangle(tOffx, tOffy + l, width, 1), ImageLockMode.WriteOnly, pixelFormat); IntPtr ptr = dstdata.Scan0; @@ -307,15 +570,15 @@ public static Image FromStream(Stream stream) } } } + return dst; } - public static List GetLayerBoundaries(Stream stream) + public static List GetLayerBoundaries(Stream stream, ParameterList parameters = null) { RandomAccessIO in_stream = new ISRandomAccessIO(stream); - // Create parameter list using defaults - ParameterList pl = new ParameterList(GetDefaultParameterList(decoder_pinfo)); + var pl = parameters ?? new ParameterList(GetDefaultDecoderParameterList(decoder_pinfo)); // **** File Format **** // If the codestream is wrapped in the jp2 fileformat, Read the @@ -379,262 +642,968 @@ public static List GetLayerBoundaries(Stream stream) #region Static Encoder Methods - public static void ToFile(Bitmap bitmap, string filename) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static BlkImgDataSrc CreateEncodableSource(Stream stream) + { + return CreateEncodableSource(new[] { stream }); + } + + public static BlkImgDataSrc CreateEncodableSource(IEnumerable streams) { - using (FileStream stream = new FileStream(filename, FileMode.OpenOrCreate, FileAccess.ReadWrite)) + if (streams == null) { - ToStream(bitmap, stream); + throw new ArgumentNullException("streams"); } + + var counter = 0; + var ncomp = 0; + var ppminput = false; + var imageReaders = new List(); + + foreach (var stream in streams) + { + ++counter; + var imgType = GetImageType(stream); + + switch (imgType) + { + case "P5": + imageReaders.Add(new ImgReaderPGM(stream)); + ncomp += 1; + break; + case "P6": + imageReaders.Add(new ImgReaderPPM(stream)); + ncomp += 3; + ppminput = true; + break; + case "PG": + imageReaders.Add(new ImgReaderPGX(stream)); + ncomp += 1; + break; + default: + throw new ArgumentOutOfRangeException("streams", "Invalid image type"); + } + } + + if (ppminput && counter > 1) + { + error("With PPM input format only 1 input file can be specified", 2); + return null; + } + + BlkImgDataSrc imgsrc; + + // **** ImgDataJoiner (if needed) **** + if (ppminput || ncomp == 1) + { + // Just one input + imgsrc = imageReaders[0]; + } + else + { + // More than one reader => join all readers into 1 + var imgcmpidxs = new int[ncomp]; + imgsrc = new ImgDataJoiner(imageReaders, imgcmpidxs); + } + + return imgsrc; } - public static byte[] ToArray(Bitmap bitmap) + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static byte[] ToBytes(object imageObject, ParameterList parameters = null) { - using (MemoryStream stream = new MemoryStream()) + var imgsrc = ImageFactory.ToPortableImageSource(imageObject); + return ToBytes(imgsrc, parameters); + } + + public static byte[] ToBytes(BlkImgDataSrc imgsrc, ParameterList parameters = null) + { + // Create parameter list using defaults + ParameterList pl = parameters ?? new ParameterList(GetDefaultEncoderParameterList(encoder_pinfo));; + + bool useFileFormat = false; + bool pphTile = false; + bool pphMain = false; + bool tempSop = false; + bool tempEph = false; + + // **** Get general parameters **** + + if (pl.getParameter("file_format").Equals("on")) + { + useFileFormat = true; + if (pl.getParameter("rate") != null && pl.getFloatParameter("rate") != pl.getFloatParameter("rate")) + { + warning("Specified bit-rate applies only on the codestream but not on the whole file."); + } + } + + if (pl.getParameter("tiles") == null) + { + error("No tiles option specified", 2); + return null; + } + + if (pl.getParameter("pph_tile").Equals("on")) + { + pphTile = true; + + if (pl.getParameter("Psop").Equals("off")) + { + pl["Psop"] = "on"; + tempSop = true; + } + if (pl.getParameter("Peph").Equals("off")) + { + pl["Peph"] = "on"; + tempEph = true; + } + } + + if (pl.getParameter("pph_main").Equals("on")) + { + pphMain = true; + + if (pl.getParameter("Psop").Equals("off")) + { + pl["Psop"] = "on"; + tempSop = true; + } + if (pl.getParameter("Peph").Equals("off")) + { + pl["Peph"] = "on"; + tempEph = true; + } + } + + if (pphTile && pphMain) error("Can't have packed packet headers in both main and" + " tile headers", 2); + + if (pl.getBooleanParameter("lossless") && pl.getParameter("rate") != null + && pl.getFloatParameter("rate") != pl.getFloatParameter("rate")) throw new ArgumentException("Cannot use '-rate' and " + "'-lossless' option at " + " the same time."); + + if (pl.getParameter("rate") == null) + { + error("Target bitrate not specified", 2); + return null; + } + float rate; + try + { + rate = pl.getFloatParameter("rate"); + if (rate == -1) + { + rate = float.MaxValue; + } + } + catch (FormatException e) + { + error("Invalid value in 'rate' option: " + pl.getParameter("rate"), 2); + return null; + } + int pktspertp; + try + { + pktspertp = pl.getIntParameter("tile_parts"); + if (pktspertp != 0) + { + if (pl.getParameter("Psop").Equals("off")) + { + pl["Psop"] = "on"; + tempSop = true; + } + if (pl.getParameter("Peph").Equals("off")) + { + pl["Peph"] = "on"; + tempEph = true; + } + } + } + catch (FormatException e) + { + error("Invalid value in 'tile_parts' option: " + pl.getParameter("tile_parts"), 2); + return null; + } + + // **** ImgReader **** + var ncomp = imgsrc.NumComps; + var ppminput = imgsrc.NumComps > 1; + + // **** Tiler **** + // get nominal tile dimensions + SupportClass.StreamTokenizerSupport stok = + new SupportClass.StreamTokenizerSupport(new StringReader(pl.getParameter("tiles"))); + stok.EOLIsSignificant(false); + + stok.NextToken(); + if (stok.ttype != SupportClass.StreamTokenizerSupport.TT_NUMBER) + { + error("An error occurred while parsing the tiles option: " + pl.getParameter("tiles"), 2); + return null; + } + var tw = (int)stok.nval; + stok.NextToken(); + if (stok.ttype != SupportClass.StreamTokenizerSupport.TT_NUMBER) + { + error("An error occurred while parsing the tiles option: " + pl.getParameter("tiles"), 2); + return null; + } + var th = (int)stok.nval; + + // Get image reference point + var refs = pl.getParameter("ref").Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); + int refx; + int refy; + try + { + refx = Int32.Parse(refs[0]); + refy = Int32.Parse(refs[1]); + } + catch (IndexOutOfRangeException e) + { + throw new ArgumentException("Error while parsing 'ref' " + "option"); + } + catch (FormatException e) + { + throw new ArgumentException("Invalid number type in " + "'ref' option"); + } + if (refx < 0 || refy < 0) { - ToStream(bitmap, stream); - return stream.ToArray(); + throw new ArgumentException("Invalid value in 'ref' " + "option "); + } + + // Get tiling reference point + var trefs = pl.getParameter("tref").Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); + int trefx; + int trefy; + try + { + trefx = Int32.Parse(trefs[0]); + trefy = Int32.Parse(trefs[1]); + } + catch (IndexOutOfRangeException e) + { + throw new ArgumentException("Error while parsing 'tref' " + "option"); + } + catch (FormatException e) + { + throw new ArgumentException("Invalid number type in " + "'tref' option"); + } + if (trefx < 0 || trefy < 0 || trefx > refx || trefy > refy) + { + throw new ArgumentException("Invalid value in 'tref' " + "option "); + } + + // Instantiate tiler + Tiler imgtiler; + try + { + imgtiler = new Tiler(imgsrc, refx, refy, trefx, trefy, tw, th); + } + catch (ArgumentException e) + { + error("Could not tile image" + ((e.Message != null) ? (":\n" + e.Message) : ""), 2); + return null; + } + int ntiles = imgtiler.getNumTiles(); + + // **** Encoder specifications **** + var encSpec = new EncoderSpecs(ntiles, ncomp, imgsrc, pl); + + // **** Component transformation **** + if (ppminput && pl.getParameter("Mct") != null && pl.getParameter("Mct").Equals("off")) + { + FacilityManager.getMsgLogger() + .printmsg( + MsgLogger_Fields.WARNING, + "Input image is RGB and no color transform has " + + "been specified. Compression performance and " + + "image quality might be greatly degraded. Use " + + "the 'Mct' option to specify a color transform"); + } + ForwCompTransf fctransf; + try + { + fctransf = new ForwCompTransf(imgtiler, encSpec); + } + catch (ArgumentException e) + { + error( + "Could not instantiate forward component " + "transformation" + + ((e.Message != null) ? (":\n" + e.Message) : ""), + 2); + return null; + } + + // **** ImgDataConverter **** + var converter = new ImgDataConverter(fctransf); + + + // **** ForwardWT **** + ForwardWT dwt; + try + { + dwt = ForwardWT.createInstance(converter, pl, encSpec); + } + catch (ArgumentException e) + { + error("Could not instantiate wavelet transform" + ((e.Message != null) ? (":\n" + e.Message) : ""), 2); + return null; + } + + // **** Quantizer **** + Quantizer quant; + try + { + quant = Quantizer.createInstance(dwt, encSpec); + } + catch (ArgumentException e) + { + error("Could not instantiate quantizer" + ((e.Message != null) ? (":\n" + e.Message) : ""), 2); + return null; + } + + // **** ROIScaler **** + ROIScaler rois; + try + { + rois = ROIScaler.createInstance(quant, pl, encSpec); + } + catch (ArgumentException e) + { + error("Could not instantiate ROI scaler" + ((e.Message != null) ? (":\n" + e.Message) : ""), 2); + return null; + } + + // **** EntropyCoder **** + EntropyCoder ecoder; + try + { + ecoder = EntropyCoder.createInstance( + rois, + pl, + encSpec.cblks, + encSpec.pss, + encSpec.bms, + encSpec.mqrs, + encSpec.rts, + encSpec.css, + encSpec.sss, + encSpec.lcs, + encSpec.tts); + } + catch (ArgumentException e) + { + error("Could not instantiate entropy coder" + ((e.Message != null) ? (":\n" + e.Message) : ""), 2); + return null; + } + + // **** CodestreamWriter **** + using (var outStream = new MemoryStream()) + { + CodestreamWriter bwriter; + try + { + // Rely on rate allocator to limit amount of data + bwriter = new FileCodestreamWriter(outStream, Int32.MaxValue); + } + catch (IOException e) + { + error("Could not open output file" + ((e.Message != null) ? (":\n" + e.Message) : ""), 2); + return null; + } + + // **** Rate allocator **** + PostCompRateAllocator ralloc; + try + { + ralloc = PostCompRateAllocator.createInstance(ecoder, pl, rate, bwriter, encSpec); + } + catch (ArgumentException e) + { + error("Could not instantiate rate allocator" + ((e.Message != null) ? (":\n" + e.Message) : ""), 2); + return null; + } + + // **** HeaderEncoder **** + var imsigned = Enumerable.Repeat(false, ncomp).ToArray(); // TODO Consider supporting signed components. + var headenc = new HeaderEncoder(imgsrc, imsigned, dwt, imgtiler, encSpec, rois, ralloc, pl); + ralloc.HeaderEncoder = headenc; + + // **** Write header to be able to estimate header overhead **** + headenc.encodeMainHeader(); + + // **** Initialize rate allocator, with proper header + // overhead. This will also encode all the data **** + ralloc.initialize(); + + // **** Write header (final) **** + headenc.reset(); + headenc.encodeMainHeader(); + + // Insert header into the codestream + bwriter.commitBitstreamHeader(headenc); + + // **** Now do the rate-allocation and write result **** + ralloc.runAndWrite(); + + // **** Done **** + bwriter.close(); + + // **** Calculate file length **** + int fileLength = bwriter.Length; + + // **** Tile-parts and packed packet headers **** + if (pktspertp > 0 || pphTile || pphMain) + { + try + { + CodestreamManipulator cm = new CodestreamManipulator( + outStream, + ntiles, + pktspertp, + pphMain, + pphTile, + tempSop, + tempEph); + fileLength += cm.doCodestreamManipulation(); + //String res=""; + if (pktspertp > 0) + { + FacilityManager.getMsgLogger() + .println( + "Created tile-parts " + "containing at most " + pktspertp + " packets per tile.", + 4, + 6); + } + if (pphTile) + { + FacilityManager.getMsgLogger().println("Moved packet headers " + "to tile headers", 4, 6); + } + if (pphMain) + { + FacilityManager.getMsgLogger().println("Moved packet headers " + "to main header", 4, 6); + } + } + catch (IOException e) + { + error( + "Error while creating tileparts or packed packet" + " headers" + + ((e.Message != null) ? (":\n" + e.Message) : ""), + 2); + return null; + } + } + + // **** File Format **** + if (useFileFormat) + { + try + { + int nc = imgsrc.NumComps; + int[] bpc = new int[nc]; + for (int comp = 0; comp < nc; comp++) + { + bpc[comp] = imgsrc.getNomRangeBits(comp); + } + + outStream.Seek(0, SeekOrigin.Begin); + var ffw = new FileFormatWriter( + outStream, + imgsrc.ImgHeight, + imgsrc.ImgWidth, + nc, + bpc, + fileLength); + fileLength += ffw.writeFileFormat(); + } + catch (IOException e) + { + throw new InvalidOperationException("Error while writing JP2 file format: " + e.Message); + } + } + + // **** Close image readers *** + imgsrc.close(); + + return outStream.ToArray(); } } - public static void ToStream(Bitmap bitmap, Stream stream) + + #endregion + + #region Default Parameter Loaders + + public static ParameterList GetDefaultDecoderParameterList() { - throw new NotImplementedException(); + return GetDefaultDecoderParameterList(decoder_pinfo); } - #endregion + private static ParameterList CacheDefaultDecoder = null; + - #region Default Parameter Loader - public static ParameterList GetDefaultParameterList(string[][] pinfo) + public static ParameterList GetDefaultDecoderParameterList(string[][] pinfo) { + if (CacheDefaultDecoder != null) + return CacheDefaultDecoder; + ParameterList pl = new ParameterList(); string[][] str; str = BitstreamReaderAgent.ParameterInfo; - if (str != null) for (int i = str.Length - 1; i >= 0; i--) - pl.Set(str[i][0], str[i][3]); + if (str != null) for (int i = 0; i < str.Length; i++) pl[str[i][0]] = str[i][3]; str = EntropyDecoder.ParameterInfo; - if (str != null) for (int i = str.Length - 1; i >= 0; i--) - pl.Set(str[i][0], str[i][3]); + if (str != null) for (int i = 0; i < str.Length; i++) pl[str[i][0]] = str[i][3]; str = ROIDeScaler.ParameterInfo; - if (str != null) for (int i = str.Length - 1; i >= 0; i--) - pl.Set(str[i][0], str[i][3]); + if (str != null) for (int i = 0; i < str.Length; i++) pl[str[i][0]] = str[i][3]; str = Dequantizer.ParameterInfo; - if (str != null) for (int i = str.Length - 1; i >= 0; i--) - pl.Set(str[i][0], str[i][3]); + if (str != null) for (int i = 0; i < str.Length; i++) pl[str[i][0]] = str[i][3]; str = InvCompTransf.ParameterInfo; - if (str != null) for (int i = str.Length - 1; i >= 0; i--) - pl.Set(str[i][0], str[i][3]); + if (str != null) for (int i = 0; i < str.Length; i++) pl[str[i][0]] = str[i][3]; str = HeaderDecoder.ParameterInfo; - if (str != null) for (int i = str.Length - 1; i >= 0; i--) - pl.Set(str[i][0], str[i][3]); + if (str != null) for (int i = 0; i < str.Length; i++) pl[str[i][0]] = str[i][3]; str = ICCProfiler.ParameterInfo; - if (str != null) for (int i = str.Length - 1; i >= 0; i--) - pl.Set(str[i][0], str[i][3]); + if (str != null) for (int i = 0; i < str.Length; i++) pl[str[i][0]] = str[i][3]; - str = pinfo; - if (str != null) for (int i = str.Length - 1; i >= 0; i--) - pl.Set(str[i][0], str[i][3]); + str = pinfo ?? decoder_pinfo; + if (str != null) for (int i = 0; i < str.Length; i++) pl[str[i][0]] = str[i][3]; + CacheDefaultDecoder = pl; return pl; } + + public static ParameterList GetDefaultEncoderParameterList(string[][] pinfo) + { + ParameterList pl = new ParameterList(); + string[][] str; + + str = pinfo ?? encoder_pinfo; + if (str != null) for (int i = 0; i < str.Length; i++) pl[str[i][0]] = str[i][3]; + + str = ForwCompTransf.ParameterInfo; + if (str != null) for (int i = 0; i < str.Length; i++) pl[str[i][0]] = str[i][3]; + + str = AnWTFilter.ParameterInfo; + if (str != null) for (int i = 0; i < str.Length; i++) pl[str[i][0]] = str[i][3]; + + str = ForwardWT.ParameterInfo; + if (str != null) for (int i = 0; i < str.Length; i++) pl[str[i][0]] = str[i][3]; + + str = Quantizer.ParameterInfo; + if (str != null) for (int i = 0; i < str.Length; i++) pl[str[i][0]] = str[i][3]; + + str = ROIScaler.ParameterInfo; + if (str != null) for (int i = 0; i < str.Length; i++) pl[str[i][0]] = str[i][3]; + + str = EntropyCoder.ParameterInfo; + if (str != null) for (int i = 0; i < str.Length; i++) pl[str[i][0]] = str[i][3]; + + str = HeaderEncoder.ParameterInfo; + if (str != null) for (int i = 0; i < str.Length; i++) pl[str[i][0]] = str[i][3]; + + str = PostCompRateAllocator.ParameterInfo; + if (str != null) for (int i = 0; i < str.Length; i++) pl[str[i][0]] = str[i][3]; + + str = PktEncoder.ParameterInfo; + if (str != null) for (int i = 0; i < str.Length; i++) pl[str[i][0]] = str[i][3]; + + return pl; + } + #endregion #region Decoder Parameters - private static String[][] decoder_pinfo = { - new string[] { "u", "[on|off]", - "Prints usage information. "+ - "If specified all other arguments (except 'v') are ignored","off"}, - new string[] { "v", "[on|off]", - "Prints version and copyright information","off"}, - new string[] { "verbose", "[on|off]", - "Prints information about the decoded codestream","on"}, - new string[] { "pfile", "", - "Loads the arguments from the specified file. Arguments that are "+ - "specified on the command line override the ones from the file.\n"+ - "The arguments file is a simple text file with one argument per "+ - "line of the following form:\n" + - " =\n"+ - "If the argument is of boolean type (i.e. its presence turns a "+ - "feature on), then the 'on' value turns it on, while the 'off' "+ - "value turns it off. The argument name does not include the '-' "+ - "or '+' character. Long lines can be broken into several lines "+ - "by terminating them with '\\'. Lines starting with '#' are "+ - "considered as comments. This option is not recursive: any 'pfile' "+ - "argument appearing in the file is ignored.",null}, - new string[] { "res", "", - "The resolution level at which to reconstruct the image "+ - " (0 means the lowest available resolution whereas the maximum "+ - "resolution level corresponds to the original image resolution). "+ - "If the given index"+ - " is greater than the number of available resolution levels of the "+ - "compressed image, the image is reconstructed at its highest "+ - "resolution (among all tile-components). Note that this option"+ - " affects only the inverse wavelet transform and not the number "+ - " of bytes read by the codestream parser: this number of bytes "+ - "depends only on options '-nbytes' or '-rate'.", null}, - new string[] { "i", "", - "The file containing the JPEG 2000 compressed data. This can be "+ - "either a JPEG 2000 codestream or a JP2 file containing a "+ - "JPEG 2000 "+ - "codestream. In the latter case the first codestream in the file "+ - "will be decoded. If an URL is specified (e.g., http://...) "+ - "the data will be downloaded and cached in memory before decoding. "+ - "This is intended for easy use in applets, but it is not a very "+ - "efficient way of decoding network served data.", null}, - new string[] { "o", "", - "This is the name of the file to which the decompressed image "+ - "is written. If no output filename is given, the image is "+ - "displayed on the screen. "+ - "Output file format is PGX by default. If the extension"+ - " is '.pgm' then a PGM file is written as output, however this is "+ - "only permitted if the component bitdepth does not exceed 8. If "+ - "the extension is '.ppm' then a PPM file is written, however this "+ - "is only permitted if there are 3 components and none of them has "+ - "a bitdepth of more than 8. If there is more than 1 component, "+ - "suffices '-1', '-2', '-3', ... are added to the file name, just "+ - "before the extension, except for PPM files where all three "+ - "components are written to the same file.",null}, - new string[] { "rate","", - "Specifies the decoding rate in bits per pixel (bpp) where the "+ - "number of pixels is related to the image's original size (Note:"+ - " this number is not affected by the '-res' option). If it is equal"+ - "to -1, the whole codestream is decoded. "+ - "The codestream is either parsed (default) or truncated depending "+ - "the command line option '-parsing'. To specify the decoding "+ - "rate in bytes, use '-nbytes' options instead.","-1"}, - new string[] { "nbytes","", - "Specifies the decoding rate in bytes. "+ - "The codestream is either parsed (default) or truncated depending "+ - "the command line option '-parsing'. To specify the decoding "+ - "rate in bits per pixel, use '-rate' options instead.","-1"}, - new string[] { "parsing", null, - "Enable or not the parsing mode when decoding rate is specified "+ - "('-nbytes' or '-rate' options). If it is false, the codestream "+ - "is decoded as if it were truncated to the given rate. If it is "+ - "true, the decoder creates, truncates and decodes a virtual layer"+ - " progressive codestream with the same truncation points in each "+ - "code-block.","on"}, - new string[] { "ncb_quit","", - "Use the ncb and lbody quit conditions. If state information is "+ - "found for more code blocks than is indicated with this option, "+ - "the decoder "+ - "will decode using only information found before that point. "+ - "Using this otion implies that the 'rate' or 'nbyte' parameter "+ - "is used to indicate the lbody parameter which is the number of "+ - "packet body bytes the decoder will decode.","-1"}, - new string[] { "l_quit","", - "Specifies the maximum number of layers to decode for any code-"+ - "block","-1"}, - new string[] { "m_quit","", - "Specifies the maximum number of bit planes to decode for any code"+ - "-block","-1"}, - new string[] { "poc_quit",null, - "Specifies the whether the decoder should only decode code-blocks "+ - "included in the first progression order.","off"}, - new string[] { "one_tp",null, - "Specifies whether the decoder should only decode the first "+ - "tile part of each tile.","off"}, - new string[] { "comp_transf",null, - "Specifies whether the component transform indicated in the "+ - "codestream should be used.","on"}, - new string[] { "debug", null, - "Print debugging messages when an error is encountered.","off"}, - new string[] { "cdstr_info", null, - "Display information about the codestream. This information is: "+ - "\n- Marker segments value in main and tile-part headers,"+ - "\n- Tile-part length and position within the code-stream.", "off"}, - new string[] { "nocolorspace",null, - "Ignore any colorspace information in the image.","off"}, - new string[] { "colorspace_debug", null, - "Print debugging messages when an error is encountered in the"+ - " colorspace module.","off"} - }; + + private static String[][] decoder_pinfo = + { + new string[] + { + "u", "[on|off]", + "Prints usage information. " + + "If specified all other arguments (except 'v') are ignored", + "off" + }, + new string[] + { + "v", "[on|off]", "Prints version and copyright information", + "off" + }, + new string[] + { + "verbose", "[on|off]", + "Prints information about the decoded codestream", "on" + }, + new string[] + { + "pfile", "", + "Loads the arguments from the specified file. Arguments that are " + + "specified on the command line override the ones from the file.\n" + + "The arguments file is a simple text file with one argument per " + + "line of the following form:\n" + + " =\n" + + "If the argument is of boolean type (i.e. its presence turns a " + + "feature on), then the 'on' value turns it on, while the 'off' " + + "value turns it off. The argument name does not include the '-' " + + "or '+' character. Long lines can be broken into several lines " + + "by terminating them with '\\'. Lines starting with '#' are " + + "considered as comments. This option is not recursive: any 'pfile' " + + "argument appearing in the file is ignored.", + null + }, + new string[] + { + "res", "", + "The resolution level at which to reconstruct the image " + + " (0 means the lowest available resolution whereas the maximum " + + "resolution level corresponds to the original image resolution). " + + "If the given index" + + " is greater than the number of available resolution levels of the " + + "compressed image, the image is reconstructed at its highest " + + "resolution (among all tile-components). Note that this option" + + " affects only the inverse wavelet transform and not the number " + + " of bytes read by the codestream parser: this number of bytes " + + "depends only on options '-nbytes' or '-rate'.", + null + }, + new string[] + { + "i", "", + "The file containing the JPEG 2000 compressed data. This can be " + + "either a JPEG 2000 codestream or a JP2 file containing a " + + "JPEG 2000 " + + "codestream. In the latter case the first codestream in the file " + + "will be decoded. If an URL is specified (e.g., http://...) " + + "the data will be downloaded and cached in memory before decoding. " + + "This is intended for easy use in applets, but it is not a very " + + "efficient way of decoding network served data.", + null + }, + new string[] + { + "o", "", + "This is the name of the file to which the decompressed image " + + "is written. If no output filename is given, the image is " + + "displayed on the screen. " + + "Output file format is PGX by default. If the extension" + + " is '.pgm' then a PGM file is written as output, however this is " + + "only permitted if the component bitdepth does not exceed 8. If " + + "the extension is '.ppm' then a PPM file is written, however this " + + "is only permitted if there are 3 components and none of them has " + + "a bitdepth of more than 8. If there is more than 1 component, " + + "suffices '-1', '-2', '-3', ... are added to the file name, just " + + "before the extension, except for PPM files where all three " + + "components are written to the same file.", + null + }, + new string[] + { + "rate", "", + "Specifies the decoding rate in bits per pixel (bpp) where the " + + "number of pixels is related to the image's original size (Note:" + + " this number is not affected by the '-res' option). If it is equal" + + "to -1, the whole codestream is decoded. " + + "The codestream is either parsed (default) or truncated depending " + + "the command line option '-parsing'. To specify the decoding " + + "rate in bytes, use '-nbytes' options instead.", + "-1" + }, + new string[] + { + "nbytes", "", + "Specifies the decoding rate in bytes. " + + "The codestream is either parsed (default) or truncated depending " + + "the command line option '-parsing'. To specify the decoding " + + "rate in bits per pixel, use '-rate' options instead.", + "-1" + }, + new string[] + { + "parsing", null, + "Enable or not the parsing mode when decoding rate is specified " + + "('-nbytes' or '-rate' options). If it is false, the codestream " + + "is decoded as if it were truncated to the given rate. If it is " + + "true, the decoder creates, truncates and decodes a virtual layer" + + " progressive codestream with the same truncation points in each " + + "code-block.", + "on" + }, + new string[] + { + "ncb_quit", "", + "Use the ncb and lbody quit conditions. If state information is " + + "found for more code blocks than is indicated with this option, " + + "the decoder " + + "will decode using only information found before that point. " + + "Using this otion implies that the 'rate' or 'nbyte' parameter " + + "is used to indicate the lbody parameter which is the number of " + + "packet body bytes the decoder will decode.", + "-1" + }, + new string[] + { + "l_quit", "", + "Specifies the maximum number of layers to decode for any code-" + + "block", + "-1" + }, + new string[] + { + "m_quit", "", + "Specifies the maximum number of bit planes to decode for any code" + + "-block", + "-1" + }, + new string[] + { + "poc_quit", null, + "Specifies the whether the decoder should only decode code-blocks " + + "included in the first progression order.", + "off" + }, + new string[] + { + "one_tp", null, + "Specifies whether the decoder should only decode the first " + + "tile part of each tile.", + "off" + }, + new string[] + { + "comp_transf", null, + "Specifies whether the component transform indicated in the " + + "codestream should be used.", + "on" + }, + new string[] + { + "debug", null, + "Print debugging messages when an error is encountered.", + "off" + }, + new string[] + { + "cdstr_info", null, + "Display information about the codestream. This information is: " + + "\n- Marker segments value in main and tile-part headers," + + "\n- Tile-part length and position within the code-stream.", + "off" + }, + new string[] + { + "nocolorspace", null, + "Ignore any colorspace information in the image.", "off" + }, + new string[] + { + "colorspace_debug", null, + "Print debugging messages when an error is encountered in the" + + " colorspace module.", + "off" + } + }; + #endregion #region Encoder Parameters - private static String[][] encoder_pinfo = { - new string[] { "debug", null, - "Print debugging messages when an error is encountered.","off"}, - new string[] { "disable_jp2_extension", "[on|off]", - "JJ2000 automatically adds .jp2 extension when using 'file_format'"+ - "option. This option disables it when on.", "off"}, - new string[] { "file_format", "[on|off]", - "Puts the JPEG 2000 codestream in a JP2 file format wrapper.","off"}, - new string[] { "pph_tile", "[on|off]", - "Packs the packet headers in the tile headers.","off"}, - new string[] { "pph_main", "[on|off]", - "Packs the packet headers in the main header.","off"}, - new string[] { "pfile", "", - "Loads the arguments from the specified file. Arguments that are "+ - "specified on the command line override the ones from the file.\n"+ - "The arguments file is a simple text file with one argument per "+ - "line of the following form:\n" + - " =\n"+ - "If the argument is of boolean type (i.e. its presence turns a "+ - "feature on), then the 'on' value turns it on, while the 'off' "+ - "value turns it off. The argument name does not include the '-' "+ - "or '+' character. Long lines can be broken into several lines "+ - "by terminating them with '\'. Lines starting with '#' are "+ - "considered as comments. This option is not recursive: any 'pfile' "+ - "argument appearing in the file is ignored.",null}, - new string[] { "tile_parts", "", - "This option specifies the maximum number of packets to have in "+ - "one tile-part. 0 means include all packets in first tile-part "+ - "of each tile","0"}, - new string[] { "tiles", " ", - "This option specifies the maximum tile dimensions to use. "+ - "If both dimensions are 0 then no tiling is used.","0 0"}, - new string[] { "ref", " ", - "Sets the origin of the image in the canvas system. It sets the "+ - "coordinate of the top-left corner of the image reference grid, "+ - "with respect to the canvas origin","0 0"}, - new string[] { "tref", " ", - "Sets the origin of the tile partitioning on the reference grid, "+ - "with respect to the canvas origin. The value of 'x' ('y') "+ - "specified can not be larger than the 'x' one specified in the ref "+ - "option.","0 0"}, - new string[] { "rate", "", - "This is the output bitrate of the codestream in bits per pixel."+ - " When equal to -1, no image information (beside quantization "+ - "effects) is discarded during compression.\n"+ - "Note: In the case where '-file_format' option is used, the "+ - "resulting file may have a larger bitrate.","-1"}, - new string[] { "lossless", "[on|off]", - "Specifies a lossless compression for the encoder. This options"+ - " is equivalent to use reversible quantization ('-Qtype "+ - "reversible')"+ - " and 5x3 wavelet filters pair ('-Ffilters w5x3'). Note that "+ - "this option cannot be used with '-rate'. When this option is "+ - "off, the quantization type and the filters pair is defined by "+ - "'-Qtype' and '-Ffilters' respectively.","off"}, - new string[] { "i", " [, [, ... ]]", - "Mandatory argument. This option specifies the name of the input "+ - "image files. If several image files are provided, they have to be"+ - " separated by commas in the command line. Supported formats are "+ - "PGM (raw), PPM (raw) and PGX, "+ - "which is a simple extension of the PGM file format for single "+ - "component data supporting arbitrary bitdepths. If the extension "+ - "is '.pgm', PGM-raw file format is assumed, if the extension is "+ - "'.ppm', PPM-raw file format is assumed, otherwise PGX file "+ - "format is assumed. PGM and PPM files are assumed to be 8 bits "+ - "deep. A multi-component image can be specified by either "+ - "specifying several PPM and/or PGX files, or by specifying one "+ - "PPM file.",null}, - new string[] { "o", "", - "Mandatory argument. This option specifies the name of the output "+ - "file to which the codestream will be written.",null}, - new string[] { "verbose", null, - "Prints information about the obtained bit stream.","on"}, - new string[] { "v", "[on|off]", - "Prints version and copyright information.","off"}, - new string[] { "u", "[on|off]", - "Prints usage information. "+ - "If specified all other arguments (except 'v') are ignored","off"}, - }; + + private static String[][] encoder_pinfo = + { + new string[] + { + "debug", null, + "Print debugging messages when an error is encountered.", + "off" + }, + new string[] + { + "disable_jp2_extension", "[on|off]", + "JJ2000 automatically adds .jp2 extension when using 'file_format'" + + "option. This option disables it when on.", + "off" + }, + new string[] + { + "file_format", "[on|off]", + "Puts the JPEG 2000 codestream in a JP2 file format wrapper.", + "on" + }, + new string[] + { + "pph_tile", "[on|off]", + "Packs the packet headers in the tile headers.", "off" + }, + new string[] + { + "pph_main", "[on|off]", + "Packs the packet headers in the main header.", "off" + }, + new string[] + { + "pfile", "", + "Loads the arguments from the specified file. Arguments that are " + + "specified on the command line override the ones from the file.\n" + + "The arguments file is a simple text file with one argument per " + + "line of the following form:\n" + + " =\n" + + "If the argument is of boolean type (i.e. its presence turns a " + + "feature on), then the 'on' value turns it on, while the 'off' " + + "value turns it off. The argument name does not include the '-' " + + "or '+' character. Long lines can be broken into several lines " + + "by terminating them with '\'. Lines starting with '#' are " + + "considered as comments. This option is not recursive: any 'pfile' " + + "argument appearing in the file is ignored.", + null + }, + new string[] + { + "tile_parts", "", + "This option specifies the maximum number of packets to have in " + + "one tile-part. 0 means include all packets in first tile-part " + + "of each tile", + "0" + }, + new string[] + { + "tiles", " ", + "This option specifies the maximum tile dimensions to use. " + + "If both dimensions are 0 then no tiling is used.", + "0 0" + }, + new string[] + { + "ref", " ", + "Sets the origin of the image in the canvas system. It sets the " + + "coordinate of the top-left corner of the image reference grid, " + + "with respect to the canvas origin", + "0 0" + }, + new string[] + { + "tref", " ", + "Sets the origin of the tile partitioning on the reference grid, " + + "with respect to the canvas origin. The value of 'x' ('y') " + + "specified can not be larger than the 'x' one specified in the ref " + + "option.", + "0 0" + }, + new string[] + { + "rate", "", + "This is the output bitrate of the codestream in bits per pixel." + + " When equal to -1, no image information (beside quantization " + + "effects) is discarded during compression.\n" + + "Note: In the case where '-file_format' option is used, the " + + "resulting file may have a larger bitrate.", + "-1" + }, + new string[] + { + "lossless", "[on|off]", + "Specifies a lossless compression for the encoder. This options" + + " is equivalent to use reversible quantization ('-Qtype " + + "reversible')" + + " and 5x3 wavelet filters pair ('-Ffilters w5x3'). Note that " + + "this option cannot be used with '-rate'. When this option is " + + "off, the quantization type and the filters pair is defined by " + + "'-Qtype' and '-Ffilters' respectively.", + "off" + }, + new string[] + { + "i", " [, [, ... ]]", + "Mandatory argument. This option specifies the name of the input " + + "image files. If several image files are provided, they have to be" + + " separated by commas in the command line. Supported formats are " + + "PGM (raw), PPM (raw) and PGX, " + + "which is a simple extension of the PGM file format for single " + + "component data supporting arbitrary bitdepths. If the extension " + + "is '.pgm', PGM-raw file format is assumed, if the extension is " + + "'.ppm', PPM-raw file format is assumed, otherwise PGX file " + + "format is assumed. PGM and PPM files are assumed to be 8 bits " + + "deep. A multi-component image can be specified by either " + + "specifying several PPM and/or PGX files, or by specifying one " + + "PPM file.", + null + }, + new string[] + { + "o", "", + "Mandatory argument. This option specifies the name of the output " + + "file to which the codestream will be written.", + null + }, + new string[] + { + "verbose", null, + "Prints information about the obtained bit stream.", "on" + }, + new string[] + { + "v", "[on|off]", "Prints version and copyright information.", + "off" + }, + new string[] + { + "u", "[on|off]", + "Prints usage information. " + + "If specified all other arguments (except 'v') are ignored", + "off" + }, + }; + #endregion + + /** + * Prints the error message 'msg' to standard err, prepending "ERROR" to + * it, and sets the exitCode to 'code'. An exit code different than 0 + * indicates that there where problems. + * + * @param msg The error message + * + * @param code The exit code to set + * */ + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + + private static void error(String msg, int code) + { + //exitCode = code; + FacilityManager.getMsgLogger().printmsg(MsgLogger_Fields.ERROR, msg); + } + + /** + * Prints the warning message 'msg' to standard err, prepending "WARNING" + * to it. + * + * @param msg The error message + * */ + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static void warning(String msg) + { + FacilityManager.getMsgLogger().printmsg(MsgLogger_Fields.WARNING, msg); + } + + private static string GetImageType(Stream inStream) + { + try + { + var bytes = new byte[2]; + inStream.Position = 0; + inStream.Read(bytes, 0, 2); + inStream.Position = 0; + var imgType = Encoding.UTF8.GetString(bytes, 0, 2); + return imgType; + } + catch + { + return null; + } + } } } diff --git a/CSJ2K/Util/EndianBinaryReader.cs b/CSJ2K/Util/EndianBinaryReader.cs index 79912cad..e41dad80 100644 --- a/CSJ2K/Util/EndianBinaryReader.cs +++ b/CSJ2K/Util/EndianBinaryReader.cs @@ -55,7 +55,7 @@ public EndianBinaryReader(Stream input, Encoding encoding, bool bigEndian) _bigEndian = bigEndian; } - public EndianBinaryReader(Stream input, bool bigEndian) : base(input, bigEndian ? Encoding.BigEndianUnicode : Encoding.ASCII) + public EndianBinaryReader(Stream input, bool bigEndian) : base(input, bigEndian ? Encoding.BigEndianUnicode : Encoding.UTF8) { _bigEndian = bigEndian; } @@ -344,6 +344,7 @@ public EndianBinaryReader(Stream input, bool bigEndian) : base(input, bigEndian // // System.IO.EndOfStreamException: // The end of the stream is reached. +#if DOTNET public override decimal ReadDecimal() { if (_bigEndian) @@ -361,6 +362,7 @@ public override decimal ReadDecimal() } else return base.ReadDecimal(); } +#endif // // Summary: // Reads an 8-byte floating point value from the current stream and advances diff --git a/CSJ2K/Util/EndianBinaryWriter.cs b/CSJ2K/Util/EndianBinaryWriter.cs index 9390708f..c5b79c09 100644 --- a/CSJ2K/Util/EndianBinaryWriter.cs +++ b/CSJ2K/Util/EndianBinaryWriter.cs @@ -55,7 +55,7 @@ public EndianBinaryWriter(Stream input, Encoding encoding, bool bigEndian) _bigEndian = bigEndian; } - public EndianBinaryWriter(Stream input, bool bigEndian) : base(input, bigEndian ? Encoding.BigEndianUnicode : Encoding.ASCII) + public EndianBinaryWriter(Stream input, bool bigEndian) : base(input, bigEndian ? Encoding.BigEndianUnicode : Encoding.UTF8) { _bigEndian = bigEndian; } @@ -212,6 +212,7 @@ public EndianBinaryWriter(Stream input, bool bigEndian) : base(input, bigEndian // // System.IO.IOException: // An I/O error occurs. +#if DOTNET public override void Write(decimal value) { if (_bigEndian) @@ -234,6 +235,7 @@ public override void Write(decimal value) } else base.Write(value); } +#endif // // Summary: // Writes an eight-byte floating-point value to the current stream and advances diff --git a/CSJ2K/Util/SupportClass.cs b/CSJ2K/Util/SupportClass.cs index 611dc672..2c8bf6c9 100644 --- a/CSJ2K/Util/SupportClass.cs +++ b/CSJ2K/Util/SupportClass.cs @@ -10,8 +10,10 @@ // using System; +using CSJ2K.Util; +using CSJ2K.j2k.util; - /// +/// /// This interface should be implemented by any class whose instances are intended /// to be executed by a thread. /// @@ -54,7 +56,7 @@ public static byte[] ToByteArray(sbyte[] sbyteArray) /// The new array of bytes public static byte[] ToByteArray(System.String sourceString) { - return System.Text.UTF8Encoding.UTF8.GetBytes(sourceString); + return System.Text.Encoding.UTF8.GetBytes(sourceString); } /// @@ -75,15 +77,14 @@ public static byte[] ToByteArray(System.Object[] tempObjectArray) } /*******************************/ + /// /// Writes the exception stack trace to the received stream /// /// Exception to obtain information from - /// Output sream used to write to - public static void WriteStackTrace(System.Exception throwable, System.IO.TextWriter stream) + public static void WriteStackTrace(Exception throwable) { - stream.Write(throwable.StackTrace); - stream.Flush(); + FacilityManager.getMsgLogger().printmsg(MsgLogger_Fields.ERROR, throwable.StackTrace); } /*******************************/ @@ -112,7 +113,7 @@ public static sbyte[] ToSByteArray(byte[] byteArray) /// The new array of chars public static char[] ToCharArray(sbyte[] sByteArray) { - return System.Text.UTF8Encoding.UTF8.GetChars(ToByteArray(sByteArray)); + return System.Text.Encoding.UTF8.GetChars(ToByteArray(sByteArray)); } /// @@ -122,7 +123,7 @@ public static char[] ToCharArray(sbyte[] sByteArray) /// The new array of chars public static char[] ToCharArray(byte[] byteArray) { - return System.Text.UTF8Encoding.UTF8.GetChars(byteArray); + return System.Text.Encoding.UTF8.GetChars(byteArray); } /*******************************/ @@ -178,20 +179,9 @@ public class RandomAccessFileSupport /// A relative or absolute path for the file to open /// Mode to open the file in /// The new System.IO.FileStream - public static System.IO.FileStream CreateRandomAccessFile(System.String fileName, System.String mode) + public static System.IO.Stream CreateRandomAccessFile(System.String fileName, System.String mode) { - System.IO.FileStream newFile = null; - - if (mode.CompareTo("rw") == 0) - // newFile = new System.IO.FileStream(fileName, System.IO.FileMode.Create, System.IO.FileAccess.ReadWrite); - //else if (mode.CompareTo("rw+") == 0) - newFile = new System.IO.FileStream(fileName, System.IO.FileMode.OpenOrCreate, System.IO.FileAccess.ReadWrite); - else if (mode.CompareTo("r") == 0) - newFile = new System.IO.FileStream(fileName, System.IO.FileMode.Open, System.IO.FileAccess.Read); - else - throw new System.ArgumentException(); - - return newFile; + return FileStreamFactory.New(fileName, mode); } /// @@ -200,17 +190,17 @@ public static System.IO.FileStream CreateRandomAccessFile(System.String fileName /// File infomation for the file to open /// Mode to open the file in /// The new System.IO.FileStream - public static System.IO.FileStream CreateRandomAccessFile(System.IO.FileInfo fileName, System.String mode) + public static System.IO.Stream CreateRandomAccessFile(IFileInfo fileName, System.String mode) { return CreateRandomAccessFile(fileName.FullName, mode); - } + } /// /// Writes the data to the specified file stream /// /// Data to write /// File to write to - public static void WriteBytes(System.String data,System.IO.FileStream fileStream) + public static void WriteBytes(System.String data,System.IO.Stream fileStream) { int index = 0; int length = data.Length; @@ -224,7 +214,7 @@ public static void WriteBytes(System.String data,System.IO.FileStream fileStream /// /// String of information to write /// File to write to - public static void WriteChars(System.String data,System.IO.FileStream fileStream) + public static void WriteChars(System.String data,System.IO.Stream fileStream) { WriteBytes(data, fileStream); } @@ -234,7 +224,7 @@ public static void WriteChars(System.String data,System.IO.FileStream fileStream /// /// Data to write /// File to write to - public static void WriteRandomFile(sbyte[] sByteArray,System.IO.FileStream fileStream) + public static void WriteRandomFile(sbyte[] sByteArray,System.IO.Stream fileStream) { byte[] byteArray = ToByteArray(sByteArray); fileStream.Write(byteArray, 0, byteArray.Length); @@ -810,7 +800,7 @@ public StreamTokenizerSupport(System.IO.StringReader reader) { s += (char) i; } - reader.Close(); + reader.Dispose(); this.inStringReader = new BackStringReader(s); this.init(); } @@ -831,7 +821,7 @@ public StreamTokenizerSupport(System.IO.StreamReader reader) /// Stream to be parsed. public StreamTokenizerSupport(System.IO.Stream stream) { - this.inStream = new BackInputStream(new System.IO.BufferedStream(stream), 2); + this.inStream = new BackInputStream(stream, 2); this.init(); } @@ -1711,249 +1701,6 @@ private void Move(byte[] array, int index, int count) } } - - /*******************************/ - /// - /// Support class used to handle threads - /// - public class ThreadClass : IThreadRunnable - { - /// - /// The instance of System.Threading.Thread - /// - private System.Threading.Thread threadField; - - /// - /// Initializes a new instance of the ThreadClass class - /// - public ThreadClass() - { - threadField = new System.Threading.Thread(new System.Threading.ThreadStart(Run)); - } - - /// - /// Initializes a new instance of the Thread class. - /// - /// The name of the thread - public ThreadClass(System.String Name) - { - threadField = new System.Threading.Thread(new System.Threading.ThreadStart(Run)); - this.Name = Name; - } - - /// - /// Initializes a new instance of the Thread class. - /// - /// A ThreadStart delegate that references the methods to be invoked when this thread begins executing - public ThreadClass(System.Threading.ThreadStart Start) - { - threadField = new System.Threading.Thread(Start); - } - - /// - /// Initializes a new instance of the Thread class. - /// - /// A ThreadStart delegate that references the methods to be invoked when this thread begins executing - /// The name of the thread - public ThreadClass(System.Threading.ThreadStart Start, System.String Name) - { - threadField = new System.Threading.Thread(Start); - this.Name = Name; - } - - /// - /// This method has no functionality unless the method is overridden - /// - public virtual void Run() - { - } - - /// - /// Causes the operating system to change the state of the current thread instance to ThreadState.Running - /// - public virtual void Start() - { - threadField.Start(); - } - - /// - /// Interrupts a thread that is in the WaitSleepJoin thread state - /// - public virtual void Interrupt() - { - threadField.Interrupt(); - } - - /// - /// Gets the current thread instance - /// - public System.Threading.Thread Instance - { - get - { - return threadField; - } - set - { - threadField = value; - } - } - - /// - /// Gets or sets the name of the thread - /// - public System.String Name - { - get - { - return threadField.Name; - } - set - { - if (threadField.Name == null) - threadField.Name = value; - } - } - - /// - /// Gets or sets a value indicating the scheduling priority of a thread - /// - public System.Threading.ThreadPriority Priority - { - get - { - return threadField.Priority; - } - set - { - threadField.Priority = value; - } - } - - /// - /// Gets a value indicating the execution status of the current thread - /// - public bool IsAlive - { - get - { - return threadField.IsAlive; - } - } - - /// - /// Gets or sets a value indicating whether or not a thread is a background thread. - /// - public bool IsBackground - { - get - { - return threadField.IsBackground; - } - set - { - threadField.IsBackground = value; - } - } - - /// - /// Blocks the calling thread until a thread terminates - /// - public void Join() - { - threadField.Join(); - } - - /// - /// Blocks the calling thread until a thread terminates or the specified time elapses - /// - /// Time of wait in milliseconds - public void Join(long MiliSeconds) - { - lock(this) - { - threadField.Join(new System.TimeSpan(MiliSeconds * 10000)); - } - } - - /// - /// Blocks the calling thread until a thread terminates or the specified time elapses - /// - /// Time of wait in milliseconds - /// Time of wait in nanoseconds - public void Join(long MiliSeconds, int NanoSeconds) - { - lock(this) - { - threadField.Join(new System.TimeSpan(MiliSeconds * 10000 + NanoSeconds * 100)); - } - } - /* - /// - /// Resumes a thread that has been suspended - /// - public void Resume() - { - threadField.Resume(); - } - - /// - /// Raises a ThreadAbortException in the thread on which it is invoked, - /// to begin the process of terminating the thread. Calling this method - /// usually terminates the thread - /// - public void Abort() - { - threadField.Abort(); - } - - - /// - /// Raises a ThreadAbortException in the thread on which it is invoked, - /// to begin the process of terminating the thread while also providing - /// exception information about the thread termination. - /// Calling this method usually terminates the thread. - /// - /// An object that contains application-specific information, such as state, which can be used by the thread being aborted - public void Abort(System.Object stateInfo) - { - lock(this) - { - threadField.Abort(stateInfo); - } - } - - /// - /// Suspends the thread, if the thread is already suspended it has no effect - /// - public void Suspend() - { - threadField.Suspend(); - } - */ - - /// - /// Obtain a String that represents the current Object - /// - /// A String that represents the current Object - public override System.String ToString() - { - return "Thread[" + Name + "," + Priority.ToString() + "," + "" + "]"; - } - - /// - /// Gets the currently running thread - /// - /// The currently running thread - public static ThreadClass Current() - { - ThreadClass CurrentThread = new ThreadClass(); - CurrentThread.Instance = System.Threading.Thread.CurrentThread; - return CurrentThread; - } - } - - /*******************************/ /// /// SupportClass for the Stack class. @@ -1965,9 +1712,9 @@ public class StackSupport /// /// The stack where the element at the top will be returned and removed. /// The element at the top of the stack. - public static System.Object Pop(System.Collections.ArrayList stack) + public static T Pop(System.Collections.Generic.List stack) { - System.Object obj = stack[stack.Count - 1]; + T obj = stack[stack.Count - 1]; stack.RemoveAt(stack.Count - 1); return obj; diff --git a/CSJ2K/j2k/IntegerSpec.cs b/CSJ2K/j2k/IntegerSpec.cs index 540e0ad8..853e759e 100644 --- a/CSJ2K/j2k/IntegerSpec.cs +++ b/CSJ2K/j2k/IntegerSpec.cs @@ -167,7 +167,7 @@ public IntegerSpec(int nt, int nc, byte type, ParameterList pl, System.String op { setDefault((System.Object) System.Int32.Parse(param)); } - catch (System.FormatException) + catch (System.FormatException e) { throw new System.ArgumentException("Non recognized value" + " for option -" + optName + ": " + param); } @@ -218,7 +218,7 @@ public IntegerSpec(int nt, int nc, byte type, ParameterList pl, System.String op { value_Renamed = System.Int32.Parse(word); } - catch (System.FormatException) + catch (System.FormatException e) { throw new System.ArgumentException("Non recognized value" + " for option -" + optName + ": " + word); } @@ -290,7 +290,7 @@ public IntegerSpec(int nt, int nc, byte type, ParameterList pl, System.String op { setDefault((System.Object) System.Int32.Parse(param)); } - catch (System.FormatException) + catch (System.FormatException e) { throw new System.ArgumentException("Non recognized value" + " for option -" + optName + ": " + param); } diff --git a/CSJ2K/j2k/JJ2KExceptionHandler.cs b/CSJ2K/j2k/JJ2KExceptionHandler.cs index 9d12c4d4..4df82828 100644 --- a/CSJ2K/j2k/JJ2KExceptionHandler.cs +++ b/CSJ2K/j2k/JJ2KExceptionHandler.cs @@ -44,6 +44,8 @@ * */ using System; +using CSJ2K.j2k.util; + namespace CSJ2K.j2k { @@ -82,13 +84,13 @@ public static void handleException(System.Exception e) // including this method in the stack. //UPGRADE_ISSUE: Method 'java.lang.Throwable.fillInStackTrace' was not converted. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1000_javalangThrowablefillInStackTrace'" //e.fillInStackTrace(); - //SupportClass.WriteStackTrace(e, Console.Error); + SupportClass.WriteStackTrace(e); // Print an explicative message - System.Console.Error.WriteLine("The Thread is being terminated bacause an " + "Exception (shown above)\n" + "has been thrown and no special action was " + "defined for this Thread."); + FacilityManager.getMsgLogger().println("The Thread is being terminated bacause an " + "Exception (shown above)\n" + "has been thrown and no special action was " + "defined for this Thread.", 0, 0); // Stop the thread (do not use stop, since it's deprecated in // Java 1.2) - //UPGRADE_NOTE: Exception 'java.lang.ThreadDeath' was converted to 'System.ApplicationException' which has different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1100'" - throw e; + //UPGRADE_NOTE: Exception 'java.lang.ThreadDeath' was converted to 'System.InvalidOperationException' which has different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1100'" + throw new System.InvalidOperationException(); } } } \ No newline at end of file diff --git a/CSJ2K/j2k/ModuleSpec.cs b/CSJ2K/j2k/ModuleSpec.cs index 8e8de139..7b1d7066 100644 --- a/CSJ2K/j2k/ModuleSpec.cs +++ b/CSJ2K/j2k/ModuleSpec.cs @@ -41,6 +41,7 @@ * Copyright (c) 1999/2000 JJ2000 Partners. * */ using System; +using System.Collections.Generic; using CSJ2K.j2k.image; namespace CSJ2K.j2k { @@ -62,7 +63,7 @@ namespace CSJ2K.j2k ///

/// ///
- public class ModuleSpec : System.ICloneable + public class ModuleSpec { virtual public ModuleSpec Copy { @@ -129,7 +130,7 @@ virtual public ModuleSpec Copy /// 3 is accessible through the hash value "t16c3". Null if no /// tile-component specific value is defined ///
- protected internal System.Collections.Hashtable tileCompVal; + protected internal System.Collections.Generic.Dictionary tileCompVal; public virtual System.Object Clone() { @@ -139,9 +140,9 @@ public virtual System.Object Clone() ms = (ModuleSpec) base.MemberwiseClone(); } //UPGRADE_NOTE: Exception 'java.lang.CloneNotSupportedException' was converted to 'System.Exception' which has different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1100'" - catch (System.Exception) + catch (System.Exception e) { - throw new System.ApplicationException("Error when cloning ModuleSpec instance"); + throw new System.InvalidOperationException("Error when cloning ModuleSpec instance"); } // Create a copy of the specValType array ms.specValType = new byte[nTiles][]; @@ -168,16 +169,12 @@ public virtual System.Object Clone() // Create a copy of tileCompVal if (tileCompVal != null) { - ms.tileCompVal = System.Collections.Hashtable.Synchronized(new System.Collections.Hashtable()); - System.String tmpKey; - System.Object tmpVal; + ms.tileCompVal = new Dictionary(); //UPGRADE_TODO: Method 'java.util.Enumeration.hasMoreElements' was converted to 'System.Collections.IEnumerator.MoveNext' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationhasMoreElements'" - for (System.Collections.IEnumerator e = tileCompVal.Keys.GetEnumerator(); e.MoveNext(); ) + for (System.Collections.Generic.IEnumerator e = tileCompVal.Keys.GetEnumerator(); e.MoveNext(); ) { //UPGRADE_TODO: Method 'java.util.Enumeration.nextElement' was converted to 'System.Collections.IEnumerator.Current' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationnextElement'" - tmpKey = ((System.String) e.Current); - tmpVal = tileCompVal[tmpKey]; - ms.tileCompVal[tmpKey] = tmpVal; + ms.tileCompVal[e.Current] = tileCompVal[e.Current]; } } return ms; @@ -227,7 +224,7 @@ public virtual void rotate90(Coord anT) // Rotate tileCompVal if (tileCompVal != null && tileCompVal.Count > 0) { - System.Collections.Hashtable tmptcv = System.Collections.Hashtable.Synchronized(new System.Collections.Hashtable()); + System.Collections.Generic.Dictionary tmptcv = new Dictionary(); System.String tmpKey; System.Object tmpVal; int btIdx, atIdx; @@ -326,7 +323,7 @@ public virtual void setCompDef(int c, System.Object value_Renamed) { //UPGRADE_TODO: The equivalent in .NET for method 'java.lang.Object.toString' may return a different value. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1043'" System.String errMsg = "Option whose value is '" + value_Renamed + "' cannot be " + "specified for components as it is a 'tile only' specific " + "option"; - throw new System.ApplicationException(errMsg); + throw new System.InvalidOperationException(errMsg); } if (compDef == null) { @@ -360,7 +357,7 @@ public virtual System.Object getCompDef(int c) { if (specType == SPEC_TYPE_TILE) { - throw new System.ApplicationException("Illegal use of ModuleSpec class"); + throw new System.InvalidOperationException("Illegal use of ModuleSpec class"); } if (compDef == null || compDef[c] == null) { @@ -385,7 +382,7 @@ public virtual void setTileDef(int t, System.Object value_Renamed) { //UPGRADE_TODO: The equivalent in .NET for method 'java.lang.Object.toString' may return a different value. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1043'" System.String errMsg = "Option whose value is '" + value_Renamed + "' cannot be " + "specified for tiles as it is a 'component only' specific " + "option"; - throw new System.ApplicationException(errMsg); + throw new System.InvalidOperationException(errMsg); } if (tileDef == null) { @@ -418,7 +415,7 @@ public virtual System.Object getTileDef(int t) { if (specType == SPEC_TYPE_COMP) { - throw new System.ApplicationException("Illegal use of ModuleSpec class"); + throw new System.InvalidOperationException("Illegal use of ModuleSpec class"); } if (tileDef == null || tileDef[t] == null) { @@ -456,10 +453,10 @@ public virtual void setTileCompVal(int t, int c, System.Object value_Renamed) errMsg += "tiles as it is a 'component only' specific option"; break; } - throw new System.ApplicationException(errMsg); + throw new System.InvalidOperationException(errMsg); } if (tileCompVal == null) - tileCompVal = System.Collections.Hashtable.Synchronized(new System.Collections.Hashtable()); + tileCompVal = new Dictionary(); specValType[t][c] = SPEC_TILE_COMP; tileCompVal["t" + t + "c" + c] = value_Renamed; } @@ -487,7 +484,7 @@ public virtual System.Object getTileCompVal(int t, int c) { if (specType != SPEC_TYPE_TILE_COMP) { - throw new System.ApplicationException("Illegal use of ModuleSpec class"); + throw new System.InvalidOperationException("Illegal use of ModuleSpec class"); } return getSpec(t, c); } diff --git a/CSJ2K/j2k/NoNextElementException.cs b/CSJ2K/j2k/NoNextElementException.cs index c907317b..57f76707 100644 --- a/CSJ2K/j2k/NoNextElementException.cs +++ b/CSJ2K/j2k/NoNextElementException.cs @@ -52,8 +52,7 @@ namespace CSJ2K.j2k /// there is no next element to return. /// ///
- [Serializable] - public class NoNextElementException:System.SystemException + public class NoNextElementException:System.InvalidOperationException { /// Constructs a new NoNextElementException exception with no diff --git a/CSJ2K/j2k/codestream/CorruptedCodestreamException.cs b/CSJ2K/j2k/codestream/CorruptedCodestreamException.cs index b1bcbfaf..5f38c10f 100644 --- a/CSJ2K/j2k/codestream/CorruptedCodestreamException.cs +++ b/CSJ2K/j2k/codestream/CorruptedCodestreamException.cs @@ -51,7 +51,6 @@ namespace CSJ2K.j2k.codestream /// which is illegal. /// /// - [Serializable] public class CorruptedCodestreamException:System.IO.IOException { diff --git a/CSJ2K/j2k/codestream/HeaderInfo.cs b/CSJ2K/j2k/codestream/HeaderInfo.cs index eceb71a3..42f2df57 100644 --- a/CSJ2K/j2k/codestream/HeaderInfo.cs +++ b/CSJ2K/j2k/codestream/HeaderInfo.cs @@ -42,6 +42,7 @@ * Copyright (c) 1999/2000 JJ2000 Partners. * */ using System; +using System.Collections.Generic; using CSJ2K.j2k.wavelet; namespace CSJ2K.j2k.codestream { @@ -51,7 +52,7 @@ namespace CSJ2K.j2k.codestream /// in these headers. /// ///
- public class HeaderInfo : FilterTypes, System.ICloneable + public class HeaderInfo : FilterTypes { /// Returns a new instance of SIZ virtual public SIZ NewSIZ @@ -155,7 +156,7 @@ virtual public int NumCOM //UPGRADE_NOTE: Field 'EnclosingInstance' was added to class 'SIZ' to access its enclosing instance. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1019'" /// Internal class holding information found in the SIZ marker segment - public class SIZ : System.ICloneable + public class SIZ { public SIZ(HeaderInfo enclosingInstance) { @@ -242,9 +243,9 @@ virtual public SIZ Copy ms = (SIZ) this.Clone(); } //UPGRADE_NOTE: Exception 'java.lang.CloneNotSupportedException' was converted to 'System.Exception' which has different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1100'" - catch (System.Exception) + catch (System.Exception e) { - throw new System.ApplicationException("Cannot clone SIZ marker segment"); + throw new System.InvalidOperationException("Cannot clone SIZ marker segment"); } return ms; } @@ -421,7 +422,7 @@ public override System.String ToString() //UPGRADE_NOTE: Field 'EnclosingInstance' was added to class 'COD' to access its enclosing instance. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1019'" /// Internal class holding information found in the COD marker segments - public class COD : System.ICloneable + public class COD { public COD(HeaderInfo enclosingInstance) { @@ -442,9 +443,9 @@ virtual public COD Copy ms = (COD) this.Clone(); } //UPGRADE_NOTE: Exception 'java.lang.CloneNotSupportedException' was converted to 'System.Exception' which has different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1100'" - catch (System.Exception) + catch (System.Exception e) { - throw new System.ApplicationException("Cannot clone SIZ marker segment"); + throw new System.InvalidOperationException("Cannot clone SIZ marker segment"); } return ms; } @@ -1086,7 +1087,7 @@ public override System.String ToString() else if (rcom == 1) { str += (" Registration : General use (IS 8859-15:1999 " + "(Latin) values)\n"); - str += (" Text : " + System.Text.ASCIIEncoding.ASCII.GetString(ccom) + "\n"); + str += (" Text : " + System.Text.Encoding.UTF8.GetString(ccom, 0, ccom.Length) + "\n"); } else { @@ -1103,40 +1104,40 @@ public override System.String ToString() /// Reference to the SOT marker segments found in tile-part headers. The /// kwy is given by "t"+tileIdx"_tp"+tilepartIndex. /// - public System.Collections.Hashtable sotValue = System.Collections.Hashtable.Synchronized(new System.Collections.Hashtable()); + public System.Collections.Generic.Dictionary sotValue = new Dictionary(); /// Reference to the COD marker segments found in main and first tile-part /// header. The key is either "main" or "t"+tileIdx. /// - public System.Collections.Hashtable codValue = System.Collections.Hashtable.Synchronized(new System.Collections.Hashtable()); - + public System.Collections.Generic.Dictionary codValue = new Dictionary(); + /// Reference to the COC marker segments found in main and first tile-part /// header. The key is either "main_c"+componentIndex or /// "t"+tileIdx+"_c"+component_index. /// - public System.Collections.Hashtable cocValue = System.Collections.Hashtable.Synchronized(new System.Collections.Hashtable()); + public System.Collections.Generic.Dictionary cocValue = new Dictionary(); /// Reference to the RGN marker segments found in main and first tile-part /// header. The key is either "main_c"+componentIndex or /// "t"+tileIdx+"_c"+component_index. /// - public System.Collections.Hashtable rgnValue = System.Collections.Hashtable.Synchronized(new System.Collections.Hashtable()); + public System.Collections.Generic.Dictionary rgnValue = new Dictionary(); /// Reference to the QCD marker segments found in main and first tile-part /// header. The key is either "main" or "t"+tileIdx. /// - public System.Collections.Hashtable qcdValue = System.Collections.Hashtable.Synchronized(new System.Collections.Hashtable()); + public System.Collections.Generic.Dictionary qcdValue = new Dictionary(); /// Reference to the QCC marker segments found in main and first tile-part /// header. They key is either "main_c"+componentIndex or /// "t"+tileIdx+"_c"+component_index. /// - public System.Collections.Hashtable qccValue = System.Collections.Hashtable.Synchronized(new System.Collections.Hashtable()); + public System.Collections.Generic.Dictionary qccValue = new Dictionary(); /// Reference to the POC marker segments found in main and first tile-part /// header. They key is either "main" or "t"+tileIdx. /// - public System.Collections.Hashtable pocValue = System.Collections.Hashtable.Synchronized(new System.Collections.Hashtable()); + public System.Collections.Generic.Dictionary pocValue = new Dictionary(); /// Reference to the CRG marker segment found in main header public CRG crgValue; @@ -1144,7 +1145,7 @@ public override System.String ToString() /// Reference to the COM marker segments found in main and tile-part /// headers. The key is either "main_"+comIdx or "t"+tileIdx+"_"+comIdx. /// - public System.Collections.Hashtable comValue = System.Collections.Hashtable.Synchronized(new System.Collections.Hashtable()); + public System.Collections.Generic.Dictionary comValue = new Dictionary(); /// Number of found COM marker segment private int ncom = 0; @@ -1339,9 +1340,9 @@ public virtual HeaderInfo getCopy(int nt) nhi = (HeaderInfo) Clone(); } //UPGRADE_NOTE: Exception 'java.lang.CloneNotSupportedException' was converted to 'System.Exception' which has different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1100'" - catch (System.Exception) + catch (System.Exception e) { - throw new System.ApplicationException("Cannot clone HeaderInfo instance"); + throw new System.InvalidOperationException("Cannot clone HeaderInfo instance"); } nhi.sizValue = sizValue.Copy; // COD diff --git a/CSJ2K/j2k/codestream/Markers.cs b/CSJ2K/j2k/codestream/Markers.cs index 536d2d9e..7a3a7bb2 100644 --- a/CSJ2K/j2k/codestream/Markers.cs +++ b/CSJ2K/j2k/codestream/Markers.cs @@ -151,9 +151,7 @@ public struct Markers public const short CRG = unchecked((short)0xff63); /// Comment (COM): 0xFF64 public const short COM = unchecked((short)0xff64); - /// General use registration value (binary) (COM): 0x0000 - public const short RCOM_BINARY = 0; - /// General use registration value (latin) (COM): 0x0001 - public const short RCOM_LATIN = 1; + /// General use registration value (COM): 0x0001 + public const short RCOM_GEN_USE = unchecked((short)0x0001); } } \ No newline at end of file diff --git a/CSJ2K/j2k/codestream/reader/BitstreamReaderAgent.cs b/CSJ2K/j2k/codestream/reader/BitstreamReaderAgent.cs index a732fcbc..098b6f46 100644 --- a/CSJ2K/j2k/codestream/reader/BitstreamReaderAgent.cs +++ b/CSJ2K/j2k/codestream/reader/BitstreamReaderAgent.cs @@ -760,7 +760,7 @@ public int getTileCompWidth(int t, int c, int rl) int tIdx = TileIdx; if (t != tIdx) { - throw new System.ApplicationException("Asking the tile-component width of a tile " + "different from the current one."); + throw new System.InvalidOperationException("Asking the tile-component width of a tile " + "different from the current one."); } int ntulx; int dl = mdl[c] - rl; @@ -795,7 +795,7 @@ public int getTileCompHeight(int t, int c, int rl) int tIdx = TileIdx; if (t != tIdx) { - throw new System.ApplicationException("Asking the tile-component width of a tile " + "different from the current one."); + throw new System.InvalidOperationException("Asking the tile-component width of a tile " + "different from the current one."); } int ntuly; int dl = mdl[c] - rl; // Revert level indexation (0 is hi-res) @@ -1232,7 +1232,7 @@ protected internal virtual void initSubbandsFields(int c, SubbandSyn sb) break; default: - throw new System.ApplicationException("Internal JJ2000 error"); + throw new System.InvalidOperationException("Internal JJ2000 error"); } if (sb.ulcx - acb0x < 0 || sb.ulcy - acb0y < 0) diff --git a/CSJ2K/j2k/codestream/reader/FileBitstreamReaderAgent.cs b/CSJ2K/j2k/codestream/reader/FileBitstreamReaderAgent.cs index e992cad6..72d109db 100644 --- a/CSJ2K/j2k/codestream/reader/FileBitstreamReaderAgent.cs +++ b/CSJ2K/j2k/codestream/reader/FileBitstreamReaderAgent.cs @@ -41,6 +41,7 @@ * Copyright (c) 1999/2000 JJ2000 Partners. * */ using System; +using System.Collections.Generic; using CSJ2K.j2k.quantization.dequantizer; using CSJ2K.j2k.wavelet.synthesis; using CSJ2K.j2k.entropy.decoder; @@ -113,7 +114,7 @@ public virtual int getNumTileParts(int t) { if (firstPackOff == null || firstPackOff[t] == null) { - throw new System.ApplicationException("Tile " + t + " not found in input codestream."); + throw new System.InvalidOperationException("Tile " + t + " not found in input codestream."); } return firstPackOff[t].Length; } @@ -160,11 +161,10 @@ public virtual int getNumTileParts(int t) private int[][] tilePartHeadLen; /// Length of each packet head found in the tile - private System.Collections.ArrayList pktHL; - - /// Layer starting positions - public System.Collections.Generic.List layerStarts; + private System.Collections.Generic.List pktHL; + public System.Collections.Generic.List layerStarts; + /// True if truncation mode is used. False if parsing mode private bool isTruncMode; @@ -239,10 +239,10 @@ public virtual int getNumTileParts(int t) /// public FileBitstreamReaderAgent(HeaderDecoder hd, RandomAccessIO ehs, DecoderSpecs decSpec, ParameterList pl, bool cdstrInfo, HeaderInfo hi):base(hd, decSpec) { - this.pl = pl; this.printInfo = cdstrInfo; this.hi = hi; + System.String strInfo = "Codestream elements information in bytes " + "(offset, total length, header length):\n\n"; // Check whether quit conditiosn used usePOCQuit = pl.getBooleanParameter("poc_quit"); @@ -258,26 +258,26 @@ public FileBitstreamReaderAgent(HeaderDecoder hd, RandomAccessIO ehs, DecoderSpe trate = System.Single.MaxValue; } } - catch (System.FormatException) + catch (System.FormatException e) { - throw new System.ApplicationException("Invalid value in 'rate' option: " + pl.getParameter("rate")); + throw new System.InvalidOperationException("Invalid value in 'rate' option: " + pl.getParameter("rate")); } - catch (System.ArgumentException) + catch (System.ArgumentException e) { - throw new System.ApplicationException("'rate' option is missing"); + throw new System.InvalidOperationException("'rate' option is missing"); } try { tnbytes = pl.getIntParameter("nbytes"); } - catch (System.FormatException) + catch (System.FormatException e) { - throw new System.ApplicationException("Invalid value in 'nbytes' option: " + pl.getParameter("nbytes")); + throw new System.InvalidOperationException("Invalid value in 'nbytes' option: " + pl.getParameter("nbytes")); } - catch (System.ArgumentException) + catch (System.ArgumentException e) { - throw new System.ApplicationException("'nbytes' option is missing"); + throw new System.InvalidOperationException("'nbytes' option is missing"); } // Check that '-rate' and '-nbytes' are not used at the same time @@ -309,30 +309,30 @@ public FileBitstreamReaderAgent(HeaderDecoder hd, RandomAccessIO ehs, DecoderSpe { ncbQuit = pl.getIntParameter("ncb_quit"); } - catch (System.FormatException) + catch (System.FormatException e) { - throw new System.ApplicationException("Invalid value in 'ncb_quit' option: " + pl.getParameter("ncb_quit")); + throw new System.InvalidOperationException("Invalid value in 'ncb_quit' option: " + pl.getParameter("ncb_quit")); } - catch (System.ArgumentException) + catch (System.ArgumentException e) { - throw new System.ApplicationException("'ncb_quit' option is missing"); + throw new System.InvalidOperationException("'ncb_quit' option is missing"); } if (ncbQuit != - 1 && !isTruncMode) { - throw new System.ApplicationException("Cannot use -parsing and -ncb_quit condition at " + "the same time."); + throw new System.InvalidOperationException("Cannot use -parsing and -ncb_quit condition at " + "the same time."); } try { lQuit = pl.getIntParameter("l_quit"); } - catch (System.FormatException) + catch (System.FormatException e) { - throw new System.ApplicationException("Invalid value in 'l_quit' option: " + pl.getParameter("l_quit")); + throw new System.InvalidOperationException("Invalid value in 'l_quit' option: " + pl.getParameter("l_quit")); } - catch (System.ArgumentException) + catch (System.ArgumentException e) { - throw new System.ApplicationException("'l_quit' option is missing"); + throw new System.InvalidOperationException("'l_quit' option is missing"); } // initializations @@ -370,10 +370,12 @@ public FileBitstreamReaderAgent(HeaderDecoder hd, RandomAccessIO ehs, DecoderSpe anbytes = 0; } + strInfo += ("Main header length : " + cdstreamStart + ", " + mainHeadLen + ", " + mainHeadLen + "\n"); + // If cannot even read the first tile-part if (anbytes > tnbytes) { - throw new System.ApplicationException("Requested bitrate is too small."); + throw new System.InvalidOperationException("Requested bitrate is too small."); } // Read all tile-part headers from all tiles. @@ -435,6 +437,8 @@ public FileBitstreamReaderAgent(HeaderDecoder hd, RandomAccessIO ehs, DecoderSpe firstPackOff[t][tp] = pos; tilePartHeadLen[t][tp] = (pos - tilePartStart); + strInfo += ("Tile-part " + tp + " of tile " + t + " : " + tilePartStart + ", " + tilePartLen[t][tp] + ", " + tilePartHeadLen[t][tp] + "\n"); + // Update length counters totTileLen[t] += tilePartLen[t][tp]; totTileHeadLen[t] += tilePartHeadLen[t][tp]; @@ -492,10 +496,11 @@ public FileBitstreamReaderAgent(HeaderDecoder hd, RandomAccessIO ehs, DecoderSpe } } } - catch (System.IO.EndOfStreamException) + catch (System.IO.EndOfStreamException e) { if (printInfo) { + FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.INFO, strInfo); } FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.WARNING, "Codestream truncated in tile " + t); @@ -528,7 +533,7 @@ public FileBitstreamReaderAgent(HeaderDecoder hd, RandomAccessIO ehs, DecoderSpe throw new System.ArgumentException("Specified negative " + "resolution level " + "index: " + targetRes); } } - catch (System.FormatException) + catch (System.FormatException f) { throw new System.ArgumentException("Invalid resolution level " + "index ('-res' option) " + pl.getParameter("res")); } @@ -567,7 +572,7 @@ public FileBitstreamReaderAgent(HeaderDecoder hd, RandomAccessIO ehs, DecoderSpe throw new System.ArgumentException("Specified negative " + "resolution level index: " + targetRes); } } - catch (System.FormatException) + catch (System.FormatException e) { throw new System.ArgumentException("Invalid resolution level " + "index ('-res' option) " + pl.getParameter("res")); } @@ -583,6 +588,7 @@ public FileBitstreamReaderAgent(HeaderDecoder hd, RandomAccessIO ehs, DecoderSpe if (printInfo) { + FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.INFO, strInfo); } // Check presence of EOC marker is decoding rate not reached or if @@ -591,16 +597,12 @@ public FileBitstreamReaderAgent(HeaderDecoder hd, RandomAccessIO ehs, DecoderSpe { try { - short eocCheck = 0; - if (in_Renamed.Pos + sizeof(short) <= in_Renamed.length()) - eocCheck = in_Renamed.readShort(); - - if (!rateReached && !isPsotEqualsZero && eocCheck != CSJ2K.j2k.codestream.Markers.EOC) + if (!rateReached && !isPsotEqualsZero && in_Renamed.readShort() != CSJ2K.j2k.codestream.Markers.EOC) { FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.WARNING, "EOC marker not found. " + "Codestream is corrupted."); } } - catch (System.IO.EndOfStreamException) + catch (System.IO.EndOfStreamException e) { FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.WARNING, "EOC marker is missing"); } @@ -648,7 +650,7 @@ private void allocateRate() // error if (anbytes > stopOff) { - throw new System.ApplicationException("Requested bitrate is too small for parsing"); + throw new System.InvalidOperationException("Requested bitrate is too small for parsing"); } // Calculate bitrate for each tile @@ -710,7 +712,7 @@ private int readTilePartHeader() isPsotEqualsZero = (psot != 0)?false:true; if (psot < 0) { - throw new NotImplementedException("Tile length larger " + "than maximum supported"); + throw new NotImplementedException("Tile length larger " + "than maximum supported"); } // TPsot int tilePart = in_Renamed.read(); @@ -909,7 +911,7 @@ private bool readLyResCompPos(int[][] lys, int lye, int ress, int rese, int comp // Check if this component exists if (c >= mdl.Length) continue; - + for (int r = ress; r < rese; r++) { //loop on resolution levels @@ -927,15 +929,17 @@ private bool readLyResCompPos(int[][] lys, int lye, int ress, int rese, int comp int numLayers = ((System.Int32) decSpec.nls.getTileDef(t)); int nPrec = 1; int hlen, plen; + System.String strInfo = "Tile " + TileIdx + " (tile-part:" + curTilePart + "): offset, length, header length\n"; ; bool pph = false; if (((System.Boolean) decSpec.pphs.getTileDef(t))) { pph = true; } + + layerStarts = []; for (int l = minlys; l < lye; l++) { - // store the layer starting position - layerStarts.Add(in_Renamed.Pos); + layerStarts.Add(in_Renamed.Pos); // loop on layers for (int r = ress; r < rese; r++) @@ -985,6 +989,7 @@ private bool readLyResCompPos(int[][] lys, int lye, int ress, int rese, int comp { if (printInfo) { + FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.INFO, strInfo); } return true; } @@ -998,6 +1003,7 @@ private bool readLyResCompPos(int[][] lys, int lye, int ress, int rese, int comp { if (printInfo) { + FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.INFO, strInfo); } return true; } @@ -1009,11 +1015,13 @@ private bool readLyResCompPos(int[][] lys, int lye, int ress, int rese, int comp // Reads packet's body status = pktDec.readPktBody(l, r, c, p, cbI[c][r], nBytes); plen = in_Renamed.Pos - start; + strInfo += (" Pkt l=" + l + ",r=" + r + ",c=" + c + ",p=" + p + ": " + start + ", " + plen + ", " + hlen + "\n"); if (status) { if (printInfo) { + FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.INFO, strInfo); } return true; } @@ -1024,6 +1032,7 @@ private bool readLyResCompPos(int[][] lys, int lye, int ress, int rese, int comp if (printInfo) { + FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.INFO, strInfo); } return false; // Decoding rate was not reached } @@ -1079,6 +1088,7 @@ private bool readResLyCompPos(int[][] lys, int lye, int ress, int rese, int comp } } + System.String strInfo = "Tile " + TileIdx + " (tile-part:" + curTilePart + "): offset, length, header length\n"; ; int numLayers = ((System.Int32) decSpec.nls.getTileDef(t)); bool pph = false; if (((System.Boolean) decSpec.pphs.getTileDef(t))) @@ -1139,6 +1149,7 @@ private bool readResLyCompPos(int[][] lys, int lye, int ress, int rese, int comp { if (printInfo) { + FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.INFO, strInfo); } return true; } @@ -1152,6 +1163,7 @@ private bool readResLyCompPos(int[][] lys, int lye, int ress, int rese, int comp { if (printInfo) { + FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.INFO, strInfo); } // Output rate of EOF reached return true; @@ -1164,11 +1176,13 @@ private bool readResLyCompPos(int[][] lys, int lye, int ress, int rese, int comp // Reads packet's body status = pktDec.readPktBody(l, r, c, p, cbI[c][r], nBytes); plen = in_Renamed.Pos - start; + strInfo += (" Pkt l=" + l + ",r=" + r + ",c=" + c + ",p=" + p + ": " + start + ", " + plen + ", " + hlen + "\n"); if (status) { if (printInfo) { + FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.INFO, strInfo); } // Output rate or EOF reached return true; @@ -1180,6 +1194,7 @@ private bool readResLyCompPos(int[][] lys, int lye, int ress, int rese, int comp if (printInfo) { + FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.INFO, strInfo); } return false; // Decoding rate was not reached } @@ -1298,7 +1313,7 @@ private bool readResPosCompLy(int[][] lys, int lye, int ress, int rese, int comp if (nPrec == 0) { - throw new System.ApplicationException("Image cannot have no precinct"); + throw new System.InvalidOperationException("Image cannot have no precinct"); } int pyend = (maxy - miny) / gcd_y + 1; @@ -1309,6 +1324,7 @@ private bool readResPosCompLy(int[][] lys, int lye, int ress, int rese, int comp bool status = false; int lastByte = firstPackOff[t][curTilePart] + tilePartLen[t][curTilePart] - 1 - tilePartHeadLen[t][curTilePart]; int numLayers = ((System.Int32) decSpec.nls.getTileDef(t)); + System.String strInfo = "Tile " + TileIdx + " (tile-part:" + curTilePart + "): offset, length, header length\n"; ; bool pph = false; if (((System.Boolean) decSpec.pphs.getTileDef(t))) { @@ -1375,6 +1391,7 @@ private bool readResPosCompLy(int[][] lys, int lye, int ress, int rese, int comp { if (printInfo) { + FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.INFO, strInfo); } return true; } @@ -1388,6 +1405,7 @@ private bool readResPosCompLy(int[][] lys, int lye, int ress, int rese, int comp { if (printInfo) { + FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.INFO, strInfo); } return true; } @@ -1399,11 +1417,13 @@ private bool readResPosCompLy(int[][] lys, int lye, int ress, int rese, int comp // Reads packet's body status = pktDec.readPktBody(l, r, c, nextPrec[c][r], cbI[c][r], nBytes); plen = in_Renamed.Pos - start; + strInfo += (" Pkt l=" + l + ",r=" + r + ",c=" + c + ",p=" + nextPrec[c][r] + ": " + start + ", " + plen + ", " + hlen + "\n"); if (status) { if (printInfo) { + FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.INFO, strInfo); } return true; } @@ -1432,6 +1452,7 @@ private bool readResPosCompLy(int[][] lys, int lye, int ress, int rese, int comp if (printInfo) { + FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.INFO, strInfo); } return false; // Decoding rate was not reached } @@ -1548,7 +1569,7 @@ private bool readPosCompResLy(int[][] lys, int lye, int ress, int rese, int comp if (nPrec == 0) { - throw new System.ApplicationException("Image cannot have no precinct"); + throw new System.InvalidOperationException("Image cannot have no precinct"); } int pyend = (maxy - miny) / gcd_y + 1; @@ -1558,6 +1579,7 @@ private bool readPosCompResLy(int[][] lys, int lye, int ress, int rese, int comp bool status = false; int lastByte = firstPackOff[t][curTilePart] + tilePartLen[t][curTilePart] - 1 - tilePartHeadLen[t][curTilePart]; int numLayers = ((System.Int32) decSpec.nls.getTileDef(t)); + System.String strInfo = "Tile " + TileIdx + " (tile-part:" + curTilePart + "): offset, length, header length\n"; ; bool pph = false; if (((System.Boolean) decSpec.pphs.getTileDef(t))) { @@ -1625,6 +1647,7 @@ private bool readPosCompResLy(int[][] lys, int lye, int ress, int rese, int comp { if (printInfo) { + FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.INFO, strInfo); } return true; } @@ -1638,6 +1661,7 @@ private bool readPosCompResLy(int[][] lys, int lye, int ress, int rese, int comp { if (printInfo) { + FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.INFO, strInfo); } return true; } @@ -1649,11 +1673,13 @@ private bool readPosCompResLy(int[][] lys, int lye, int ress, int rese, int comp // Reads packet's body status = pktDec.readPktBody(l, r, c, nextPrec[c][r], cbI[c][r], nBytes); plen = in_Renamed.Pos - start; + strInfo += (" Pkt l=" + l + ",r=" + r + ",c=" + c + ",p=" + nextPrec[c][r] + ": " + start + ", " + plen + ", " + hlen + "\n"); if (status) { if (printInfo) { + FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.INFO, strInfo); } return true; } @@ -1682,6 +1708,7 @@ private bool readPosCompResLy(int[][] lys, int lye, int ress, int rese, int comp if (printInfo) { + FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.INFO, strInfo); } return false; // Decoding rate was not reached } @@ -1798,7 +1825,7 @@ private bool readCompPosResLy(int[][] lys, int lye, int ress, int rese, int comp if (nPrec == 0) { - throw new System.ApplicationException("Image cannot have no precinct"); + throw new System.InvalidOperationException("Image cannot have no precinct"); } int pyend = (maxy - miny) / gcd_y + 1; @@ -1808,6 +1835,7 @@ private bool readCompPosResLy(int[][] lys, int lye, int ress, int rese, int comp bool status = false; int lastByte = firstPackOff[t][curTilePart] + tilePartLen[t][curTilePart] - 1 - tilePartHeadLen[t][curTilePart]; int numLayers = ((System.Int32) decSpec.nls.getTileDef(t)); + System.String strInfo = "Tile " + TileIdx + " (tile-part:" + curTilePart + "): offset, length, header length\n"; ; bool pph = false; if (((System.Boolean) decSpec.pphs.getTileDef(t))) { @@ -1877,6 +1905,7 @@ private bool readCompPosResLy(int[][] lys, int lye, int ress, int rese, int comp { if (printInfo) { + FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.INFO, strInfo); } return true; } @@ -1890,6 +1919,7 @@ private bool readCompPosResLy(int[][] lys, int lye, int ress, int rese, int comp { if (printInfo) { + FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.INFO, strInfo); } return true; } @@ -1901,11 +1931,13 @@ private bool readCompPosResLy(int[][] lys, int lye, int ress, int rese, int comp // Reads packet's body status = pktDec.readPktBody(l, r, c, nextPrec[c][r], cbI[c][r], nBytes); plen = in_Renamed.Pos - start; + strInfo += (" Pkt l=" + l + ",r=" + r + ",c=" + c + ",p=" + nextPrec[c][r] + ": " + start + ", " + plen + ", " + hlen + "\n"); if (status) { if (printInfo) { + FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.INFO, strInfo); } return true; } @@ -1934,6 +1966,7 @@ private bool readCompPosResLy(int[][] lys, int lye, int ress, int rese, int comp if (printInfo) { + FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.INFO, strInfo); } return false; // Decoding rate was not reached } @@ -1956,8 +1989,7 @@ private bool readCompPosResLy(int[][] lys, int lye, int ress, int rese, int comp /// private void readTilePkts(int t) { - pktHL = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10)); - layerStarts = new System.Collections.Generic.List(5); + pktHL = new List(10); // Number of layers int nl = ((System.Int32) decSpec.nls.getTileDef(t)); @@ -2030,7 +2062,7 @@ private void readTilePkts(int t) } in_Renamed.seek(firstPackOff[t][0]); } - catch (System.IO.EndOfStreamException) + catch (System.IO.EndOfStreamException e) { FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.WARNING, "Codestream truncated in tile " + t); return ; @@ -2365,8 +2397,8 @@ public override void setTile(int x, int y) } catch (System.IO.IOException e) { - SupportClass.WriteStackTrace(e, Console.Error); - throw new System.ApplicationException("IO Error when reading tile " + x + " x " + y); + SupportClass.WriteStackTrace(e); + throw new System.InvalidOperationException("IO Error when reading tile " + x + " x " + y); } } @@ -2482,7 +2514,7 @@ public override DecLyrdCBlk getCodeBlock(int c, int m, int n, SubbandSyn sb, int int maxdl = getSynSubbandTree(t, c).resLvl; if (r > targetRes + maxdl - decSpec.dls.Min) { - throw new System.ApplicationException("JJ2000 error: requesting a code-block " + "disallowed by the '-res' option."); + throw new System.InvalidOperationException("JJ2000 error: requesting a code-block " + "disallowed by the '-res' option."); } // Check validity of all the arguments @@ -2495,11 +2527,11 @@ public override DecLyrdCBlk getCodeBlock(int c, int m, int n, SubbandSyn sb, int throw new System.ArgumentException(); } } - catch (System.IndexOutOfRangeException) + catch (System.IndexOutOfRangeException e) { throw new System.ArgumentException("Code-block (t:" + t + ", c:" + c + ", r:" + r + ", s:" + s + ", " + m + "x" + (+ n) + ") not found in codestream"); } - catch (System.NullReferenceException) + catch (System.NullReferenceException e) { throw new System.ArgumentException("Code-block (t:" + t + ", c:" + c + ", r:" + r + ", s:" + s + ", " + m + "x" + n + ") not found in bit stream"); } diff --git a/CSJ2K/j2k/codestream/reader/HeaderDecoder.cs b/CSJ2K/j2k/codestream/reader/HeaderDecoder.cs index fb12a38d..db019851 100644 --- a/CSJ2K/j2k/codestream/reader/HeaderDecoder.cs +++ b/CSJ2K/j2k/codestream/reader/HeaderDecoder.cs @@ -41,6 +41,7 @@ * Copyright (c) 1999/2000 JJ2000 Partners. * */ using System; +using System.Collections.Generic; using CSJ2K.j2k.quantization.dequantizer; using CSJ2K.j2k.wavelet.synthesis; using CSJ2K.j2k.entropy.decoder; @@ -451,7 +452,7 @@ virtual public int NumFoundMarkSeg //private static readonly int TILE_RESET = ~ (PLM_FOUND | SIZ_FOUND | RGN_FOUND); /// HashTable used to store temporary marker segment byte buffers - private System.Collections.Hashtable ht = null; + private System.Collections.Generic.Dictionary ht = null; /// The number of components in the image private int nComp; @@ -472,7 +473,7 @@ virtual public int NumFoundMarkSeg public int mainHeadOff; /// Vector containing info as to which tile each tilepart belong - private System.Collections.ArrayList tileOfTileParts; + private System.Collections.Generic.List tileOfTileParts; /// Array containing the Nppm and Ippm fields of the PPM marker segments private byte[][] pPMMarkerData; @@ -667,7 +668,7 @@ private SynWTFilter readFilter(System.IO.BinaryReader ehs, int[] filtIdx) kid = filtIdx[0] = ehs.ReadByte(); if (kid >= (1 << 7)) { - throw new NotImplementedException("Custom filters not supported"); + throw new NotImplementedException("Custom filters not supported"); } // Return filter based on ID switch (kid) @@ -736,7 +737,7 @@ private void readSIZ(System.IO.BinaryReader ehs) ms.rsiz = ehs.ReadUInt16(); if (ms.rsiz > 2) { - throw new System.ApplicationException("Codestream capabiities not JPEG 2000 - Part I" + " compliant"); + throw new System.InvalidOperationException("Codestream capabiities not JPEG 2000 - Part I" + " compliant"); } // Read image size @@ -865,18 +866,19 @@ private void readCOM(System.IO.BinaryReader ehs, bool mainh, int tileIdx, int c ms.rcom = ehs.ReadUInt16(); switch (ms.rcom) { - case CSJ2K.j2k.codestream.Markers.RCOM_BINARY: - case CSJ2K.j2k.codestream.Markers.RCOM_LATIN: + + case CSJ2K.j2k.codestream.Markers.RCOM_GEN_USE: ms.ccom = new byte[ms.lcom - 4]; for (int i = 0; i < ms.lcom - 4; i++) { ms.ccom[i] = ehs.ReadByte(); } break; - default: + + default: // --- Unknown or unsupported markers --- // (skip them and see if we can get way with it) - FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.WARNING, "COM marker registered as " + ms.rcom + " unknown, ignoring (this might crash the " + "decoder or decode a quality degraded or even " + "useless image)"); + FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.WARNING, "COM marker registered as 0x" + System.Convert.ToString(ms.rcom, 16) + " unknown, ignoring (this might crash the " + "decoder or decode a quality degraded or even " + "useless image)"); System.IO.BinaryReader temp_BinaryReader; System.Int64 temp_Int64; temp_BinaryReader = ehs; @@ -1596,9 +1598,9 @@ private void readCOD(System.IO.BinaryReader ehs, bool mainh, int tileIdx, int t hvfilters[1] = vfilters; // Get precinct partition sizes - System.Collections.ArrayList[] v = new System.Collections.ArrayList[2]; - v[0] = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10)); - v[1] = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10)); + System.Collections.Generic.List[] v = new System.Collections.Generic.List[2]; + v[0] = new List(10); + v[1] = new List(10); int val = CSJ2K.j2k.codestream.Markers.PRECINCT_PARTITION_DEF_SIZE; if (!precinctPartitionIsUsed) { @@ -1774,9 +1776,9 @@ private void readCOC(System.IO.BinaryReader ehs, bool mainh, int tileIdx, int t hvfilters[1] = vfilters; // Get precinct partition sizes - System.Collections.ArrayList[] v = new System.Collections.ArrayList[2]; - v[0] = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10)); - v[1] = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10)); + System.Collections.Generic.List[] v = new System.Collections.Generic.List[2]; + v[0] = new List(10); + v[1] = new List(10); int val = CSJ2K.j2k.codestream.Markers.PRECINCT_PARTITION_DEF_SIZE; if (!precinctPartitionIsUsed) { @@ -2186,7 +2188,7 @@ private void readPPM(System.IO.BinaryReader ehs) if (pPMMarkerData == null) { pPMMarkerData = new byte[nPPMMarkSeg][]; - tileOfTileParts = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10)); + tileOfTileParts = new List(10); decSpec.pphs.setDefault((System.Object) true); } @@ -2292,7 +2294,7 @@ private void extractMainMarkSeg(short marker, RandomAccessIO ehs) System.String htKey = ""; // Name used as a key for the hash-table if (ht == null) { - ht = System.Collections.Hashtable.Synchronized(new System.Collections.Hashtable()); + ht = new Dictionary(); } switch (marker) @@ -2458,7 +2460,7 @@ public virtual void extractTilePartMarkSeg(short marker, RandomAccessIO ehs, in System.String htKey = ""; // Name used as a hash-table key if (ht == null) { - ht = System.Collections.Hashtable.Synchronized(new System.Collections.Hashtable()); + ht = new Dictionary(); } switch (marker) @@ -2594,7 +2596,6 @@ private void readFoundMainMarkSeg() { bais = new System.IO.MemoryStream((byte[])ht["SIZ"]); readSIZ(new CSJ2K.Util.EndianBinaryReader(bais, true)); - bais.Dispose(); } // COM marker segments @@ -2604,7 +2605,6 @@ private void readFoundMainMarkSeg() { bais = new System.IO.MemoryStream((byte[])ht["COM" + i]); readCOM(new CSJ2K.Util.EndianBinaryReader(bais, true), true, 0, i); - bais.Dispose(); } } @@ -2613,7 +2613,6 @@ private void readFoundMainMarkSeg() { bais = new System.IO.MemoryStream((byte[])ht["CRG"]); readCRG(new CSJ2K.Util.EndianBinaryReader(bais, true)); - bais.Dispose(); } // COD marker segment @@ -2621,7 +2620,6 @@ private void readFoundMainMarkSeg() { bais = new System.IO.MemoryStream((byte[])ht["COD"]); readCOD(new CSJ2K.Util.EndianBinaryReader(bais, true), true, 0, 0); - bais.Dispose(); } // COC marker segments @@ -2631,7 +2629,6 @@ private void readFoundMainMarkSeg() { bais = new System.IO.MemoryStream((byte[])ht["COC" + i]); readCOC(new CSJ2K.Util.EndianBinaryReader(bais, true), true, 0, 0); - bais.Dispose(); } } @@ -2642,7 +2639,6 @@ private void readFoundMainMarkSeg() { bais = new System.IO.MemoryStream((byte[])ht["RGN" + i]); readRGN(new CSJ2K.Util.EndianBinaryReader(bais, true), true, 0, 0); - bais.Dispose(); } } @@ -2651,7 +2647,6 @@ private void readFoundMainMarkSeg() { bais = new System.IO.MemoryStream((byte[])ht["QCD"]); readQCD(new CSJ2K.Util.EndianBinaryReader(bais, true), true, 0, 0); - bais.Dispose(); } // QCC marker segments @@ -2661,7 +2656,6 @@ private void readFoundMainMarkSeg() { bais = new System.IO.MemoryStream((byte[])ht["QCC" + i]); readQCC(new CSJ2K.Util.EndianBinaryReader(bais, true), true, 0, 0); - bais.Dispose(); } } @@ -2670,7 +2664,6 @@ private void readFoundMainMarkSeg() { bais = new System.IO.MemoryStream((byte[])ht["POC"]); readPOC(new CSJ2K.Util.EndianBinaryReader(bais, true), true, 0, 0); - bais.Dispose(); } // PPM marker segments @@ -2680,7 +2673,6 @@ private void readFoundMainMarkSeg() { bais = new System.IO.MemoryStream((byte[])ht["PPM" + i]); readPPM(new CSJ2K.Util.EndianBinaryReader(bais)); - bais.Dispose(); } } diff --git a/CSJ2K/j2k/codestream/reader/PktDecoder.cs b/CSJ2K/j2k/codestream/reader/PktDecoder.cs index ac4390d5..1fbfca2c 100644 --- a/CSJ2K/j2k/codestream/reader/PktDecoder.cs +++ b/CSJ2K/j2k/codestream/reader/PktDecoder.cs @@ -42,6 +42,7 @@ /// ///
using System; +using System.Collections.Generic; using CSJ2K.j2k.wavelet.synthesis; using CSJ2K.j2k.codestream; using CSJ2K.j2k.entropy; @@ -168,7 +169,7 @@ public class PktDecoder /// List of code-blocks found in last read packet head (one list /// per subband) /// - private System.Collections.ArrayList[] cblks; + private System.Collections.Generic.List[] cblks; /// Number of codeblocks encountered. used for ncb quit condition private int ncb; @@ -991,10 +992,10 @@ public virtual bool readPktHead(int l, int r, int c, int p, CBlkInfo[][][] cbI, if (bin.readBit() == 0) { // No code-block is included - cblks = new System.Collections.ArrayList[maxs + 1]; + cblks = new List[maxs + 1]; for (int s = mins; s < maxs; s++) { - cblks[s] = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10)); + cblks[s] = new List(10); } pktIdx++; @@ -1027,14 +1028,14 @@ public virtual bool readPktHead(int l, int r, int c, int p, CBlkInfo[][][] cbI, // Loop on each subband in this resolution level if (cblks == null || cblks.Length < maxs + 1) { - cblks = new System.Collections.ArrayList[maxs + 1]; + cblks = new List[maxs + 1]; } for (int s = mins; s < maxs; s++) { if (cblks[s] == null) { - cblks[s] = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10)); + cblks[s] = new List(10); } else { @@ -1310,7 +1311,7 @@ public virtual bool readPktHead(int l, int r, int c, int p, CBlkInfo[][][] cbI, } } } - catch (System.IO.EndOfStreamException) + catch (System.IO.EndOfStreamException e) { // Remove found information in this code-block if (l == 0) @@ -1420,7 +1421,7 @@ public virtual bool readPktBody(int l, int r, int c, int p, CBlkInfo[][][] cbI, { ehs.seek(curOff); } - catch (System.IO.EndOfStreamException) + catch (System.IO.EndOfStreamException e) { if (l == 0) { @@ -1433,13 +1434,7 @@ public virtual bool readPktBody(int l, int r, int c, int p, CBlkInfo[][][] cbI, ccb.ntp[l] = 0; ccb.pktIdx[l] = - 1; } - - // JH: If we try and seek past the end of the stream just stop the decoding - curOff = ehs.length() - 1; - ehs.seek(curOff); - stopRead = true; - return true; - //throw new System.IO.EndOfStreamException(); + throw new System.IO.EndOfStreamException(); } // If truncation mode @@ -1601,7 +1596,7 @@ public virtual bool readSOPMarker(int[] nBytes, int p, int c, int r) val |= sopArray[1]; if (val != CSJ2K.j2k.codestream.Markers.SOP) { - throw new System.ApplicationException("Corrupted Bitstream: Could not parse SOP " + "marker !"); + throw new System.InvalidOperationException("Corrupted Bitstream: Could not parse SOP " + "marker !"); } // Check if length is correct @@ -1610,7 +1605,7 @@ public virtual bool readSOPMarker(int[] nBytes, int p, int c, int r) val |= (sopArray[3] & 0xff); if (val != 4) { - throw new System.ApplicationException("Corrupted Bitstream: Corrupted SOP marker !"); + throw new System.InvalidOperationException("Corrupted Bitstream: Corrupted SOP marker !"); } // Check if sequence number if ok @@ -1620,13 +1615,13 @@ public virtual bool readSOPMarker(int[] nBytes, int p, int c, int r) if (!pph && val != pktIdx) { - throw new System.ApplicationException("Corrupted Bitstream: SOP marker out of " + "sequence !"); + throw new System.InvalidOperationException("Corrupted Bitstream: SOP marker out of " + "sequence !"); } if (pph && val != pktIdx - 1) { // if packed packet headers are used, packet header was read // before SOP marker segment - throw new System.ApplicationException("Corrupted Bitstream: SOP marker out of " + "sequence !"); + throw new System.InvalidOperationException("Corrupted Bitstream: SOP marker out of " + "sequence !"); } return false; } @@ -1658,7 +1653,7 @@ public virtual void readEPHMarker(PktHeaderBitReader bin) val |= ephArray[1]; if (val != CSJ2K.j2k.codestream.Markers.EPH) { - throw new System.ApplicationException("Corrupted Bitstream: Could not parse EPH " + "marker ! "); + throw new System.InvalidOperationException("Corrupted Bitstream: Could not parse EPH " + "marker ! "); } } diff --git a/CSJ2K/j2k/codestream/writer/BitOutputBuffer.cs b/CSJ2K/j2k/codestream/writer/BitOutputBuffer.cs index 0b367f4a..7e67929b 100644 --- a/CSJ2K/j2k/codestream/writer/BitOutputBuffer.cs +++ b/CSJ2K/j2k/codestream/writer/BitOutputBuffer.cs @@ -44,272 +44,272 @@ using CSJ2K.j2k.util; namespace CSJ2K.j2k.codestream.writer { - - /// This class implements a buffer for writing bits, with the required bit - /// stuffing policy for the packet headers. The bits are stored in a byte array - /// in the order in which they are written. The byte array is automatically - /// reallocated and enlarged whenever necessary. A BitOutputBuffer object may - /// be reused by calling its 'reset()' method. - /// - ///

NOTE: The methods implemented in this class are intended to be used only - /// in writing packet heads, since a special bit stuffing procedure is used, as - /// required for the packet heads. - /// - ///

- public class BitOutputBuffer - { - /// Returns the current length of the buffer, in bytes. - /// - ///

This method is declared final to increase performance. - /// - ///

- /// The currebt length of the buffer in bytes. - /// - /// - virtual public int Length - { - get - { - if (avbits == 8) - { - // A integral number of bytes - return curbyte; - } - else - { - // Some bits in last byte - return curbyte + 1; - } - } - - } - /// Returns the byte buffer. This is the internal byte buffer so it should - /// not be modified. Only the first N elements have valid data, where N is - /// the value returned by 'getLength()' - /// - ///

This method is declared final to increase performance. - /// - ///

- /// The internal byte buffer. - /// - /// - virtual public byte[] Buffer - { - get - { - return buf; - } - - } - - /// The buffer where we store the data - internal byte[] buf; - - /// The position of the current byte to write - internal int curbyte; - - /// The number of available bits in the current byte - internal int avbits = 8; - - /// The increment size for the buffer, 16 bytes. This is the - /// number of bytes that are added to the buffer each time it is - /// needed to enlarge it. - /// - // This must be always 6 or larger. - public const int SZ_INCR = 16; - - /// The initial size for the buffer, 32 bytes. - public const int SZ_INIT = 32; - - /// Creates a new BitOutputBuffer width a buffer of length - /// 'SZ_INIT'. - /// - /// - public BitOutputBuffer() - { - buf = new byte[SZ_INIT]; - } - - /// Resets the buffer. This rewinds the current position to the start of - /// the buffer and sets all tha data to 0. Note that no new buffer is - /// allocated, so this will affect any data that was returned by the - /// 'getBuffer()' method. - /// - /// - public virtual void reset() - { - //int i; - // Reinit pointers - curbyte = 0; - avbits = 8; - ArrayUtil.byteArraySet(buf, (byte)0); - } - - /// Writes a bit to the buffer at the current position. The value 'bit' - /// must be either 0 or 1, otherwise it corrupts the bits that have been - /// already written. The buffer is enlarged, by 'SZ_INCR' bytes, if - /// necessary. - /// - ///

This method is declared final to increase performance. - /// - ///

- /// The bit to write, 0 or 1. - /// - /// - public void writeBit(int bit) - { - buf[curbyte] |= (byte)(bit << --avbits); - if (avbits > 0) - { - // There is still place in current byte for next bit - return; - } - else - { - // End of current byte => goto next - if (buf[curbyte] != (byte)SupportClass.Identity(0xFF)) - { - // We don't need bit stuffing - avbits = 8; - } - else - { - // We need to stuff a bit (next MSBit is 0) - avbits = 7; - } - curbyte++; - if (curbyte == buf.Length) - { - // We are at end of 'buf' => extend it - byte[] oldbuf = buf; - buf = new byte[oldbuf.Length + SZ_INCR]; - Array.Copy(oldbuf, 0, buf, 0, oldbuf.Length); - } - } - } - - /// Writes the n least significant bits of 'bits' to the buffer at the - /// current position. The least significant bit is written last. The 32-n - /// most significant bits of 'bits' must be 0, otherwise corruption of the - /// buffer will result. The buffer is enlarged, by 'SZ_INCR' bytes, if - /// necessary. - /// - ///

This method is declared final to increase performance. - /// - ///

- /// The bits to write. - /// - /// - /// The number of LSBs in 'bits' to write. - /// - /// - public void writeBits(int bits, int n) - { - // Check that we have enough place in 'buf' for n bits, and that we do - // not fill last byte, taking into account possibly stuffed bits (max - // 2) - if (((buf.Length - curbyte) << 3) - 8 + avbits <= n + 2) - { - // Not enough place, extend it - byte[] oldbuf = buf; - buf = new byte[oldbuf.Length + SZ_INCR]; - Array.Copy(oldbuf, 0, buf, 0, oldbuf.Length); - // SZ_INCR is always 6 or more, so it is enough to hold all the - // new bits plus the ones to come after - } - // Now write the bits - if (n >= avbits) - { - // Complete the current byte - n -= avbits; - buf[curbyte] |= (byte)(bits >> n); - if (buf[curbyte] != (byte)SupportClass.Identity(0xFF)) - { - // We don't need bit stuffing - avbits = 8; - } - else - { - // We need to stuff a bit (next MSBit is 0) - avbits = 7; - } - curbyte++; - // Write whole bytes - while (n >= avbits) - { - n -= avbits; + + /// This class implements a buffer for writing bits, with the required bit + /// stuffing policy for the packet headers. The bits are stored in a byte array + /// in the order in which they are written. The byte array is automatically + /// reallocated and enlarged whenever necessary. A BitOutputBuffer object may + /// be reused by calling its 'reset()' method. + /// + ///

NOTE: The methods implemented in this class are intended to be used only + /// in writing packet heads, since a special bit stuffing procedure is used, as + /// required for the packet heads. + /// + ///

+ public class BitOutputBuffer + { + /// Returns the current length of the buffer, in bytes. + /// + ///

This method is declared final to increase performance. + /// + ///

+ /// The currebt length of the buffer in bytes. + /// + /// + virtual public int Length + { + get + { + if (avbits == 8) + { + // A integral number of bytes + return curbyte; + } + else + { + // Some bits in last byte + return curbyte + 1; + } + } + + } + /// Returns the byte buffer. This is the internal byte buffer so it should + /// not be modified. Only the first N elements have valid data, where N is + /// the value returned by 'getLength()' + /// + ///

This method is declared final to increase performance. + /// + ///

+ /// The internal byte buffer. + /// + /// + virtual public byte[] Buffer + { + get + { + return buf; + } + + } + + /// The buffer where we store the data + internal byte[] buf; + + /// The position of the current byte to write + internal int curbyte; + + /// The number of available bits in the current byte + internal int avbits = 8; + + /// The increment size for the buffer, 16 bytes. This is the + /// number of bytes that are added to the buffer each time it is + /// needed to enlarge it. + /// + // This must be always 6 or larger. + public const int SZ_INCR = 16; + + /// The initial size for the buffer, 32 bytes. + public const int SZ_INIT = 32; + + /// Creates a new BitOutputBuffer width a buffer of length + /// 'SZ_INIT'. + /// + /// + public BitOutputBuffer() + { + buf = new byte[SZ_INIT]; + } + + /// Resets the buffer. This rewinds the current position to the start of + /// the buffer and sets all tha data to 0. Note that no new buffer is + /// allocated, so this will affect any data that was returned by the + /// 'getBuffer()' method. + /// + /// + public virtual void reset() + { + //int i; + // Reinit pointers + curbyte = 0; + avbits = 8; + ArrayUtil.byteArraySet(buf, (byte) 0); + } + + /// Writes a bit to the buffer at the current position. The value 'bit' + /// must be either 0 or 1, otherwise it corrupts the bits that have been + /// already written. The buffer is enlarged, by 'SZ_INCR' bytes, if + /// necessary. + /// + ///

This method is declared final to increase performance. + /// + ///

+ /// The bit to write, 0 or 1. + /// + /// + public void writeBit(int bit) + { + buf[curbyte] |= (byte) (bit << --avbits); + if (avbits > 0) + { + // There is still place in current byte for next bit + return ; + } + else + { + // End of current byte => goto next + if (buf[curbyte] != (byte) SupportClass.Identity(0xFF)) + { + // We don't need bit stuffing + avbits = 8; + } + else + { + // We need to stuff a bit (next MSBit is 0) + avbits = 7; + } + curbyte++; + if (curbyte == buf.Length) + { + // We are at end of 'buf' => extend it + byte[] oldbuf = buf; + buf = new byte[oldbuf.Length + SZ_INCR]; + Array.Copy(oldbuf, 0, buf, 0, oldbuf.Length); + } + } + } + + /// Writes the n least significant bits of 'bits' to the buffer at the + /// current position. The least significant bit is written last. The 32-n + /// most significant bits of 'bits' must be 0, otherwise corruption of the + /// buffer will result. The buffer is enlarged, by 'SZ_INCR' bytes, if + /// necessary. + /// + ///

This method is declared final to increase performance. + /// + ///

+ /// The bits to write. + /// + /// + /// The number of LSBs in 'bits' to write. + /// + /// + public void writeBits(int bits, int n) + { + // Check that we have enough place in 'buf' for n bits, and that we do + // not fill last byte, taking into account possibly stuffed bits (max + // 2) + if (((buf.Length - curbyte) << 3) - 8 + avbits <= n + 2) + { + // Not enough place, extend it + byte[] oldbuf = buf; + buf = new byte[oldbuf.Length + SZ_INCR]; + Array.Copy(oldbuf, 0, buf, 0, oldbuf.Length); + // SZ_INCR is always 6 or more, so it is enough to hold all the + // new bits plus the ones to come after + } + // Now write the bits + if (n >= avbits) + { + // Complete the current byte + n -= avbits; + buf[curbyte] |= (byte) (bits >> n); + if (buf[curbyte] != (byte) SupportClass.Identity(0xFF)) + { + // We don't need bit stuffing + avbits = 8; + } + else + { + // We need to stuff a bit (next MSBit is 0) + avbits = 7; + } + curbyte++; + // Write whole bytes + while (n >= avbits) + { + n -= avbits; // CONVERSION PROBLEM? - buf[curbyte] |= (byte)((bits >> n) & (~(1 << avbits))); - if (buf[curbyte] != (byte)SupportClass.Identity(0xFF)) - { - // We don't need bit - // stuffing - avbits = 8; - } - else - { - // We need to stuff a bit (next MSBit is 0) - avbits = 7; - } - curbyte++; - } - } - // Finish last byte (we know that now n < avbits) - if (n > 0) - { - avbits -= n; - buf[curbyte] |= (byte)((bits & ((1 << n) - 1)) << avbits); - } - if (avbits == 0) - { - // Last byte is full - if (buf[curbyte] != (byte)SupportClass.Identity(0xFF)) - { - // We don't need bit stuffing - avbits = 8; - } - else - { - // We need to stuff a bit (next MSBit is 0) - avbits = 7; - } - curbyte++; // We already ensured that we have enough place - } - } - - /// Returns the byte buffer data in a new array. This is a copy of the - /// internal byte buffer. If 'data' is non-null it is used to return the - /// data. This array should be large enough to contain all the data, - /// otherwise a IndexOutOfBoundsException is thrown by the Java system. The - /// number of elements returned is what 'getLength()' returns. - /// - /// - /// If non-null this array is used to return the data, which - /// mus be large enough. Otherwise a new one is created and returned. - /// - /// - /// The byte buffer data. - /// - /// - public virtual byte[] toByteArray(byte[] data) - { - if (data == null) - { - data = new byte[(avbits == 8) ? curbyte : curbyte + 1]; - } - Array.Copy(buf, 0, data, 0, (avbits == 8) ? curbyte : curbyte + 1); - return data; - } - - /// Prints information about this object for debugging purposes - /// - /// - /// Information about the object. - /// - /// - public override System.String ToString() - { - return "bits written = " + (curbyte * 8 + (8 - avbits)) + ", curbyte = " + curbyte + ", avbits = " + avbits; - } - } + buf[curbyte] |= (byte)((bits >> n) & (~ (1 << avbits))); + if (buf[curbyte] != (byte) SupportClass.Identity(0xFF)) + { + // We don't need bit + // stuffing + avbits = 8; + } + else + { + // We need to stuff a bit (next MSBit is 0) + avbits = 7; + } + curbyte++; + } + } + // Finish last byte (we know that now n < avbits) + if (n > 0) + { + avbits -= n; + buf[curbyte] |= (byte) ((bits & ((1 << n) - 1)) << avbits); + } + if (avbits == 0) + { + // Last byte is full + if (buf[curbyte] != (byte) SupportClass.Identity(0xFF)) + { + // We don't need bit stuffing + avbits = 8; + } + else + { + // We need to stuff a bit (next MSBit is 0) + avbits = 7; + } + curbyte++; // We already ensured that we have enough place + } + } + + /// Returns the byte buffer data in a new array. This is a copy of the + /// internal byte buffer. If 'data' is non-null it is used to return the + /// data. This array should be large enough to contain all the data, + /// otherwise a IndexOutOfBoundsException is thrown by the Java system. The + /// number of elements returned is what 'getLength()' returns. + /// + /// + /// If non-null this array is used to return the data, which + /// mus be large enough. Otherwise a new one is created and returned. + /// + /// + /// The byte buffer data. + /// + /// + public virtual byte[] toByteArray(byte[] data) + { + if (data == null) + { + data = new byte[(avbits == 8)?curbyte:curbyte + 1]; + } + Array.Copy(buf, 0, data, 0, (avbits == 8)?curbyte:curbyte + 1); + return data; + } + + /// Prints information about this object for debugging purposes + /// + /// + /// Information about the object. + /// + /// + public override System.String ToString() + { + return "bits written = " + (curbyte * 8 + (8 - avbits)) + ", curbyte = " + curbyte + ", avbits = " + avbits; + } + } } \ No newline at end of file diff --git a/CSJ2K/j2k/codestream/writer/FileCodestreamWriter.cs b/CSJ2K/j2k/codestream/writer/FileCodestreamWriter.cs index 5e29491a..3d581cf1 100644 --- a/CSJ2K/j2k/codestream/writer/FileCodestreamWriter.cs +++ b/CSJ2K/j2k/codestream/writer/FileCodestreamWriter.cs @@ -41,6 +41,7 @@ * Copyright (c) 1999/2000 JJ2000 Partners. * */ using System; +using CSJ2K.Util; using CSJ2K.j2k.codestream; namespace CSJ2K.j2k.codestream.writer { @@ -147,7 +148,8 @@ override public int OffLastROIPkt /// Length of last packets containing no ROI information private int lenLastNoROI = 0; - + +#if DOTNET ///
Opens the file 'file' for writing the codestream. The magic number is /// written to the bit stream. Normally, the header encoder must be empty /// (i.e. no data has been written to it yet). A BufferedOutputStream is @@ -166,41 +168,15 @@ override public int OffLastROIPkt /// for writing or while writing the magic number. /// /// - public FileCodestreamWriter(System.IO.FileInfo file, int mb):base(mb) + public FileCodestreamWriter(System.IO.FileInfo file, int mb) + : base(mb) { //UPGRADE_TODO: Constructor 'java.io.FileOutputStream.FileOutputStream' was converted to 'System.IO.FileStream.FileStream' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javaioFileOutputStreamFileOutputStream_javaioFile'" out_Renamed = new System.IO.BufferedStream(new System.IO.FileStream(file.FullName, System.IO.FileMode.Create), DEF_BUF_LEN); initSOP_EPHArrays(); - } - - /// Opens the file named 'fname' for writing the bit stream, using the 'he' - /// header encoder. The magic number is written to the bit - /// stream. Normally, the header encoder must be empty (i.e. no data has - /// been written to it yet). A BufferedOutputStream is used on top of the - /// file to increase throughput, the length of the buffer is DEF_BUF_LEN. - /// - /// - /// The name of file where to write the bit stream - /// - /// - /// The maximum number of bytes that can be written to the bit - /// stream. - /// - /// - /// The encoder's specifications - /// - /// - /// If an error occurs while trying to open the file - /// for writing or while writing the magic number. - /// - /// - public FileCodestreamWriter(System.String fname, int mb):base(mb) - { - //UPGRADE_TODO: Constructor 'java.io.FileOutputStream.FileOutputStream' was converted to 'System.IO.FileStream.FileStream' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javaioFileOutputStreamFileOutputStream_javalangString'" - out_Renamed = new System.IO.BufferedStream(new System.IO.FileStream(fname, System.IO.FileMode.Create), DEF_BUF_LEN); - initSOP_EPHArrays(); - } - + } +#endif + /// Uses the output stream 'os' for writing the bit stream, using the 'he' /// header encoder. The magic number is written to the bit /// stream. Normally, the header encoder must be empty (i.e. no data has @@ -395,7 +371,7 @@ public override int writePacketBody(byte[] body, int blen, bool sim, bool roiInP return len; } - /// Writes the EOC marker and closes the underlying stream. + /// Writes the EOC marker. /// /// /// If an error occurs while closing the underlying @@ -411,8 +387,6 @@ public override void close() out_Renamed.WriteByte((byte) (CSJ2K.j2k.codestream.Markers.EOC & 0x00FF)); ndata += 2; // Add two to length of codestream for EOC marker - - out_Renamed.Close(); } /// Writes the header data in the codestream and actualize ndata with the diff --git a/CSJ2K/j2k/codestream/writer/HeaderEncoder.cs b/CSJ2K/j2k/codestream/writer/HeaderEncoder.cs index a27231e9..6bccb1ee 100644 --- a/CSJ2K/j2k/codestream/writer/HeaderEncoder.cs +++ b/CSJ2K/j2k/codestream/writer/HeaderEncoder.cs @@ -666,14 +666,14 @@ protected internal virtual void writeCOD(bool mh, int tileIdx) { // Write the precinct size for each resolution level + 1 // (resolution 0) if precinct partition is used. - System.Collections.ArrayList[] v = null; + System.Collections.Generic.List[] v = null; if (mh) { - v = (System.Collections.ArrayList[]) encSpec.pss.getDefault(); + v = (System.Collections.Generic.List[])encSpec.pss.getDefault(); } else { - v = (System.Collections.ArrayList[]) encSpec.pss.getTileDef(tileIdx); + v = (System.Collections.Generic.List[])encSpec.pss.getTileDef(tileIdx); } for (int r = mrl; r >= 0; r--) { @@ -903,14 +903,14 @@ protected internal virtual void writeCOC(bool mh, int tileIdx, int compIdx) { // Write the precinct size for each resolution level + 1 // (resolution 0) if precinct partition is used. - System.Collections.ArrayList[] v = null; + System.Collections.Generic.List[] v = null; if (mh) { - v = (System.Collections.ArrayList[]) encSpec.pss.getCompDef(compIdx); + v = (System.Collections.Generic.List[])encSpec.pss.getCompDef(compIdx); } else { - v = (System.Collections.ArrayList[]) encSpec.pss.getTileCompVal(tileIdx, compIdx); + v = (System.Collections.Generic.List[])encSpec.pss.getTileCompVal(tileIdx, compIdx); } for (int r = mrl; r >= 0; r--) { @@ -983,7 +983,7 @@ protected internal virtual void writeMainQCD() } if (notFound) { - throw new System.ApplicationException("Default representative for quantization type " + " and number of decomposition levels not found " + " in main QCD marker segment. " + "You have found a JJ2000 bug."); + throw new System.InvalidOperationException("Default representative for quantization type " + " and number of decomposition levels not found " + " in main QCD marker segment. " + "You have found a JJ2000 bug."); } SubbandAn sb, csb, sbRoot = dwt.getAnSubbandTree(tcIdx[0], tcIdx[1]); defimgn = dwt.getNomRangeBits(tcIdx[1]); @@ -1029,7 +1029,7 @@ protected internal virtual void writeMainQCD() break; default: - throw new System.ApplicationException("Internal JJ2000 error"); + throw new System.InvalidOperationException("Internal JJ2000 error"); } @@ -1104,7 +1104,7 @@ protected internal virtual void writeMainQCD() break; default: - throw new System.ApplicationException("Internal JJ2000 error"); + throw new System.InvalidOperationException("Internal JJ2000 error"); } } @@ -1160,7 +1160,7 @@ protected internal virtual void writeMainQCC(int compIdx) } if (notFound) { - throw new System.ApplicationException("Default representative for quantization type " + " and number of decomposition levels not found " + " in main QCC (c=" + compIdx + ") marker segment. " + "You have found a JJ2000 bug."); + throw new System.InvalidOperationException("Default representative for quantization type " + " and number of decomposition levels not found " + " in main QCC (c=" + compIdx + ") marker segment. " + "You have found a JJ2000 bug."); } sbRoot = dwt.getAnSubbandTree(tIdx, compIdx); @@ -1223,7 +1223,7 @@ protected internal virtual void writeMainQCC(int compIdx) break; default: - throw new System.ApplicationException("Internal JJ2000 error"); + throw new System.InvalidOperationException("Internal JJ2000 error"); } @@ -1309,7 +1309,7 @@ protected internal virtual void writeMainQCC(int compIdx) break; default: - throw new System.ApplicationException("Internal JJ2000 error"); + throw new System.InvalidOperationException("Internal JJ2000 error"); } } @@ -1354,7 +1354,7 @@ protected internal virtual void writeTileQCD(int tIdx) } if (notFound) { - throw new System.ApplicationException("Default representative for quantization type " + " and number of decomposition levels not found " + " in tile QCD (t=" + tIdx + ") marker segment. " + "You have found a JJ2000 bug."); + throw new System.InvalidOperationException("Default representative for quantization type " + " and number of decomposition levels not found " + " in tile QCD (t=" + tIdx + ") marker segment. " + "You have found a JJ2000 bug."); } sbRoot = dwt.getAnSubbandTree(tIdx, compIdx); @@ -1405,7 +1405,7 @@ protected internal virtual void writeTileQCD(int tIdx) break; default: - throw new System.ApplicationException("Internal JJ2000 error"); + throw new System.InvalidOperationException("Internal JJ2000 error"); } @@ -1480,7 +1480,7 @@ protected internal virtual void writeTileQCD(int tIdx) break; default: - throw new System.ApplicationException("Internal JJ2000 error"); + throw new System.InvalidOperationException("Internal JJ2000 error"); } } @@ -1576,7 +1576,7 @@ protected internal virtual void writeTileQCC(int t, int compIdx) break; default: - throw new System.ApplicationException("Internal JJ2000 error"); + throw new System.InvalidOperationException("Internal JJ2000 error"); } @@ -1662,7 +1662,7 @@ protected internal virtual void writeTileQCC(int t, int compIdx) break; default: - throw new System.ApplicationException("Internal JJ2000 error"); + throw new System.InvalidOperationException("Internal JJ2000 error"); } } @@ -1845,7 +1845,7 @@ private void writeCOM() // Rcom hbuf.Write((System.Int16) 1); // General use (IS 8859-15:1999(Latin) values) - byte[] chars = System.Text.ASCIIEncoding.ASCII.GetBytes(str); + byte[] chars = System.Text.Encoding.UTF8.GetBytes(str); for (int i = 0; i < chars.Length; i++) { hbuf.Write((byte) chars[i]); @@ -1871,7 +1871,7 @@ private void writeCOM() hbuf.Write((System.Int16) 1); // General use (IS 8859-15:1999(Latin) // values) - byte[] chars = System.Text.ASCIIEncoding.ASCII.GetBytes(str); + byte[] chars = System.Text.Encoding.UTF8.GetBytes(str); for (int i = 0; i < chars.Length; i++) { hbuf.Write((byte) chars[i]); diff --git a/CSJ2K/j2k/codestream/writer/PktEncoder.cs b/CSJ2K/j2k/codestream/writer/PktEncoder.cs index 3861977e..b6827f10 100644 --- a/CSJ2K/j2k/codestream/writer/PktEncoder.cs +++ b/CSJ2K/j2k/codestream/writer/PktEncoder.cs @@ -1287,7 +1287,7 @@ public virtual BitOutputBuffer encodePacket(int ly, int c, int r, int t, CBlkRat // Must never happen if (hbuf.Length == 0) { - throw new System.ApplicationException("You have found a bug in PktEncoder, method:" + " encodePacket"); + throw new System.InvalidOperationException("You have found a bug in PktEncoder, method:" + " encodePacket"); } return hbuf; diff --git a/CSJ2K/j2k/decoder/DecoderSpecs.cs b/CSJ2K/j2k/decoder/DecoderSpecs.cs index 707cb183..b8f191ba 100644 --- a/CSJ2K/j2k/decoder/DecoderSpecs.cs +++ b/CSJ2K/j2k/decoder/DecoderSpecs.cs @@ -62,7 +62,7 @@ namespace CSJ2K.j2k.decoder /// /// /// - public class DecoderSpecs : System.ICloneable + public class DecoderSpecs { /// Returns a copy of the current object. /// @@ -77,9 +77,9 @@ virtual public DecoderSpecs Copy decSpec2 = (DecoderSpecs) this.Clone(); } //UPGRADE_NOTE: Exception 'java.lang.CloneNotSupportedException' was converted to 'System.Exception' which has different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1100'" - catch (System.Exception) + catch (System.Exception e) { - throw new System.ApplicationException("Cannot clone the DecoderSpecs instance"); + throw new System.InvalidOperationException("Cannot clone the DecoderSpecs instance"); } // Quantization decSpec2.qts = (QuantTypeSpec) qts.Copy; diff --git a/CSJ2K/j2k/entropy/CBlkSizeSpec.cs b/CSJ2K/j2k/entropy/CBlkSizeSpec.cs index fd2cd3e2..a4c32840 100644 --- a/CSJ2K/j2k/entropy/CBlkSizeSpec.cs +++ b/CSJ2K/j2k/entropy/CBlkSizeSpec.cs @@ -208,7 +208,7 @@ public CBlkSizeSpec(int nt, int nc, byte type, ParameterList pl):base(nt, nc, ty throw new System.ArgumentException(errMsg); } } - catch (System.FormatException) + catch (System.FormatException e) { errMsg = "'" + optName + "' option : the code-block's " + "width could not be parsed."; throw new System.ArgumentException(errMsg); @@ -218,7 +218,7 @@ public CBlkSizeSpec(int nt, int nc, byte type, ParameterList pl):base(nt, nc, ty { word = stk.NextToken(); } - catch (System.ArgumentOutOfRangeException) + catch (System.ArgumentOutOfRangeException e) { errMsg = "'" + optName + "' option : could not parse the " + "code-block's height"; throw new System.ArgumentException(errMsg); @@ -255,7 +255,7 @@ public CBlkSizeSpec(int nt, int nc, byte type, ParameterList pl):base(nt, nc, ty throw new System.ArgumentException(errMsg); } } - catch (System.FormatException) + catch (System.FormatException e) { errMsg = "'" + optName + "' option : the code-block's height " + "could not be parsed."; throw new System.ArgumentException(errMsg); diff --git a/CSJ2K/j2k/entropy/PrecinctSizeSpec.cs b/CSJ2K/j2k/entropy/PrecinctSizeSpec.cs index 4ecfe182..01202e0d 100644 --- a/CSJ2K/j2k/entropy/PrecinctSizeSpec.cs +++ b/CSJ2K/j2k/entropy/PrecinctSizeSpec.cs @@ -41,6 +41,7 @@ * Copyright (c) 1999/2000 JJ2000 Partners. * */ using System; +using System.Collections.Generic; using CSJ2K.j2k.codestream; using CSJ2K.j2k.wavelet; using CSJ2K.j2k.image; @@ -137,10 +138,10 @@ public PrecinctSizeSpec(int nt, int nc, byte type, BlkImgDataSrc imgsrc, Integer // Set precinct sizes to default i.e. 2^15 = // Markers.PRECINCT_PARTITION_DEF_SIZE - System.Collections.ArrayList[] tmpv = new System.Collections.ArrayList[2]; - tmpv[0] = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10)); // ppx + System.Collections.Generic.List[] tmpv = new List[2]; + tmpv[0] = new List(10); // ppx tmpv[0].Add((System.Int32) CSJ2K.j2k.codestream.Markers.PRECINCT_PARTITION_DEF_SIZE); - tmpv[1] = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10)); // ppy + tmpv[1] = new List(10); // ppy tmpv[1].Add((System.Int32) CSJ2K.j2k.codestream.Markers.PRECINCT_PARTITION_DEF_SIZE); setDefault(tmpv); @@ -167,7 +168,7 @@ public PrecinctSizeSpec(int nt, int nc, byte type, BlkImgDataSrc imgsrc, Integer while ((stk.HasMoreTokens() || wasReadingPrecinctSize) && !endOfParamList) { - System.Collections.ArrayList[] v = new System.Collections.ArrayList[2]; // v[0] : ppx, v[1] : ppy + System.Collections.Generic.List[] v = new List[2]; // v[0] : ppx, v[1] : ppy // We do not read the next token if we were reading a precinct's // size argument as we have already read the next token into word. @@ -216,8 +217,8 @@ public PrecinctSizeSpec(int nt, int nc, byte type, BlkImgDataSrc imgsrc, Integer } // Initialises Vector objects - v[0] = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10)); // ppx - v[1] = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10)); // ppy + v[0] = new List(10); // ppx + v[1] = new List(10); // ppy while (true) { @@ -233,7 +234,7 @@ public PrecinctSizeSpec(int nt, int nc, byte type, BlkImgDataSrc imgsrc, Integer { word = stk.NextToken(); } - catch (System.ArgumentOutOfRangeException) + catch (System.ArgumentOutOfRangeException e) { errMsg = "'" + optName + "' option : could not " + "parse the precinct's width"; throw new System.ArgumentException(errMsg); @@ -246,7 +247,7 @@ public PrecinctSizeSpec(int nt, int nc, byte type, BlkImgDataSrc imgsrc, Integer throw new System.ArgumentException(errMsg); } } - catch (System.FormatException) + catch (System.FormatException e) { errMsg = "'" + optName + "' option : the argument '" + word + "' could not be parsed."; throw new System.ArgumentException(errMsg); @@ -393,7 +394,7 @@ public PrecinctSizeSpec(int nt, int nc, byte type, BlkImgDataSrc imgsrc, Integer public virtual int getPPX(int t, int c, int rl) { int mrl, idx; - System.Collections.ArrayList[] v = null; + System.Collections.Generic.List[] v = null; bool tileSpecified = (t != - 1?true:false); bool compSpecified = (c != - 1?true:false); @@ -403,22 +404,22 @@ public virtual int getPPX(int t, int c, int rl) if (tileSpecified && compSpecified) { mrl = ((System.Int32) dls.getTileCompVal(t, c)); - v = (System.Collections.ArrayList[]) getTileCompVal(t, c); + v = (System.Collections.Generic.List[])getTileCompVal(t, c); } else if (tileSpecified && !compSpecified) { mrl = ((System.Int32) dls.getTileDef(t)); - v = (System.Collections.ArrayList[]) getTileDef(t); + v = (System.Collections.Generic.List[])getTileDef(t); } else if (!tileSpecified && compSpecified) { mrl = ((System.Int32) dls.getCompDef(c)); - v = (System.Collections.ArrayList[]) getCompDef(c); + v = (System.Collections.Generic.List[])getCompDef(c); } else { mrl = ((System.Int32) dls.getDefault()); - v = (System.Collections.ArrayList[]) getDefault(); + v = (System.Collections.Generic.List[])getDefault(); } idx = mrl - rl; if (v[0].Count > idx) @@ -455,7 +456,7 @@ public virtual int getPPX(int t, int c, int rl) public virtual int getPPY(int t, int c, int rl) { int mrl, idx; - System.Collections.ArrayList[] v = null; + System.Collections.Generic.List[] v = null; bool tileSpecified = (t != - 1?true:false); bool compSpecified = (c != - 1?true:false); @@ -465,22 +466,22 @@ public virtual int getPPY(int t, int c, int rl) if (tileSpecified && compSpecified) { mrl = ((System.Int32) dls.getTileCompVal(t, c)); - v = (System.Collections.ArrayList[]) getTileCompVal(t, c); + v = (System.Collections.Generic.List[]) getTileCompVal(t, c); } else if (tileSpecified && !compSpecified) { mrl = ((System.Int32) dls.getTileDef(t)); - v = (System.Collections.ArrayList[]) getTileDef(t); + v = (System.Collections.Generic.List[]) getTileDef(t); } else if (!tileSpecified && compSpecified) { mrl = ((System.Int32) dls.getCompDef(c)); - v = (System.Collections.ArrayList[]) getCompDef(c); + v = (System.Collections.Generic.List[]) getCompDef(c); } else { mrl = ((System.Int32) dls.getDefault()); - v = (System.Collections.ArrayList[]) getDefault(); + v = (System.Collections.Generic.List[]) getDefault(); } idx = mrl - rl; if (v[1].Count > idx) diff --git a/CSJ2K/j2k/entropy/Progression.cs b/CSJ2K/j2k/entropy/Progression.cs index 1853a1cd..45d0c265 100644 --- a/CSJ2K/j2k/entropy/Progression.cs +++ b/CSJ2K/j2k/entropy/Progression.cs @@ -142,7 +142,7 @@ public override System.String ToString() break; default: - throw new System.ApplicationException("Unknown progression type"); + throw new System.InvalidOperationException("Unknown progression type"); } str += ("comp.: " + cs + "-" + ce + ", "); diff --git a/CSJ2K/j2k/entropy/ProgressionSpec.cs b/CSJ2K/j2k/entropy/ProgressionSpec.cs index b6bb4368..72436765 100644 --- a/CSJ2K/j2k/entropy/ProgressionSpec.cs +++ b/CSJ2K/j2k/entropy/ProgressionSpec.cs @@ -40,6 +40,7 @@ * Copyright (c) 1999/2000 JJ2000 Partners. * */ using System; +using System.Collections.Generic; using CSJ2K.j2k.codestream; using CSJ2K.j2k.wavelet; using CSJ2K.j2k.image; @@ -78,7 +79,7 @@ public ProgressionSpec(int nt, int nc, byte type):base(nt, nc, type) { if (type != ModuleSpec.SPEC_TYPE_TILE) { - throw new System.ApplicationException("Illegal use of class ProgressionSpec !"); + throw new System.InvalidOperationException("Illegal use of class ProgressionSpec !"); } } @@ -146,7 +147,7 @@ public ProgressionSpec(int nt, int nc, int nl, IntegerSpec dls, byte type, Param // resolution level, 1= index of first component, 2=index of first // layer not included, 3= index of first resolution level not // included, 4= index of first component not included - System.Collections.ArrayList progression = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10)); + System.Collections.Generic.List progression = new List(10); int tmp = 0; Progression curProg = null; @@ -200,7 +201,7 @@ public ProgressionSpec(int nt, int nc, int nl, IntegerSpec dls, byte type, Param { tmp = (System.Int32.Parse(word)); } - catch (System.FormatException) + catch (System.FormatException e) { // Progression has missing parameters throw new System.ArgumentException("Progression " + "order" + " specification " + "has missing " + "parameters: " + param); @@ -263,7 +264,7 @@ public ProgressionSpec(int nt, int nc, int nl, IntegerSpec dls, byte type, Param } else { - throw new System.ApplicationException("Error in usage of 'Aptype' " + "option: " + param); + throw new System.InvalidOperationException("Error in usage of 'Aptype' " + "option: " + param); } } diff --git a/CSJ2K/j2k/entropy/decoder/StdEntropyDecoder.cs b/CSJ2K/j2k/entropy/decoder/StdEntropyDecoder.cs index 86db191d..5ce7ad37 100644 --- a/CSJ2K/j2k/entropy/decoder/StdEntropyDecoder.cs +++ b/CSJ2K/j2k/entropy/decoder/StdEntropyDecoder.cs @@ -681,7 +681,7 @@ public override DataBlk getCodeBlock(int c, int m, int n, SubbandSyn sb, DataBlk break; default: - throw new System.ApplicationException("JJ2000 internal error"); + throw new System.InvalidOperationException("JJ2000 internal error"); } diff --git a/CSJ2K/j2k/entropy/encoder/EBCOTRateAllocator.cs b/CSJ2K/j2k/entropy/encoder/EBCOTRateAllocator.cs index e29cd506..43e36498 100644 --- a/CSJ2K/j2k/entropy/encoder/EBCOTRateAllocator.cs +++ b/CSJ2K/j2k/entropy/encoder/EBCOTRateAllocator.cs @@ -670,7 +670,7 @@ public override void initialize() } if (nValidProg == 0) { - throw new System.ApplicationException("Unable to initialize rate allocator: No " + "default progression type has been defined."); + throw new System.InvalidOperationException("Unable to initialize rate allocator: No " + "default progression type has been defined."); } // Tile specific values @@ -689,7 +689,7 @@ public override void initialize() } if (nValidProg == 0) { - throw new System.ApplicationException("Unable to initialize rate allocator:" + " No default progression type has been " + "defined for tile " + t); + throw new System.InvalidOperationException("Unable to initialize rate allocator:" + " No default progression type has been " + "defined for tile " + t); } } } // End loop on tiles @@ -731,15 +731,12 @@ private void getAllCodeBlocks() SubbandAn root, sb; int cblkToEncode = 0; - int nEncCblk = 0; - ProgressWatch pw = FacilityManager.ProgressWatch; //Get all coded code-blocks Goto first tile src.setTile(0, 0); for (t = 0; t < numTiles; t++) { //loop on tiles - nEncCblk = 0; cblkToEncode = 0; for (c = 0; c < numComps; c++) { @@ -766,10 +763,6 @@ private void getAllCodeBlocks() } } } - if (pw != null) - { - pw.initProgressWatch(0, cblkToEncode, "Encoding tile " + t + "..."); - } for (c = 0; c < numComps; c++) { @@ -781,13 +774,7 @@ private void getAllCodeBlocks() #if DO_TIMING stime = (System.DateTime.Now.Ticks - 621355968000000000) / 10000; #endif - - if (pw != null) - { - nEncCblk++; - pw.updateProgressWatch(nEncCblk, null); - } - + subb = ccb.sb; //Get the coded code-block resolution level index @@ -827,11 +814,6 @@ private void getAllCodeBlocks() } } - if (pw != null) - { - pw.terminateProgressWatch(); - } - //Goto next tile if (t < numTiles - 1) //not at last tile @@ -1015,7 +997,7 @@ private void buildAndWriteLayers() break; default: - throw new System.ApplicationException("Unsupported bit stream progression type"); + throw new System.InvalidOperationException("Unsupported bit stream progression type"); } // switch on progression @@ -1363,7 +1345,7 @@ public virtual void writePosCompResLy(int t, int rs, int re, int cs, int ce, in if (nPrec == 0) { - throw new System.ApplicationException("Image cannot have no precinct"); + throw new System.InvalidOperationException("Image cannot have no precinct"); } int pyend = (maxy - miny) / gcd_y + 1; @@ -1456,7 +1438,7 @@ public virtual void writePosCompResLy(int t, int rs, int re, int cs, int ce, in continue; if (nextPrec[c][r] < numPrec[t][c][r].x * numPrec[t][c][r].y - 1) { - throw new System.ApplicationException("JJ2000 bug: One precinct at least has " + "not been written for resolution level " + r + " of component " + c + " in tile " + t + "."); + throw new System.InvalidOperationException("JJ2000 bug: One precinct at least has " + "not been written for resolution level " + r + " of component " + c + " in tile " + t + "."); } } } @@ -1580,7 +1562,7 @@ public virtual void writeCompPosResLy(int t, int rs, int re, int cs, int ce, in if (nPrec == 0) { - throw new System.ApplicationException("Image cannot have no precinct"); + throw new System.InvalidOperationException("Image cannot have no precinct"); } int pyend = (maxy - miny) / gcd_y + 1; @@ -1676,7 +1658,7 @@ public virtual void writeCompPosResLy(int t, int rs, int re, int cs, int ce, in continue; if (nextPrec[c][r] < numPrec[t][c][r].x * numPrec[t][c][r].y - 1) { - throw new System.ApplicationException("JJ2000 bug: One precinct at least has " + "not been written for resolution level " + r + " of component " + c + " in tile " + t + "."); + throw new System.InvalidOperationException("JJ2000 bug: One precinct at least has " + "not been written for resolution level " + r + " of component " + c + " in tile " + t + "."); } } } @@ -1800,7 +1782,7 @@ public virtual void writeResPosCompLy(int t, int rs, int re, int cs, int ce, in if (nPrec == 0) { - throw new System.ApplicationException("Image cannot have no precinct"); + throw new System.InvalidOperationException("Image cannot have no precinct"); } int pyend = (maxy - miny) / gcd_y + 1; @@ -1893,7 +1875,7 @@ public virtual void writeResPosCompLy(int t, int rs, int re, int cs, int ce, in continue; if (nextPrec[c][r] < numPrec[t][c][r].x * numPrec[t][c][r].y - 1) { - throw new System.ApplicationException("JJ2000 bug: One precinct at least has " + "not been written for resolution level " + r + " of component " + c + " in tile " + t + "."); + throw new System.InvalidOperationException("JJ2000 bug: One precinct at least has " + "not been written for resolution level " + r + " of component " + c + " in tile " + t + "."); } } } diff --git a/CSJ2K/j2k/entropy/encoder/MQCoder.cs b/CSJ2K/j2k/entropy/encoder/MQCoder.cs index 520d87ce..63319c9e 100644 --- a/CSJ2K/j2k/entropy/encoder/MQCoder.cs +++ b/CSJ2K/j2k/entropy/encoder/MQCoder.cs @@ -295,7 +295,7 @@ virtual public int NumCodedBytes return nrOfWrittenBytes; default: - throw new System.ApplicationException("Illegal length calculation type code"); + throw new System.InvalidOperationException("Illegal length calculation type code"); } } @@ -1285,7 +1285,7 @@ public virtual int terminate() break; default: - throw new System.ApplicationException("Illegal termination type code"); + throw new System.InvalidOperationException("Illegal termination type code"); } diff --git a/CSJ2K/j2k/entropy/encoder/PostCompRateAllocator.cs b/CSJ2K/j2k/entropy/encoder/PostCompRateAllocator.cs index 51813164..6713af7c 100644 --- a/CSJ2K/j2k/entropy/encoder/PostCompRateAllocator.cs +++ b/CSJ2K/j2k/entropy/encoder/PostCompRateAllocator.cs @@ -262,9 +262,9 @@ private static LayersInfo parseAlayers(System.String params_Renamed, float rate) { stok.NextToken(); } - catch (System.IO.IOException) + catch (System.IO.IOException e) { - throw new System.ApplicationException("An IOException has ocurred where it " + "should never occur"); + throw new System.InvalidOperationException("An IOException has ocurred where it " + "should never occur"); } ratepending = false; islayer = false; @@ -327,9 +327,9 @@ private static LayersInfo parseAlayers(System.String params_Renamed, float rate) { stok.NextToken(); } - catch (System.IO.IOException) + catch (System.IO.IOException e) { - throw new System.ApplicationException("An IOException has ocurred where it " + "should never occur"); + throw new System.InvalidOperationException("An IOException has ocurred where it " + "should never occur"); } if (stok.ttype != SupportClass.StreamTokenizerSupport.TT_EOF) { @@ -345,9 +345,9 @@ private static LayersInfo parseAlayers(System.String params_Renamed, float rate) { stok.NextToken(); } - catch (System.IO.IOException) + catch (System.IO.IOException e) { - throw new System.ApplicationException("An IOException has ocurred where it " + "should never occur"); + throw new System.InvalidOperationException("An IOException has ocurred where it " + "should never occur"); } } if (islayer) diff --git a/CSJ2K/j2k/entropy/encoder/StdEntropyCoder.cs b/CSJ2K/j2k/entropy/encoder/StdEntropyCoder.cs index f396aaf6..f566bdca 100644 --- a/CSJ2K/j2k/entropy/encoder/StdEntropyCoder.cs +++ b/CSJ2K/j2k/entropy/encoder/StdEntropyCoder.cs @@ -40,17 +40,14 @@ * * Copyright (c) 1999/2000 JJ2000 Partners. * */ -using System; +#define DO_TIMING + using CSJ2K.j2k.quantization.quantizer; using CSJ2K.j2k.wavelet.analysis; -using CSJ2K.j2k.codestream; using CSJ2K.j2k.wavelet; -using CSJ2K.j2k.encoder; -using CSJ2K.j2k.entropy; using CSJ2K.j2k.image; using CSJ2K.j2k.util; -using CSJ2K.j2k.io; -using CSJ2K.j2k; + namespace CSJ2K.j2k.entropy.encoder { @@ -113,53 +110,14 @@ namespace CSJ2K.j2k.entropy.encoder /// public class StdEntropyCoder:EntropyCoder { - - /// Whether to collect timing information or not: false. Used as a compile - /// time directive. - /// - private const bool DO_TIMING = false; - +#if DO_TIMING /// The cumulative wall time for the entropy coding engine, for each /// component. In the single-threaded implementation it is the total time, /// in the multi-threaded implementation it is the time spent managing the /// compressor threads only. /// - //private long[] time; - - /// The Java system property name for the number of threads to use: - /// jj2000.j2k.entropy.encoder.StdEntropyCoder.nthreads - /// - public const System.String THREADS_PROP_NAME = "jj2000.j2k.entropy.encoder.StdEntropyCoder.nthreads"; - - /// The default value for the property in THREADS_PROP_NAME: 0 - public const System.String DEF_THREADS_NUM = "0"; - - /// The increase in priority for the compressor threads, currently 3. The - /// compressor threads will have a priority of THREADS_PRIORITY_INC more - /// than the priority of the thread calling this class constructor. Used - /// only in the multi-threaded implementation. - /// - public const int THREADS_PRIORITY_INC = 0; - - /// The pool of threads, for the threaded implementation. It is null, if - /// non threaded implementation is used - /// - private ThreadPool tPool; - - /// The queue of idle compressors. Used in multithreaded - /// implementation only - /// - private System.Collections.ArrayList idleComps; - - /// The queue of completed compressors, for each component. Used - /// in multithreaded implementation only. - /// - private System.Collections.ArrayList[] completedComps; - - /// The number of busy compressors, for each component. Used in - /// multithreaded implementation only. - /// - private int[] nBusyComps; + private long[] time; +#endif /// A flag indicating for each component if all the code-blocks of the * /// current tile have been returned. Used in multithreaded implementation @@ -555,8 +513,6 @@ public class StdEntropyCoder:EntropyCoder /// table is indexed with one less bit. /// private const int MSE_LKP_BITS = 7; - - private const int MSE_LKP_BITS_M1 = 6; /// The number of fractional bits used to store data in the 'fm' and 'fs' /// lookup tables. @@ -567,7 +523,7 @@ public class StdEntropyCoder:EntropyCoder /// (SC) primative, for lossy coding (i.e. normal). /// //UPGRADE_NOTE: Final was removed from the declaration of 'FS_LOSSY '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" - private static readonly int[] FS_LOSSY = new int[1 << MSE_LKP_BITS_M1]; + private static readonly int[] FS_LOSSY = new int[1 << (MSE_LKP_BITS - 1)]; /// Distortion estimation lookup table for bits coded using the /// magnitude-refinement (MR) primative, for lossy coding (i.e. normal) @@ -581,7 +537,7 @@ public class StdEntropyCoder:EntropyCoder /// distortion after the last bit-plane is coded is strictly 0. /// //UPGRADE_NOTE: Final was removed from the declaration of 'FS_LOSSLESS '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" - private static readonly int[] FS_LOSSLESS = new int[1 << MSE_LKP_BITS_M1]; + private static readonly int[] FS_LOSSLESS = new int[1 << (MSE_LKP_BITS - 1)]; /// Distortion estimation lookup table for bits coded using the /// magnitude-refinement (MR) primative, for lossless coding and last @@ -631,120 +587,6 @@ public class StdEntropyCoder:EntropyCoder /// private bool[][] precinctPartition; - //UPGRADE_NOTE: Field 'EnclosingInstance' was added to class 'Compressor' to access its enclosing instance. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1019'" - /// Class that takes care of running the 'compressCodeBlock()' method with - /// thread local arguments. Used only in multithreaded implementation. - /// - /// - private class Compressor : IThreadRunnable - { - private void InitBlock(StdEntropyCoder enclosingInstance) - { - this.enclosingInstance = enclosingInstance; - } - private StdEntropyCoder enclosingInstance; - /// Returns the index of this compressor. - /// - /// - /// The index of this compressor. - /// - /// - virtual public int Idx - { - get - { - return idx; - } - - } - public StdEntropyCoder Enclosing_Instance - { - get - { - return enclosingInstance; - } - - } - /// The index of this compressor. Used to access thread local - /// variables - /// - //UPGRADE_NOTE: Final was removed from the declaration of 'idx '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" - private int idx; - - /// The object where to store the compressed code-block - // Should be private, but some buggy JDK 1.1 compilers complain - internal CBlkRateDistStats ccb; - - /// The component on which to compress - // Should be private, but some buggy JDK 1.1 compilers complain - internal int c; - - /// The options bitmask to use in compression - // Should be private, but some buggy JDK 1.1 compilers complain - internal int options; - - /// The reversible flag to use in compression - // Should be private, but some buggy JDK 1.1 compilers complain - internal bool rev; - - /// The length calculation type to use in compression - // Should be private, but some buggy JDK 1.1 compilers complain - internal int lcType; - - /// The MQ termination type to use in compression - // Should be private, but some buggy JDK 1.1 compilers complain - internal int tType; - - /// The cumulative wall time for this compressor, for each - /// component. - /// - //private long[] time; - - /// Creates a new compressor object with the given index. - /// - /// - /// The index of this compressor. - /// - /// - internal Compressor(StdEntropyCoder enclosingInstance, int idx) - { - InitBlock(enclosingInstance); - this.idx = idx; -#if DO_TIMING - time = new long[Enclosing_Instance.src.NumComps]; -#endif - } - - /// Calls the 'compressCodeBlock()' method with thread local - /// arguments. Once completed it adds itself to the 'completedComps[c]' - /// stack, where 'c' is the component for which this compressor is - /// running. This last step occurs even if exceptions are thrown by the - /// 'compressCodeBlock()' method. - /// - /// - public virtual void Run() - { - // Start the code-block compression - try - { -#if DO_TIMING - long stime = 0L; - stime = (System.DateTime.Now.Ticks - 621355968000000000) / 10000; -#endif - CSJ2K.j2k.entropy.encoder.StdEntropyCoder.compressCodeBlock(c, ccb, Enclosing_Instance.srcblkT[idx], Enclosing_Instance.mqT[idx], Enclosing_Instance.boutT[idx], Enclosing_Instance.outT[idx], Enclosing_Instance.stateT[idx], Enclosing_Instance.distbufT[idx], Enclosing_Instance.ratebufT[idx], Enclosing_Instance.istermbufT[idx], Enclosing_Instance.symbufT[idx], Enclosing_Instance.ctxtbufT[idx], options, rev, lcType, tType); -#if DO_TIMING - time[c] += (System.DateTime.Now.Ticks - 621355968000000000) / 10000 - stime; -#endif - } - finally - { - // Join the queue of completed compression, even if exceptions - // occurred. - Enclosing_Instance.completedComps[c].Add(this); - } - } - } - /// Instantiates a new entropy coder engine, with the specified source of /// data, nominal block width and height. /// @@ -798,29 +640,12 @@ public StdEntropyCoder(CBlkQuantDataSrcEnc src, CBlkSizeSpec cblks, PrecinctSize this.tts = tts; int maxCBlkWidth, maxCBlkHeight; int i; // Counter - int nt; // The number of threads int tsl; // Size for thread structures // Get the biggest width/height for the code-blocks maxCBlkWidth = cblks.MaxCBlkWidth; maxCBlkHeight = cblks.MaxCBlkHeight; - nt = Environment.ProcessorCount; - /* - // Get the number of threads to use, or default to one - try - { - //UPGRADE_ISSUE: Method 'java.lang.System.getProperty' was not converted. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1000_javalangSystem'" - nt = System.Int32.Parse(System_Renamed.getProperty(THREADS_PROP_NAME, DEF_THREADS_NUM)); - if (nt < 0) - throw new System.FormatException(); - } - catch (System.FormatException e) - { - throw new System.ArgumentException("Invalid number of threads " + "for " + "entropy coding in property " + THREADS_PROP_NAME); - } - */ - // If we do timing create necessary structures #if DO_TIMING time = new long[src.NumComps]; @@ -828,35 +653,10 @@ public StdEntropyCoder(CBlkQuantDataSrcEnc src, CBlkSizeSpec cblks, PrecinctSize //UPGRADE_ISSUE: Method 'java.lang.System.runFinalizersOnExit' was not converted. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1000_javalangSystem'" // CONVERSION PROBLEM? //System_Renamed.runFinalizersOnExit(true); -#endif - // If using multithreaded implementation get necessasry objects - if (nt > 0) - { - FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.INFO, "Using multithreaded entropy coder " + "with " + nt + " compressor threads."); - tsl = nt; - tPool = new ThreadPool(nt, (System.Int32) SupportClass.ThreadClass.Current().Priority + THREADS_PRIORITY_INC, "StdEntropyCoder"); - idleComps = new System.Collections.ArrayList(); - completedComps = new System.Collections.ArrayList[src.NumComps]; - nBusyComps = new int[src.NumComps]; - finishedTileComponent = new bool[src.NumComps]; - for (i = src.NumComps - 1; i >= 0; i--) - { - completedComps[i] = new System.Collections.ArrayList(); - } - for (i = 0; i < nt; i++) - { - idleComps.Add(new StdEntropyCoder.Compressor(this, i)); - } - } - else - { - tsl = 1; - tPool = null; - idleComps = null; - completedComps = null; - nBusyComps = null; - finishedTileComponent = null; - } +#endif + + tsl = 1; + finishedTileComponent = null; // Allocate data structures outT = new ByteOutputBuffer[tsl]; @@ -934,57 +734,17 @@ public StdEntropyCoder(CBlkQuantDataSrcEnc src, CBlkSizeSpec cblks, PrecinctSize int c; System.Text.StringBuilder sb; - if (tPool == null) + // Single threaded implementation + sb = new System.Text.StringBuilder("StdEntropyCoder compression wall " + "clock time:"); + for (c = 0; c < time.Length; c++) { - // Single threaded implementation - sb = new System.Text.StringBuilder("StdEntropyCoder compression wall " + "clock time:"); - for (c = 0; c < time.Length; c++) - { - sb.Append("\n component "); - sb.Append(c); - sb.Append(": "); - sb.Append(time[c]); - sb.Append(" ms"); - } - FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.INFO, sb.ToString()); + sb.Append("\n component "); + sb.Append(c); + sb.Append(": "); + sb.Append(time[c]); + sb.Append(" ms"); } - else - { - // Multithreaded implementation - Compressor compr; - MsgLogger msglog = FacilityManager.getMsgLogger(); - - sb = new System.Text.StringBuilder("StdEntropyCoder manager thread " + "wall clock time:"); - for (c = 0; c < time.Length; c++) - { - sb.Append("\n component "); - sb.Append(c); - sb.Append(": "); - sb.Append(time[c]); - sb.Append(" ms"); - } - System.Collections.IEnumerator Enum = idleComps.GetEnumerator(); - sb.Append("\nStdEntropyCoder compressor threads wall clock " + "time:"); - //UPGRADE_TODO: Method 'java.util.Enumeration.hasMoreElements' was converted to 'System.Collections.IEnumerator.MoveNext' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationhasMoreElements'" - while (Enum.MoveNext()) - { - //UPGRADE_TODO: Method 'java.util.Enumeration.nextElement' was converted to 'System.Collections.IEnumerator.Current' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationnextElement'" - compr = (Compressor)(Enum.Current); - for (c = 0; c < time.Length; c++) - { - sb.Append("\n compressor "); - sb.Append(compr.Idx); - sb.Append(", component "); - sb.Append(c); - sb.Append(": "); - sb.Append(compr.getTiming(c)); - sb.Append(" ms"); - } - } - FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.INFO, sb.ToString()); - } - - //UPGRADE_NOTE: Call to 'super.finalize()' was removed. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1124'" + FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.INFO, sb.ToString()); } #endif @@ -1061,143 +821,38 @@ public override CBlkRateDistStats getNextCodeBlock(int c, CBlkRateDistStats ccb) #if DO_TIMING long stime = 0L; // Start time for timed sections #endif - if (tPool == null) - { - // Use single threaded implementation - // Get code-block data from source - srcblkT[0] = src.getNextInternCodeBlock(c, srcblkT[0]); + // Use single threaded implementation + // Get code-block data from source + srcblkT[0] = src.getNextInternCodeBlock(c, srcblkT[0]); #if DO_TIMING - stime = (System.DateTime.Now.Ticks - 621355968000000000) / 10000; + stime = (System.DateTime.Now.Ticks - 621355968000000000) / 10000; #endif - if (srcblkT[0] == null) - { - // We got all code-blocks - return null; - } - // Initialize thread local variables - if ((opts[tIdx][c] & CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_BYPASS) != 0 && boutT[0] == null) - { - boutT[0] = new BitToByteOutput(outT[0]); - } - // Initialize output code-block - if (ccb == null) - { - ccb = new CBlkRateDistStats(); - } - // Compress code-block - compressCodeBlock(c, ccb, srcblkT[0], mqT[0], boutT[0], outT[0], stateT[0], distbufT[0], ratebufT[0], istermbufT[0], symbufT[0], ctxtbufT[0], opts[tIdx][c], isReversible(tIdx, c), lenCalc[tIdx][c], tType[tIdx][c]); - -#if DO_TIMING - time[c] += (System.DateTime.Now.Ticks - 621355968000000000) / 10000 - stime; -#endif - - // Return result - return ccb; + if (srcblkT[0] == null) + { + // We got all code-blocks + return null; } - else + // Initialize thread local variables + if ((opts[tIdx][c] & CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_BYPASS) != 0 && boutT[0] == null) + { + boutT[0] = new BitToByteOutput(outT[0]); + } + // Initialize output code-block + if (ccb == null) { - // Use multiple threaded implementation - int cIdx; // Compressor idx - Compressor compr; // Compressor + ccb = new CBlkRateDistStats(); + } + // Compress code-block + compressCodeBlock(c, ccb, srcblkT[0], mqT[0], boutT[0], outT[0], stateT[0], distbufT[0], ratebufT[0], istermbufT[0], symbufT[0], ctxtbufT[0], opts[tIdx][c], isReversible(tIdx, c), lenCalc[tIdx][c], tType[tIdx][c]); #if DO_TIMING - stime = (System.DateTime.Now.Ticks - 621355968000000000) / 10000; -#endif - // Give data to all free compressors, using the current component - while (!finishedTileComponent[c] && !(idleComps.Count == 0)) - { - // Get an idle compressor - compr = (Compressor) SupportClass.StackSupport.Pop(idleComps); - cIdx = compr.Idx; - // Get data for the compressor and wake it up -#if DO_TIMING - time[c] += (System.DateTime.Now.Ticks - 621355968000000000) / 10000 - stime; + time[c] += (System.DateTime.Now.Ticks - 621355968000000000) / 10000 - stime; #endif - srcblkT[cIdx] = src.getNextInternCodeBlock(c, srcblkT[cIdx]); -#if DO_TIMING - stime = (System.DateTime.Now.Ticks - 621355968000000000) / 10000; -#endif - if (srcblkT[cIdx] != null) - { - // Initialize thread local variables - if ((opts[tIdx][c] & CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_BYPASS) != 0 && boutT[cIdx] == null) - { - boutT[cIdx] = new BitToByteOutput(outT[cIdx]); - } - // Initialize output code-block and compressor thread - if (ccb == null) - ccb = new CBlkRateDistStats(); - compr.ccb = ccb; - compr.c = c; - compr.options = opts[tIdx][c]; - compr.rev = isReversible(tIdx, c); - compr.lcType = lenCalc[tIdx][c]; - compr.tType = tType[tIdx][c]; - nBusyComps[c]++; - ccb = null; - // Send compressor to execution in thread pool - tPool.runTarget(compr, completedComps[c]); - } - else - { - // We finished with all the code-blocks in the current - // tile component - idleComps.Add(compr); - finishedTileComponent[c] = true; - } - } - // If there are threads for this component which result has not - // been returned yet, get it - if (nBusyComps[c] > 0) - { - lock (completedComps[c]) - { - // If no compressor is done, wait until one is - if ((completedComps[c].Count == 0)) - { - try - { -#if DO_TIMING - time[c] += (System.DateTime.Now.Ticks - 621355968000000000) / 10000 - stime; -#endif - System.Threading.Monitor.Wait(completedComps[c]); -#if DO_TIMING - stime = (System.DateTime.Now.Ticks - 621355968000000000) / 10000; -#endif - } - catch (System.Threading.ThreadInterruptedException) - { - } - } - // Remove the thread from the completed queue and put it - // on the idle queue - compr = (Compressor) SupportClass.StackSupport.Pop(completedComps[c]); - cIdx = compr.Idx; - nBusyComps[c]--; - idleComps.Add(compr); - // Check targets error condition - tPool.checkTargetErrors(); - // Get the result of compression and return that. -#if DO_TIMING - time[c] += (System.DateTime.Now.Ticks - 621355968000000000) / 10000 - stime; -#endif - return compr.ccb; - } - } - else - { - // Check targets error condition - tPool.checkTargetErrors(); - // Printing timing info if necessary -#if DO_TIMING - time[c] += (System.DateTime.Now.Ticks - 621355968000000000) / 10000 - stime; -#endif - // Nothing is running => no more code-blocks - return null; - } - } + + // Return result + return ccb; } /// Changes the current tile, given the new indexes. An @@ -1381,7 +1036,7 @@ static private void compressCodeBlock(int c, CBlkRateDistStats ccb, CBlkWTData break; default: - throw new System.ApplicationException("JJ2000 internal error"); + throw new System.InvalidOperationException("JJ2000 internal error"); } @@ -1641,7 +1296,7 @@ static private int sigProgPass(CBlkWTData srcblk, MQCoder mq, bool doterm, int b dist = 0; // We use the MSE_LKP_BITS-1 bits below the bit just coded for // distortion estimation. - shift = bp - MSE_LKP_BITS_M1; + shift = bp - (MSE_LKP_BITS - 1); upshift = (shift >= 0)?0:- shift; downshift = (shift <= 0)?0:shift; causal = (options & CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_VERT_STR_CAUSAL) != 0; @@ -1722,7 +1377,7 @@ static private int sigProgPass(CBlkWTData srcblk, MQCoder mq, bool doterm, int b } // Update distortion normval = (data[k] >> downshift) << upshift; - dist += fs[normval & ((1 << MSE_LKP_BITS_M1) - 1)]; + dist += fs[normval & ((1 << (MSE_LKP_BITS - 1)) - 1)]; } else { @@ -1771,7 +1426,7 @@ static private int sigProgPass(CBlkWTData srcblk, MQCoder mq, bool doterm, int b } // Update distortion normval = (data[k] >> downshift) << upshift; - dist += fs[normval & ((1 << MSE_LKP_BITS_M1) - 1)]; + dist += fs[normval & ((1 << (MSE_LKP_BITS - 1)) - 1)]; } else { @@ -1827,7 +1482,7 @@ static private int sigProgPass(CBlkWTData srcblk, MQCoder mq, bool doterm, int b } // Update distortion normval = (data[k] >> downshift) << upshift; - dist += fs[normval & ((1 << MSE_LKP_BITS_M1) - 1)]; + dist += fs[normval & ((1 << (MSE_LKP_BITS - 1)) - 1)]; } else { @@ -1876,7 +1531,7 @@ static private int sigProgPass(CBlkWTData srcblk, MQCoder mq, bool doterm, int b } // Update distortion normval = (data[k] >> downshift) << upshift; - dist += fs[normval & ((1 << MSE_LKP_BITS_M1) - 1)]; + dist += fs[normval & ((1 << (MSE_LKP_BITS - 1)) - 1)]; } else { @@ -2008,7 +1663,7 @@ static private int rawSigProgPass(CBlkWTData srcblk, BitToByteOutput bout, bool dist = 0; // We use the MSE_LKP_BITS-1 bits below the bit just coded for // distortion estimation. - shift = bp - MSE_LKP_BITS_M1; + shift = bp - (MSE_LKP_BITS - 1); upshift = (shift >= 0)?0:- shift; downshift = (shift <= 0)?0:shift; causal = (options & CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_VERT_STR_CAUSAL) != 0; @@ -2090,7 +1745,7 @@ static private int rawSigProgPass(CBlkWTData srcblk, BitToByteOutput bout, bool } // Update distortion normval = (data[k] >> downshift) << upshift; - dist += fs[normval & ((1 << MSE_LKP_BITS_M1) - 1)]; + dist += fs[normval & ((1 << (MSE_LKP_BITS - 1)) - 1)]; } else { @@ -2140,7 +1795,7 @@ static private int rawSigProgPass(CBlkWTData srcblk, BitToByteOutput bout, bool } // Update distortion normval = (data[k] >> downshift) << upshift; - dist += fs[normval & ((1 << MSE_LKP_BITS_M1) - 1)]; + dist += fs[normval & ((1 << (MSE_LKP_BITS - 1)) - 1)]; } else { @@ -2196,7 +1851,7 @@ static private int rawSigProgPass(CBlkWTData srcblk, BitToByteOutput bout, bool } // Update distortion normval = (data[k] >> downshift) << upshift; - dist += fs[normval & ((1 << MSE_LKP_BITS_M1) - 1)]; + dist += fs[normval & ((1 << (MSE_LKP_BITS - 1)) - 1)]; } else { @@ -2245,7 +1900,7 @@ static private int rawSigProgPass(CBlkWTData srcblk, BitToByteOutput bout, bool } // Update distortion normval = (data[k] >> downshift) << upshift; - dist += fs[normval & ((1 << MSE_LKP_BITS_M1) - 1)]; + dist += fs[normval & ((1 << (MSE_LKP_BITS - 1)) - 1)]; } else { @@ -2361,7 +2016,7 @@ static private int magRefPass(CBlkWTData srcblk, MQCoder mq, bool doterm, int bp dist = 0; // We use the bit just coded plus MSE_LKP_BITS-1 bits below the bit // just coded for distortion estimation. - shift = bp - MSE_LKP_BITS_M1; + shift = bp - (MSE_LKP_BITS - 1); upshift = (shift >= 0)?0:- shift; downshift = (shift <= 0)?0:shift; @@ -2580,7 +2235,7 @@ static private int rawMagRefPass(CBlkWTData srcblk, BitToByteOutput bout, bool d dist = 0; // We use the bit just coded plus MSE_LKP_BITS-1 bits below the bit // just coded for distortion estimation. - shift = bp - MSE_LKP_BITS_M1; + shift = bp - (MSE_LKP_BITS - 1); upshift = (shift >= 0)?0:- shift; downshift = (shift <= 0)?0:shift; @@ -2790,7 +2445,7 @@ static private int cleanuppass(CBlkWTData srcblk, MQCoder mq, bool doterm, int b dist = 0; // We use the MSE_LKP_BITS-1 bits below the bit just coded for // distortion estimation. - shift = bp - MSE_LKP_BITS_M1; + shift = bp - (MSE_LKP_BITS - 1); upshift = (shift >= 0)?0:- shift; downshift = (shift <= 0)?0:shift; causal = (options & CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_VERT_STR_CAUSAL) != 0; @@ -2861,7 +2516,7 @@ static private int cleanuppass(CBlkWTData srcblk, MQCoder mq, bool doterm, int b // Code sign of sample that became significant // Update distortion normval = (data[k] >> downshift) << upshift; - dist += fs[normval & ((1 << MSE_LKP_BITS_M1) - 1)]; + dist += fs[normval & ((1 << (MSE_LKP_BITS - 1)) - 1)]; // Apply sign coding sym = SupportClass.URShift(data[k], 31); if ((rlclen & 0x01) == 0) @@ -3021,7 +2676,7 @@ static private int cleanuppass(CBlkWTData srcblk, MQCoder mq, bool doterm, int b } // Update distortion normval = (data[k] >> downshift) << upshift; - dist += fs[normval & ((1 << MSE_LKP_BITS_M1) - 1)]; + dist += fs[normval & ((1 << (MSE_LKP_BITS - 1)) - 1)]; } } if (sheight < 2) @@ -3067,7 +2722,7 @@ static private int cleanuppass(CBlkWTData srcblk, MQCoder mq, bool doterm, int b } // Update distortion normval = (data[k] >> downshift) << upshift; - dist += fs[normval & ((1 << MSE_LKP_BITS_M1) - 1)]; + dist += fs[normval & ((1 << (MSE_LKP_BITS - 1)) - 1)]; } } } @@ -3125,7 +2780,7 @@ static private int cleanuppass(CBlkWTData srcblk, MQCoder mq, bool doterm, int b } // Update distortion normval = (data[k] >> downshift) << upshift; - dist += fs[normval & ((1 << MSE_LKP_BITS_M1) - 1)]; + dist += fs[normval & ((1 << (MSE_LKP_BITS - 1)) - 1)]; } } if (sheight < 4) @@ -3171,7 +2826,7 @@ static private int cleanuppass(CBlkWTData srcblk, MQCoder mq, bool doterm, int b } // Update distortion normval = (data[k] >> downshift) << upshift; - dist += fs[normval & ((1 << MSE_LKP_BITS_M1) - 1)]; + dist += fs[normval & ((1 << (MSE_LKP_BITS - 1)) - 1)]; } } } @@ -3699,10 +3354,10 @@ static StdEntropyCoder() // Initialize the distortion estimation lookup tables // fs tables - for (i = 0; i < (1 << MSE_LKP_BITS_M1); i++) + for (i = 0; i < (1 << (MSE_LKP_BITS - 1)); i++) { // In fs we index by val-1, since val is really: 1 <= val < 2 - val = (double) i / (1 << MSE_LKP_BITS_M1) + 1.0; + val = (double) i / (1 << (MSE_LKP_BITS - 1)) + 1.0; deltaMSE = val * val; //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'" FS_LOSSLESS[i] = (int) System.Math.Floor(deltaMSE * ((double) (1 << MSE_LKP_FRAC_BITS)) + 0.5); @@ -3715,11 +3370,11 @@ static StdEntropyCoder() // fm tables for (i = 0; i < (1 << MSE_LKP_BITS); i++) { - val = (double) i / (1 << MSE_LKP_BITS_M1); + val = (double) i / (1 << (MSE_LKP_BITS - 1)); deltaMSE = (val - 1.0) * (val - 1.0); //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'" FM_LOSSLESS[i] = (int) System.Math.Floor(deltaMSE * ((double) (1 << MSE_LKP_FRAC_BITS)) + 0.5); - val -= ((i < (1 << MSE_LKP_BITS_M1))?0.5:1.5); + val -= ((i < (1 << (MSE_LKP_BITS - 1)))?0.5:1.5); deltaMSE -= val * val; //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'" FM_LOSSY[i] = (int) System.Math.Floor(deltaMSE * ((double) (1 << MSE_LKP_FRAC_BITS)) + 0.5); diff --git a/CSJ2K/j2k/fileformat/reader/FileFormatReader.cs b/CSJ2K/j2k/fileformat/reader/FileFormatReader.cs index 4fc488cf..620bd91f 100644 --- a/CSJ2K/j2k/fileformat/reader/FileFormatReader.cs +++ b/CSJ2K/j2k/fileformat/reader/FileFormatReader.cs @@ -41,6 +41,7 @@ * Copyright (c) 1999/2000 JJ2000 Partners. * */ using System; +using System.Collections.Generic; using CSJ2K.j2k.codestream; using CSJ2K.j2k.fileformat; using CSJ2K.j2k.util; @@ -113,10 +114,10 @@ virtual public int FirstCodeStreamLength private RandomAccessIO in_Renamed; /// The positions of the codestreams in the fileformat - private System.Collections.ArrayList codeStreamPos; + private System.Collections.Generic.List codeStreamPos; /// The lengths of the codestreams in the fileformat - private System.Collections.ArrayList codeStreamLength; + private System.Collections.Generic.List codeStreamLength; /// Flag indicating whether or not the JP2 file format is used public bool JP2FFUsed; @@ -174,7 +175,7 @@ public virtual void readFileFormat() marker = (short) in_Renamed.readShort(); if (marker != CSJ2K.j2k.codestream.Markers.SOC) //Standard syntax marker found - throw new System.ApplicationException("File is neither valid JP2 file nor " + "valid JPEG 2000 codestream"); + throw new System.InvalidOperationException("File is neither valid JP2 file nor " + "valid JPEG 2000 codestream"); JP2FFUsed = false; in_Renamed.seek(0); return ; @@ -187,7 +188,7 @@ public virtual void readFileFormat() if (!readFileTypeBox()) { // Not a valid JP2 file or codestream - throw new System.ApplicationException("Invalid JP2 file: File Type box missing"); + throw new System.InvalidOperationException("Invalid JP2 file: File Type box missing"); } // Read all remaining boxes @@ -218,14 +219,14 @@ public virtual void readFileFormat() case CSJ2K.j2k.fileformat.FileFormatBoxes.CONTIGUOUS_CODESTREAM_BOX: if (!jp2HeaderBoxFound) { - throw new System.ApplicationException("Invalid JP2 file: JP2Header box not " + "found before Contiguous codestream " + "box "); + throw new System.InvalidOperationException("Invalid JP2 file: JP2Header box not " + "found before Contiguous codestream " + "box "); } readContiguousCodeStreamBox(pos, length, longLength); break; case CSJ2K.j2k.fileformat.FileFormatBoxes.JP2_HEADER_BOX: if (jp2HeaderBoxFound) - throw new System.ApplicationException("Invalid JP2 file: Multiple " + "JP2Header boxes found"); + throw new System.InvalidOperationException("Invalid JP2 file: Multiple " + "JP2Header boxes found"); readJP2HeaderBox(pos, length, longLength); jp2HeaderBoxFound = true; break; @@ -259,15 +260,15 @@ public virtual void readFileFormat() in_Renamed.seek(pos + length); } } - catch (System.IO.EndOfStreamException) + catch (System.IO.EndOfStreamException e) { - throw new System.ApplicationException("EOF reached before finding Contiguous " + "Codestream Box"); + throw new System.InvalidOperationException("EOF reached before finding Contiguous " + "Codestream Box"); } if (codeStreamPos.Count == 0) { // Not a valid JP2 file or codestream - throw new System.ApplicationException("Invalid JP2 file: Contiguous codestream box " + "missing"); + throw new System.InvalidOperationException("Invalid JP2 file: Contiguous codestream box " + "missing"); } return ; @@ -300,7 +301,7 @@ public virtual bool readFileTypeBox() if (length == 0) { // This can not be last box - throw new System.ApplicationException("Zero-length of Profile Box"); + throw new System.InvalidOperationException("Zero-length of Profile Box"); } // Check that this is a File Type box (TBox) @@ -367,7 +368,7 @@ public virtual bool readJP2HeaderBox(long pos, int length, long longLength) if (length == 0) { // This can not be last box - throw new System.ApplicationException("Zero-length of JP2Header Box"); + throw new System.InvalidOperationException("Zero-length of JP2Header Box"); } // Here the JP2Header data (DBox) would be read if we were to use it @@ -405,12 +406,12 @@ public virtual bool readContiguousCodeStreamBox(long pos, int length, long longL int ccpos = in_Renamed.Pos; if (codeStreamPos == null) - codeStreamPos = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10)); + codeStreamPos = new List(10); codeStreamPos.Add((System.Int32) ccpos); // Add new codestream length to length vector if (codeStreamLength == null) - codeStreamLength = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10)); + codeStreamLength = new List(10); codeStreamLength.Add((System.Int32) length); return true; diff --git a/CSJ2K/j2k/fileformat/writer/FileFormatWriter.cs b/CSJ2K/j2k/fileformat/writer/FileFormatWriter.cs index 21d48d79..283daa37 100644 --- a/CSJ2K/j2k/fileformat/writer/FileFormatWriter.cs +++ b/CSJ2K/j2k/fileformat/writer/FileFormatWriter.cs @@ -46,7 +46,8 @@ using CSJ2K.j2k.io; namespace CSJ2K.j2k.fileformat.writer { - + using System.IO; + /// This class writes the file format wrapper that may or may not exist around /// a valid JPEG 2000 codestream. This class writes the simple possible legal /// fileformat @@ -61,28 +62,28 @@ public class FileFormatWriter /// The file from which to read the codestream and write file private BEBufferedRandomAccessFile fi; - /// The name of the file from which to read the codestream and to write + /// The stream from which to read the codestream and to write /// the JP2 file /// - private System.String filename; + private Stream stream; /// Image height - private int height; + private readonly int height; /// Image width - private int width; + private readonly int width; /// Number of components - private int nc; + private readonly int nc; /// Bits per component - private int[] bpc; + private readonly int[] bpc; /// Flag indicating whether number of bits per component varies - private bool bpcVaries; + private readonly bool bpcVaries; /// Length of codestream - private int clength; + private readonly int clength; /// Length of Colour Specification Box private const int CSB_LENGTH = 15; @@ -102,7 +103,7 @@ public class FileFormatWriter /// information necessary about a codestream to generate a legal JP2 file /// /// - /// The name of the file that is to be made a JP2 file + /// The stream that is to be made a JP2 file /// /// /// The height of the image @@ -120,13 +121,13 @@ public class FileFormatWriter /// Length of codestream /// /// - public FileFormatWriter(System.String filename, int height, int width, int nc, int[] bpc, int clength) + public FileFormatWriter(Stream stream, int height, int width, int nc, int[] bpc, int clength) { this.height = height; this.width = width; this.nc = nc; this.bpc = bpc; - this.filename = filename; + this.stream = stream; this.clength = clength; bpcVaries = false; @@ -157,7 +158,7 @@ public virtual int writeFileFormat() try { // Read and buffer the codestream - fi = new BEBufferedRandomAccessFile(filename, "rw+"); + fi = new BEBufferedRandomAccessFile(stream, false); codestream = new byte[clength]; fi.readFully(codestream, 0, clength); @@ -180,7 +181,7 @@ public virtual int writeFileFormat() } catch (System.Exception e) { - throw new System.ApplicationException("Error while writing JP2 file format(2): " + e.Message + "\n" + e.StackTrace); + throw new System.InvalidOperationException("Error while writing JP2 file format(2): " + e.Message + "\n" + e.StackTrace); } if (bpcVaries) return 12 + FTB_LENGTH + 8 + IHB_LENGTH + CSB_LENGTH + BPC_LENGTH + nc + 8; diff --git a/CSJ2K/j2k/image/BlkImgDataSrc.cs b/CSJ2K/j2k/image/BlkImgDataSrc.cs index 353249fe..09ea0b22 100644 --- a/CSJ2K/j2k/image/BlkImgDataSrc.cs +++ b/CSJ2K/j2k/image/BlkImgDataSrc.cs @@ -41,139 +41,160 @@ * Copyright (c) 1999/2000 JJ2000 Partners. * */ using System; + namespace CSJ2K.j2k.image { - - /// This interface defines the methods to transfer image data in blocks, - /// without following any particular order (random access). This interface does - /// not define the methods to access the image characteristics, such as width, - /// height, number of components, tiles, etc., or to change the current - /// tile. That is provided by other interfaces such as ImgData. - /// - ///

This interface has the notion of a current tile. All data, coordinates - /// and dimensions are always relative to the current tile. If there is only - /// one tile then it is equivalent as having no tiles. - /// - ///

A block of requested data may never cross tile boundaries. This should - /// be enforced by the implementing class, or the source of image data. - /// - ///

This interface defines the methods that can be used to retrieve image - /// data. Implementing classes need not buffer all the image data, they can ask - /// their source to load the data they need. - /// - ///

- /// - /// - /// - public interface BlkImgDataSrc:ImgData - { - - /// Returns the position of the fixed point in the specified component, or - /// equivalently the number of fractional bits. This is the position of the - /// least significant integral (i.e. non-fractional) bit, which is - /// equivalent to the number of fractional bits. For instance, for - /// fixed-point values with 2 fractional bits, 2 is returned. For - /// floating-point data this value does not apply and 0 should be - /// returned. Position 0 is the position of the least significant bit in - /// the data. - /// - /// - /// The index of the component. - /// - /// - /// The position of the fixed-point, which is the same as the - /// number of fractional bits. For floating-point data 0 is returned. - /// - /// - int getFixedPoint(int c); - - /// Returns, in the blk argument, a block of image data containing the - /// specifed rectangular area, in the specified component. The data is - /// returned, as a reference to the internal data, if any, instead of as a - /// copy, therefore the returned data should not be modified. - /// - ///

The rectangular area to return is specified by the 'ulx', 'uly', 'w' - /// and 'h' members of the 'blk' argument, relative to the current - /// tile. These members are not modified by this method. The 'offset' and - /// 'scanw' of the returned data can be arbitrary. See the 'DataBlk' class. - /// - ///

This method, in general, is more efficient than the 'getCompData()' - /// method since it may not copy the data. However if the array of returned - /// data is to be modified by the caller then the other method is probably - /// preferable. - /// - ///

If possible, the data in the returned 'DataBlk' should be the - /// internal data itself, instead of a copy, in order to increase the data - /// transfer efficiency. However, this depends on the particular - /// implementation (it may be more convenient to just return a copy of the - /// data). This is the reason why the returned data should not be modified. - /// - ///

If the data array in blk is null, then a new one - /// is created if necessary. The implementation of this interface may - /// choose to return the same array or a new one, depending on what is more - /// efficient. Therefore, the data array in blk prior to the - /// method call should not be considered to contain the returned data, a - /// new array may have been created. Instead, get the array from - /// blk after the method has returned. - /// - ///

The returned data may have its 'progressive' attribute set. In this - /// case the returned data is only an approximation of the "final" data. - /// - ///

- /// Its coordinates and dimensions specify the area to return, - /// relative to the current tile. Some fields in this object are modified - /// to return the data. - /// - /// - /// The index of the component from which to get the data. - /// - /// - /// The requested DataBlk - /// - /// - /// - /// - /// - DataBlk getInternCompData(DataBlk blk, int c); - - /// Returns, in the blk argument, a block of image data containing the - /// specifed rectangular area, in the specified component. The data is - /// returned, as a copy of the internal data, therefore the returned data - /// can be modified "in place". - /// - ///

The rectangular area to return is specified by the 'ulx', 'uly', 'w' - /// and 'h' members of the 'blk' argument, relative to the current - /// tile. These members are not modified by this method. The 'offset' of - /// the returned data is 0, and the 'scanw' is the same as the block's - /// width. See the 'DataBlk' class. - /// - ///

This method, in general, is less efficient than the - /// 'getInternCompData()' method since, in general, it copies the - /// data. However if the array of returned data is to be modified by the - /// caller then this method is preferable. - /// - ///

If the data array in 'blk' is 'null', then a new one is created. If - /// the data array is not 'null' then it is reused, and it must be large - /// enough to contain the block's data. Otherwise an 'ArrayStoreException' - /// or an 'IndexOutOfBoundsException' is thrown by the Java system. - /// - ///

The returned data may have its 'progressive' attribute set. In this - /// case the returned data is only an approximation of the "final" data. - /// - ///

- /// Its coordinates and dimensions specify the area to return, - /// relative to the current tile. If it contains a non-null data array, - /// then it must be large enough. If it contains a null data array a new - /// one is created. Some fields in this object are modified to return the - /// data. - /// - /// - /// The index of the component from which to get the data. - /// - /// - /// - /// - /// - DataBlk getCompData(DataBlk blk, int c); - } -} \ No newline at end of file + + /// This interface defines the methods to transfer image data in blocks, + /// without following any particular order (random access). This interface does + /// not define the methods to access the image characteristics, such as width, + /// height, number of components, tiles, etc., or to change the current + /// tile. That is provided by other interfaces such as ImgData. + /// + ///

This interface has the notion of a current tile. All data, coordinates + /// and dimensions are always relative to the current tile. If there is only + /// one tile then it is equivalent as having no tiles. + /// + ///

A block of requested data may never cross tile boundaries. This should + /// be enforced by the implementing class, or the source of image data. + /// + ///

This interface defines the methods that can be used to retrieve image + /// data. Implementing classes need not buffer all the image data, they can ask + /// their source to load the data they need. + /// + ///

+ /// + /// + /// + public interface BlkImgDataSrc : ImgData + { + + /// Returns the position of the fixed point in the specified component, or + /// equivalently the number of fractional bits. This is the position of the + /// least significant integral (i.e. non-fractional) bit, which is + /// equivalent to the number of fractional bits. For instance, for + /// fixed-point values with 2 fractional bits, 2 is returned. For + /// floating-point data this value does not apply and 0 should be + /// returned. Position 0 is the position of the least significant bit in + /// the data. + /// + /// + /// The index of the component. + /// + /// + /// The position of the fixed-point, which is the same as the + /// number of fractional bits. For floating-point data 0 is returned. + /// + /// + int getFixedPoint(int c); + + /// Returns, in the blk argument, a block of image data containing the + /// specifed rectangular area, in the specified component. The data is + /// returned, as a reference to the internal data, if any, instead of as a + /// copy, therefore the returned data should not be modified. + /// + ///

The rectangular area to return is specified by the 'ulx', 'uly', 'w' + /// and 'h' members of the 'blk' argument, relative to the current + /// tile. These members are not modified by this method. The 'offset' and + /// 'scanw' of the returned data can be arbitrary. See the 'DataBlk' class. + /// + ///

This method, in general, is more efficient than the 'getCompData()' + /// method since it may not copy the data. However if the array of returned + /// data is to be modified by the caller then the other method is probably + /// preferable. + /// + ///

If possible, the data in the returned 'DataBlk' should be the + /// internal data itself, instead of a copy, in order to increase the data + /// transfer efficiency. However, this depends on the particular + /// implementation (it may be more convenient to just return a copy of the + /// data). This is the reason why the returned data should not be modified. + /// + ///

If the data array in blk is null, then a new one + /// is created if necessary. The implementation of this interface may + /// choose to return the same array or a new one, depending on what is more + /// efficient. Therefore, the data array in blk prior to the + /// method call should not be considered to contain the returned data, a + /// new array may have been created. Instead, get the array from + /// blk after the method has returned. + /// + ///

The returned data may have its 'progressive' attribute set. In this + /// case the returned data is only an approximation of the "final" data. + /// + ///

+ /// Its coordinates and dimensions specify the area to return, + /// relative to the current tile. Some fields in this object are modified + /// to return the data. + /// + /// + /// The index of the component from which to get the data. + /// + /// + /// The requested DataBlk + /// + /// + /// + /// + /// + DataBlk getInternCompData(DataBlk blk, int c); + + /// Returns, in the blk argument, a block of image data containing the + /// specifed rectangular area, in the specified component. The data is + /// returned, as a copy of the internal data, therefore the returned data + /// can be modified "in place". + /// + ///

The rectangular area to return is specified by the 'ulx', 'uly', 'w' + /// and 'h' members of the 'blk' argument, relative to the current + /// tile. These members are not modified by this method. The 'offset' of + /// the returned data is 0, and the 'scanw' is the same as the block's + /// width. See the 'DataBlk' class. + /// + ///

This method, in general, is less efficient than the + /// 'getInternCompData()' method since, in general, it copies the + /// data. However if the array of returned data is to be modified by the + /// caller then this method is preferable. + /// + ///

If the data array in 'blk' is 'null', then a new one is created. If + /// the data array is not 'null' then it is reused, and it must be large + /// enough to contain the block's data. Otherwise an 'ArrayStoreException' + /// or an 'IndexOutOfBoundsException' is thrown by the Java system. + /// + ///

The returned data may have its 'progressive' attribute set. In this + /// case the returned data is only an approximation of the "final" data. + /// + ///

+ /// Its coordinates and dimensions specify the area to return, + /// relative to the current tile. If it contains a non-null data array, + /// then it must be large enough. If it contains a null data array a new + /// one is created. Some fields in this object are modified to return the + /// data. + /// + /// + /// The index of the component from which to get the data. + /// + /// + /// + /// + /// + DataBlk getCompData(DataBlk blk, int c); + + /// Closes the underlying file or network connection from where the + /// image data is being read. + /// + /// + /// If an I/O error occurs. + /// + void close(); + + /// Returns true if the data read was originally signed in the specified + /// component, false if not. + /// + /// + /// The index of the component, from 0 to C-1. + /// + /// + /// true if the data was originally signed, false if not. + /// + /// + bool isOrigSigned(int c); + } +} diff --git a/CSJ2K/j2k/image/ImgDataConverter.cs b/CSJ2K/j2k/image/ImgDataConverter.cs index 96c8a590..037ea5e4 100644 --- a/CSJ2K/j2k/image/ImgDataConverter.cs +++ b/CSJ2K/j2k/image/ImgDataConverter.cs @@ -44,380 +44,417 @@ using System; using CSJ2K.j2k.image; using CSJ2K.j2k; + namespace CSJ2K.j2k.image { - - /// This class is responsible of all data type conversions. It should be used, - /// at encoder side, between Tiler and ForwardWT modules and, at decoder side, - /// between InverseWT/CompDemixer and ImgWriter modules. The conversion is - /// realized when a block of data is requested: if source and destination data - /// type are the same one, it does nothing, else appropriate cast is done. All - /// the methods of the 'ImgData' interface are implemented by the - /// 'ImgDataAdapter' class that is the superclass of this one, so they don't - /// need to be reimplemented by subclasses. - /// - /// - public class ImgDataConverter:ImgDataAdapter, BlkImgDataSrc - { - - /// The block used to request data from the source in the case that a - /// conversion seems necessary. It can be either int or float at - /// initialization time. It will be checked (and corrected if necessary) by - /// the source whenever necessary - /// - private DataBlk srcBlk = new DataBlkInt(); - - /// The source of image data - private BlkImgDataSrc src; - - /// The number of fraction bits in the casted ints - private int fp; - - /// Constructs a new ImgDataConverter object that operates on the specified - /// source of image data. - /// - /// - /// The source from where to get the data to be transformed - /// - /// - /// The number of fraction bits in the casted ints - /// - /// - /// - /// - /// - public ImgDataConverter(BlkImgDataSrc imgSrc, int fp):base(imgSrc) - { - src = imgSrc; - this.fp = fp; - } - - /// Constructs a new ImgDataConverter object that operates on the specified - /// source of image data. - /// - /// - /// The source from where to get the data to be transformed - /// - /// - /// - /// - /// - public ImgDataConverter(BlkImgDataSrc imgSrc):base(imgSrc) - { - src = imgSrc; - fp = 0; - } - - /// Returns the position of the fixed point in the specified - /// component. This is the position of the least significant integral - /// (i.e. non-fractional) bit, which is equivalent to the number of - /// fractional bits. For instance, for fixed-point values with 2 fractional - /// bits, 2 is returned. For floating-point data this value does not apply - /// and 0 should be returned. Position 0 is the position of the least - /// significant bit in the data. - /// - /// - /// The index of the component. - /// - /// - /// The position of the fixed-point, which is the same as the - /// number of fractional bits. - /// - /// - public virtual int getFixedPoint(int c) - { - return fp; - } - - /// Returns, in the blk argument, a block of image data containing the - /// specifed rectangular area, in the specified component, using the - /// 'transfer type' specified in the block given as argument. The data is - /// returned, as a copy of the internal data, therefore the returned data - /// can be modified "in place". - /// - ///

The rectangular area to return is specified by the 'ulx', 'uly', 'w' - /// and 'h' members of the 'blk' argument, relative to the current - /// tile. These members are not modified by this method. The 'offset' of - /// the returned data is 0, and the 'scanw' is the same as the block's - /// width. See the 'DataBlk' class. - /// - ///

This method, in general, is less efficient than the - /// 'getInternCompData()' method since, in general, it copies the - /// data. However if the array of returned data is to be modified by the - /// caller then this method is preferable. - /// - ///

If the data array in 'blk' is 'null', then a new one is created. If - /// the data array is not 'null' then it is reused, and it must be large - /// enough to contain the block's data. Otherwise an 'ArrayStoreException' - /// or an 'IndexOutOfBoundsException' is thrown by the Java system. - /// - ///

The returned data may have its 'progressive' attribute set. In this - /// case the returned data is only an approximation of the "final" data. - /// - ///

- /// Its coordinates and dimensions specify the area to return, - /// relative to the current tile. If it contains a non-null data array, - /// then it must be large enough. If it contains a null data array a new - /// one is created. Some fields in this object are modified to return the - /// data. - /// - /// - /// The index of the component from which to get the data. - /// - /// - /// - /// - /// - public virtual DataBlk getCompData(DataBlk blk, int c) - { - return getData(blk, c, false); - } - - /// Returns, in the blk argument, a block of image data containing the - /// specifed rectangular area, in the specified component, using the - /// 'transfer type' defined in the block given as argument. The data is - /// returned, as a reference to the internal data, if any, instead of as a - /// copy, therefore the returned data should not be modified. - /// - ///

The rectangular area to return is specified by the 'ulx', 'uly', 'w' - /// and 'h' members of the 'blk' argument, relative to the current - /// tile. These members are not modified by this method. The 'offset' and - /// 'scanw' of the returned data can be arbitrary. See the 'DataBlk' class. - /// - ///

If source data and expected data (blk) are using the same type, - /// block returned without any modification. If not appropriate cast is - /// used. - /// - ///

This method, in general, is more efficient than the 'getCompData()' - /// method since it may not copy the data. However if the array of returned - /// data is to be modified by the caller then the other method is probably - /// preferable. - /// - ///

If the data array in blk is null, then a new one - /// is created if necessary. The implementation of this interface may - /// choose to return the same array or a new one, depending on what is more - /// efficient. Therefore, the data array in blk prior to the - /// method call should not be considered to contain the returned data, a - /// new array may have been created. Instead, get the array from - /// blk after the method has returned. - /// - ///

The returned data may have its 'progressive' attribute set. In this - /// case the returned data is only an approximation of the "final" data. - /// - ///

- /// Its coordinates and dimensions specify the area to return, - /// relative to the current tile. Some fields in this object are modified - /// to return the data. - /// - /// - /// The index of the component from which to get the data. - /// - /// - /// The requested DataBlk - /// - /// - /// - /// - /// - public DataBlk getInternCompData(DataBlk blk, int c) - { - return getData(blk, c, true); - } - - /// Implements the 'getInternCompData()' and the 'getCompData()' - /// methods. The 'intern' flag signals which of the two methods should run - /// as. - /// - /// - /// The data block to get. - /// - /// - /// The index of the component from which to get the data. - /// - /// - /// If true behave as 'getInternCompData(). Otherwise behave - /// as 'getCompData()' - /// - /// - /// The requested data block - /// - /// - /// - /// - /// - /// - /// - /// - private DataBlk getData(DataBlk blk, int c, bool intern) - { - DataBlk reqBlk; // Reference to block used in request to source - - // Keep request data type - int otype = blk.DataType; - - if (otype == srcBlk.DataType) - { - // Probably requested type is same as source type - reqBlk = blk; - } - else - { - // Probably requested type is not the same as source type - reqBlk = srcBlk; - // We need to copy requested coordinates and size - reqBlk.ulx = blk.ulx; - reqBlk.uly = blk.uly; - reqBlk.w = blk.w; - reqBlk.h = blk.h; - } - - // Get source data block - if (intern) - { - // We can use the intern variant - srcBlk = src.getInternCompData(reqBlk, c); - } - else - { - // Do not use the intern variant. Note that this is not optimal - // since if we are going to convert below then we could have used - // the intern variant. But there is currently no way to know if we - // will need to do conversion or not before getting the data. - srcBlk = src.getCompData(reqBlk, c); - } - - // Check if casting is needed - if (srcBlk.DataType == otype) - { - return srcBlk; - } - - int i; - int k, kSrc, kmin; - float mult; - int w = srcBlk.w; - int h = srcBlk.h; - - switch (otype) - { - - case DataBlk.TYPE_FLOAT: // Cast INT -> FLOAT - - float[] farr; - int[] srcIArr; - - // Get data array from resulting blk - farr = (float[]) blk.Data; - if (farr == null || farr.Length < w * h) - { - farr = new float[w * h]; - blk.Data = farr; - } - - blk.scanw = srcBlk.w; - blk.offset = 0; - blk.progressive = srcBlk.progressive; - srcIArr = (int[]) srcBlk.Data; - - // Cast data from source to blk - fp = src.getFixedPoint(c); - if (fp != 0) - { - mult = 1.0f / (1 << fp); - for (i = h - 1, k = w * h - 1, kSrc = srcBlk.offset + (h - 1) * srcBlk.scanw + w - 1; i >= 0; i--) - { - for (kmin = k - w; k > kmin; k--, kSrc--) - { - farr[k] = ((srcIArr[kSrc] * mult)); - } - // Jump to geggining of next line in source - kSrc -= (srcBlk.scanw - w); - } - } - else - { - for (i = h - 1, k = w * h - 1, kSrc = srcBlk.offset + (h - 1) * srcBlk.scanw + w - 1; i >= 0; i--) - { - for (kmin = k - w; k > kmin; k--, kSrc--) - { - //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'" - farr[k] = ((float) (srcIArr[kSrc])); - } - // Jump to geggining of next line in source - kSrc -= (srcBlk.scanw - w); - } - } - break; // End of cast INT-> FLOAT - - - case DataBlk.TYPE_INT: // cast FLOAT -> INT - int[] iarr; - float[] srcFArr; - - // Get data array from resulting blk - iarr = (int[]) blk.Data; - if (iarr == null || iarr.Length < w * h) - { - iarr = new int[w * h]; - blk.Data = iarr; - } - blk.scanw = srcBlk.w; - blk.offset = 0; - blk.progressive = srcBlk.progressive; - srcFArr = (float[]) srcBlk.Data; - - // Cast data from source to blk - if (fp != 0) - { - //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'" - mult = (float) (1 << fp); - for (i = h - 1, k = w * h - 1, kSrc = srcBlk.offset + (h - 1) * srcBlk.scanw + w - 1; i >= 0; i--) - { - for (kmin = k - w; k > kmin; k--, kSrc--) - { - if (srcFArr[kSrc] > 0.0f) - { - //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'" - iarr[k] = (int) (srcFArr[kSrc] * mult + 0.5f); - } - else - { - //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'" - iarr[k] = (int) (srcFArr[kSrc] * mult - 0.5f); - } - } - // Jump to geggining of next line in source - kSrc -= (srcBlk.scanw - w); - } - } - else - { - for (i = h - 1, k = w * h - 1, kSrc = srcBlk.offset + (h - 1) * srcBlk.scanw + w - 1; i >= 0; i--) - { - for (kmin = k - w; k > kmin; k--, kSrc--) - { - if (srcFArr[kSrc] > 0.0f) - { - //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'" - iarr[k] = (int) (srcFArr[kSrc] + 0.5f); - } - else - { - //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'" - iarr[k] = (int) (srcFArr[kSrc] - 0.5f); - } - } - // Jump to geggining of next line in source - kSrc -= (srcBlk.scanw - w); - } - } - break; // End cast FLOAT -> INT - - default: - throw new System.ArgumentException("Only integer and float data " + "are " + "supported by JJ2000"); - - } - return blk; - } - } -} \ No newline at end of file + + /// This class is responsible of all data type conversions. It should be used, + /// at encoder side, between Tiler and ForwardWT modules and, at decoder side, + /// between InverseWT/CompDemixer and ImgWriter modules. The conversion is + /// realized when a block of data is requested: if source and destination data + /// type are the same one, it does nothing, else appropriate cast is done. All + /// the methods of the 'ImgData' interface are implemented by the + /// 'ImgDataAdapter' class that is the superclass of this one, so they don't + /// need to be reimplemented by subclasses. + /// + /// + public class ImgDataConverter : ImgDataAdapter, BlkImgDataSrc + { + + /// The block used to request data from the source in the case that a + /// conversion seems necessary. It can be either int or float at + /// initialization time. It will be checked (and corrected if necessary) by + /// the source whenever necessary + /// + private DataBlk srcBlk = new DataBlkInt(); + + /// The source of image data + private BlkImgDataSrc src; + + /// The number of fraction bits in the casted ints + private int fp; + + /// Constructs a new ImgDataConverter object that operates on the specified + /// source of image data. + /// + /// + /// The source from where to get the data to be transformed + /// + /// + /// The number of fraction bits in the casted ints + /// + /// + /// + /// + /// + public ImgDataConverter(BlkImgDataSrc imgSrc, int fp) + : base(imgSrc) + { + src = imgSrc; + this.fp = fp; + } + + /// Constructs a new ImgDataConverter object that operates on the specified + /// source of image data. + /// + /// + /// The source from where to get the data to be transformed + /// + /// + /// + /// + /// + public ImgDataConverter(BlkImgDataSrc imgSrc) + : base(imgSrc) + { + src = imgSrc; + fp = 0; + } + + /// Returns the position of the fixed point in the specified + /// component. This is the position of the least significant integral + /// (i.e. non-fractional) bit, which is equivalent to the number of + /// fractional bits. For instance, for fixed-point values with 2 fractional + /// bits, 2 is returned. For floating-point data this value does not apply + /// and 0 should be returned. Position 0 is the position of the least + /// significant bit in the data. + /// + /// + /// The index of the component. + /// + /// + /// The position of the fixed-point, which is the same as the + /// number of fractional bits. + /// + /// + public virtual int getFixedPoint(int c) + { + return fp; + } + + /// Returns, in the blk argument, a block of image data containing the + /// specifed rectangular area, in the specified component, using the + /// 'transfer type' specified in the block given as argument. The data is + /// returned, as a copy of the internal data, therefore the returned data + /// can be modified "in place". + /// + ///

The rectangular area to return is specified by the 'ulx', 'uly', 'w' + /// and 'h' members of the 'blk' argument, relative to the current + /// tile. These members are not modified by this method. The 'offset' of + /// the returned data is 0, and the 'scanw' is the same as the block's + /// width. See the 'DataBlk' class. + /// + ///

This method, in general, is less efficient than the + /// 'getInternCompData()' method since, in general, it copies the + /// data. However if the array of returned data is to be modified by the + /// caller then this method is preferable. + /// + ///

If the data array in 'blk' is 'null', then a new one is created. If + /// the data array is not 'null' then it is reused, and it must be large + /// enough to contain the block's data. Otherwise an 'ArrayStoreException' + /// or an 'IndexOutOfBoundsException' is thrown by the Java system. + /// + ///

The returned data may have its 'progressive' attribute set. In this + /// case the returned data is only an approximation of the "final" data. + /// + ///

+ /// Its coordinates and dimensions specify the area to return, + /// relative to the current tile. If it contains a non-null data array, + /// then it must be large enough. If it contains a null data array a new + /// one is created. Some fields in this object are modified to return the + /// data. + /// + /// + /// The index of the component from which to get the data. + /// + /// + /// + /// + /// + public virtual DataBlk getCompData(DataBlk blk, int c) + { + return getData(blk, c, false); + } + + /// Closes the underlying file or network connection from where the + /// image data is being read. + /// + /// + /// If an I/O error occurs. + /// + public void close() + { + // Do nothing. + } + + /// Returns true if the data read was originally signed in the specified + /// component, false if not. + /// + /// + /// The index of the component, from 0 to C-1. + /// + /// + /// true if the data was originally signed, false if not. + /// + /// + public bool isOrigSigned(int c) + { + return false; + } + + /// Returns, in the blk argument, a block of image data containing the + /// specifed rectangular area, in the specified component, using the + /// 'transfer type' defined in the block given as argument. The data is + /// returned, as a reference to the internal data, if any, instead of as a + /// copy, therefore the returned data should not be modified. + /// + ///

The rectangular area to return is specified by the 'ulx', 'uly', 'w' + /// and 'h' members of the 'blk' argument, relative to the current + /// tile. These members are not modified by this method. The 'offset' and + /// 'scanw' of the returned data can be arbitrary. See the 'DataBlk' class. + /// + ///

If source data and expected data (blk) are using the same type, + /// block returned without any modification. If not appropriate cast is + /// used. + /// + ///

This method, in general, is more efficient than the 'getCompData()' + /// method since it may not copy the data. However if the array of returned + /// data is to be modified by the caller then the other method is probably + /// preferable. + /// + ///

If the data array in blk is null, then a new one + /// is created if necessary. The implementation of this interface may + /// choose to return the same array or a new one, depending on what is more + /// efficient. Therefore, the data array in blk prior to the + /// method call should not be considered to contain the returned data, a + /// new array may have been created. Instead, get the array from + /// blk after the method has returned. + /// + ///

The returned data may have its 'progressive' attribute set. In this + /// case the returned data is only an approximation of the "final" data. + /// + ///

+ /// Its coordinates and dimensions specify the area to return, + /// relative to the current tile. Some fields in this object are modified + /// to return the data. + /// + /// + /// The index of the component from which to get the data. + /// + /// + /// The requested DataBlk + /// + /// + /// + /// + /// + public DataBlk getInternCompData(DataBlk blk, int c) + { + return getData(blk, c, true); + } + + /// Implements the 'getInternCompData()' and the 'getCompData()' + /// methods. The 'intern' flag signals which of the two methods should run + /// as. + /// + /// + /// The data block to get. + /// + /// + /// The index of the component from which to get the data. + /// + /// + /// If true behave as 'getInternCompData(). Otherwise behave + /// as 'getCompData()' + /// + /// + /// The requested data block + /// + /// + /// + /// + /// + /// + /// + /// + private DataBlk getData(DataBlk blk, int c, bool intern) + { + DataBlk reqBlk; // Reference to block used in request to source + + // Keep request data type + int otype = blk.DataType; + + if (otype == srcBlk.DataType) + { + // Probably requested type is same as source type + reqBlk = blk; + } + else + { + // Probably requested type is not the same as source type + reqBlk = srcBlk; + // We need to copy requested coordinates and size + reqBlk.ulx = blk.ulx; + reqBlk.uly = blk.uly; + reqBlk.w = blk.w; + reqBlk.h = blk.h; + } + + // Get source data block + if (intern) + { + // We can use the intern variant + srcBlk = src.getInternCompData(reqBlk, c); + } + else + { + // Do not use the intern variant. Note that this is not optimal + // since if we are going to convert below then we could have used + // the intern variant. But there is currently no way to know if we + // will need to do conversion or not before getting the data. + srcBlk = src.getCompData(reqBlk, c); + } + + // Check if casting is needed + if (srcBlk.DataType == otype) + { + return srcBlk; + } + + int i; + int k, kSrc, kmin; + float mult; + int w = srcBlk.w; + int h = srcBlk.h; + + switch (otype) + { + + case DataBlk.TYPE_FLOAT: // Cast INT -> FLOAT + + float[] farr; + int[] srcIArr; + + // Get data array from resulting blk + farr = (float[])blk.Data; + if (farr == null || farr.Length < w * h) + { + farr = new float[w * h]; + blk.Data = farr; + } + + blk.scanw = srcBlk.w; + blk.offset = 0; + blk.progressive = srcBlk.progressive; + srcIArr = (int[])srcBlk.Data; + + // Cast data from source to blk + fp = src.getFixedPoint(c); + if (fp != 0) + { + mult = 1.0f / (1 << fp); + for (i = h - 1, k = w * h - 1, kSrc = srcBlk.offset + (h - 1) * srcBlk.scanw + w - 1; + i >= 0; + i--) + { + for (kmin = k - w; k > kmin; k--, kSrc--) + { + farr[k] = ((srcIArr[kSrc] * mult)); + } + // Jump to geggining of next line in source + kSrc -= (srcBlk.scanw - w); + } + } + else + { + for (i = h - 1, k = w * h - 1, kSrc = srcBlk.offset + (h - 1) * srcBlk.scanw + w - 1; + i >= 0; + i--) + { + for (kmin = k - w; k > kmin; k--, kSrc--) + { + //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'" + farr[k] = ((float)(srcIArr[kSrc])); + } + // Jump to geggining of next line in source + kSrc -= (srcBlk.scanw - w); + } + } + break; // End of cast INT-> FLOAT + + + case DataBlk.TYPE_INT: // cast FLOAT -> INT + int[] iarr; + float[] srcFArr; + + // Get data array from resulting blk + iarr = (int[])blk.Data; + if (iarr == null || iarr.Length < w * h) + { + iarr = new int[w * h]; + blk.Data = iarr; + } + blk.scanw = srcBlk.w; + blk.offset = 0; + blk.progressive = srcBlk.progressive; + srcFArr = (float[])srcBlk.Data; + + // Cast data from source to blk + if (fp != 0) + { + //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'" + mult = (float)(1 << fp); + for (i = h - 1, k = w * h - 1, kSrc = srcBlk.offset + (h - 1) * srcBlk.scanw + w - 1; + i >= 0; + i--) + { + for (kmin = k - w; k > kmin; k--, kSrc--) + { + if (srcFArr[kSrc] > 0.0f) + { + //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'" + iarr[k] = (int)(srcFArr[kSrc] * mult + 0.5f); + } + else + { + //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'" + iarr[k] = (int)(srcFArr[kSrc] * mult - 0.5f); + } + } + // Jump to geggining of next line in source + kSrc -= (srcBlk.scanw - w); + } + } + else + { + for (i = h - 1, k = w * h - 1, kSrc = srcBlk.offset + (h - 1) * srcBlk.scanw + w - 1; + i >= 0; + i--) + { + for (kmin = k - w; k > kmin; k--, kSrc--) + { + if (srcFArr[kSrc] > 0.0f) + { + //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'" + iarr[k] = (int)(srcFArr[kSrc] + 0.5f); + } + else + { + //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'" + iarr[k] = (int)(srcFArr[kSrc] - 0.5f); + } + } + // Jump to geggining of next line in source + kSrc -= (srcBlk.scanw - w); + } + } + break; // End cast FLOAT -> INT + + default: + throw new System.ArgumentException("Only integer and float data " + "are " + "supported by JJ2000"); + + } + return blk; + } + } +} diff --git a/CSJ2K/j2k/image/ImgDataJoiner.cs b/CSJ2K/j2k/image/ImgDataJoiner.cs index df781548..4266caca 100644 --- a/CSJ2K/j2k/image/ImgDataJoiner.cs +++ b/CSJ2K/j2k/image/ImgDataJoiner.cs @@ -40,687 +40,718 @@ * * Copyright (c) 1999/2000 JJ2000 Partners. * */ -using System; -using CSJ2K.j2k; + namespace CSJ2K.j2k.image { - - /// This class implements the ImgData interface and allows to obtain data from - /// different sources. Here, one source is represented by an ImgData and a - /// component index. The typical use of this class is when the encoder needs - /// different components (Red, Green, Blue, alpha, ...) from different input - /// files (i.e. from different ImgReader objects). - /// - ///

All input ImgData must not be tiled (i.e. must have only 1 tile) and the - /// image origin must be the canvas origin. The different inputs can have - /// different dimensions though (this will lead to different subsampling - /// factors for each component).

- /// - ///

The input ImgData and component index list must be defined when - /// constructing this class and can not be modified later.

- /// - ///
- /// - /// - /// - /// - /// - public class ImgDataJoiner : BlkImgDataSrc - { - /// Returns the overall width of the current tile in pixels. This is the - /// tile's width without accounting for any component subsampling. - /// - /// - /// The total current tile's width in pixels. - /// - /// - virtual public int TileWidth - { - get - { - return w; - } - - } - /// Returns the overall height of the current tile in pixels. This is the - /// tile's height without accounting for any component subsampling. - /// - /// - /// The total current tile's height in pixels. - /// - /// - virtual public int TileHeight - { - get - { - return h; - } - - } - /// Returns the nominal tiles width - virtual public int NomTileWidth - { - get - { - return w; - } - - } - /// Returns the nominal tiles height - virtual public int NomTileHeight - { - get - { - return h; - } - - } - /// Returns the overall width of the image in pixels. This is the image's - /// width without accounting for any component subsampling or tiling. - /// - /// - /// The total image's width in pixels. - /// - /// - virtual public int ImgWidth - { - get - { - return w; - } - - } - /// Returns the overall height of the image in pixels. This is the image's - /// height without accounting for any component subsampling or tiling. - /// - /// - /// The total image's height in pixels. - /// - /// - virtual public int ImgHeight - { - get - { - return h; - } - - } - /// Returns the number of components in the image. - /// - /// - /// The number of components in the image. - /// - /// - virtual public int NumComps - { - get - { - return nc; - } - - } - /// Returns the index of the current tile, relative to a standard scan-line - /// order. This default implementations assumes no tiling, so 0 is always - /// returned. - /// - /// - /// The current tile's index (starts at 0). - /// - /// - virtual public int TileIdx - { - get - { - return 0; - } - - } - /// Returns the horizontal tile partition offset in the reference grid - virtual public int TilePartULX - { - get - { - return 0; - } - - } - /// Returns the vertical tile partition offset in the reference grid - virtual public int TilePartULY - { - get - { - return 0; - } - - } - /// Returns the horizontal coordinate of the image origin, the top-left - /// corner, in the canvas system, on the reference grid. - /// - /// - /// The horizontal coordinate of the image origin in the canvas - /// system, on the reference grid. - /// - /// - virtual public int ImgULX - { - get - { - return 0; - } - - } - /// Returns the vertical coordinate of the image origin, the top-left - /// corner, in the canvas system, on the reference grid. - /// - /// - /// The vertical coordinate of the image origin in the canvas - /// system, on the reference grid. - /// - /// - virtual public int ImgULY - { - get - { - return 0; - } - - } - - /// The width of the image - private int w; - - /// The height of the image - private int h; - - /// The number of components in the image - private int nc; - - /// The list of input ImgData - private BlkImgDataSrc[] imageData; - - /// The component index associated with each ImgData - private int[] compIdx; - - /// The subsampling factor along the horizontal direction, for every - /// component - /// - private int[] subsX; - - /// The subsampling factor along the vertical direction, for every - /// component - /// - private int[] subsY; - - /// Class constructor. Each input BlkImgDataSrc and its component index - /// must appear in the order wanted for the output components.
- /// - /// Example: Reading R,G,B components from 3 PGM files.
- /// - /// BlkImgDataSrc[] idList =
- /// {
- /// new ImgReaderPGM(new BEBufferedRandomAccessFile("R.pgm", "r")),
- /// new ImgReaderPGM(new BEBufferedRandomAccessFile("G.pgm", "r")),
- /// new ImgReaderPGM(new BEBufferedRandomAccessFile("B.pgm", "r"))
- /// };
- /// int[] compIdx = {0,0,0};
- /// ImgDataJoiner idj = new ImgDataJoiner(idList, compIdx); - ///
- /// - ///

Of course, the 2 arrays must have the same length (This length is - /// the number of output components). The image width and height are - /// definded to be the maximum values of all the input ImgData. - /// - ///

- /// The list of input BlkImgDataSrc in an array. - /// - /// - /// The component index associated with each ImgData. - /// - /// - public ImgDataJoiner(BlkImgDataSrc[] imD, int[] cIdx) - { - int i; - int maxW, maxH; - - // Initializes - imageData = imD; - compIdx = cIdx; - if (imageData.Length != compIdx.Length) - throw new System.ArgumentException("imD and cIdx must have the" + " same length"); - - nc = imD.Length; - - subsX = new int[nc]; - subsY = new int[nc]; - - // Check that no source is tiled and that the image origin is at the - // canvas origin. - for (i = 0; i < nc; i++) - { - if (imD[i].getNumTiles() != 1 || imD[i].getCompULX(cIdx[i]) != 0 || imD[i].getCompULY(cIdx[i]) != 0) - { - throw new System.ArgumentException("All input components must, " + "not use tiles and must " + "have " + "the origin at the canvas " + "origin"); - } - } - - // Guess component subsampling factors based on the fact that the - // ceil() operation relates the reference grid size to the component's - // size, through the subsampling factor. - - // Mhhh, difficult problem. For now just assume that one of the - // subsampling factors is always 1 and that the component width is - // always larger than its subsampling factor, which covers most of the - // cases. We check the correctness of the solution once found to chek - // out hypothesis. - - // Look for max width and height. - maxW = 0; - maxH = 0; - for (i = 0; i < nc; i++) - { - if (imD[i].getCompImgWidth(cIdx[i]) > maxW) - maxW = imD[i].getCompImgWidth(cIdx[i]); - if (imD[i].getCompImgHeight(cIdx[i]) > maxH) - maxH = imD[i].getCompImgHeight(cIdx[i]); - } - // Set the image width and height as the maximum ones - w = maxW; - h = maxH; - - // Now get the sumsampling factors and check the subsampling factors, - // just to see if above hypothesis were correct. - for (i = 0; i < nc; i++) - { - // This calculation only holds if the subsampling factor is less - // than the component width - subsX[i] = (maxW + imD[i].getCompImgWidth(cIdx[i]) - 1) / imD[i].getCompImgWidth(cIdx[i]); - subsY[i] = (maxH + imD[i].getCompImgHeight(cIdx[i]) - 1) / imD[i].getCompImgHeight(cIdx[i]); - if ((maxW + subsX[i] - 1) / subsX[i] != imD[i].getCompImgWidth(cIdx[i]) || (maxH + subsY[i] - 1) / subsY[i] != imD[i].getCompImgHeight(cIdx[i])) - { - throw new System.ApplicationException("Can not compute component subsampling " + "factors: strange subsampling."); - } - } - } - - /// Returns the component subsampling factor in the horizontal direction, - /// for the specified component. This is, approximately, the ratio of - /// dimensions between the reference grid and the component itself, see the - /// 'ImgData' interface desription for details. - /// - /// - /// The index of the component (between 0 and N-1) - /// - /// - /// The horizontal subsampling factor of component 'c' - /// - /// - /// - /// - /// - public virtual int getCompSubsX(int c) - { - return subsX[c]; - } - - /// Returns the component subsampling factor in the vertical direction, for - /// the specified component. This is, approximately, the ratio of - /// dimensions between the reference grid and the component itself, see the - /// 'ImgData' interface desription for details. - /// - /// - /// The index of the component (between 0 and N-1) - /// - /// - /// The vertical subsampling factor of component 'c' - /// - /// - /// - /// - /// - public virtual int getCompSubsY(int c) - { - return subsY[c]; - } - - - /// Returns the width in pixels of the specified tile-component - /// - /// - /// Tile index - /// - /// - /// The index of the component, from 0 to N-1. - /// - /// - /// The width in pixels of component c in tilet. - /// - /// - public virtual int getTileCompWidth(int t, int c) - { - return imageData[c].getTileCompWidth(t, compIdx[c]); - } - - /// Returns the height in pixels of the specified tile-component. - /// - /// - /// The tile index. - /// - /// - /// The index of the component, from 0 to N-1. - /// - /// - /// The height in pixels of component c in the current - /// tile. - /// - /// - public virtual int getTileCompHeight(int t, int c) - { - return imageData[c].getTileCompHeight(t, compIdx[c]); - } - - /// Returns the width in pixels of the specified component in the overall - /// image. - /// - /// - /// The index of the component, from 0 to N-1. - /// - /// - /// The width in pixels of component c in the overall - /// image. - /// - /// - public virtual int getCompImgWidth(int c) - { - return imageData[c].getCompImgWidth(compIdx[c]); - } - - /// Returns the height in pixels of the specified component in the - /// overall image. - /// - /// - /// The index of the component, from 0 to N-1. - /// - /// - /// The height in pixels of component n in the overall - /// image. - /// - /// - /// - /// - public virtual int getCompImgHeight(int n) - { - return imageData[n].getCompImgHeight(compIdx[n]); - } - - /// Returns the number of bits, referred to as the "range bits", - /// corresponding to the nominal range of the data in the specified - /// component. If this number is b then for unsigned data the - /// nominal range is between 0 and 2^b-1, and for signed data it is between - /// -2^(b-1) and 2^(b-1)-1. For floating point data this value is not - /// applicable. - /// - /// - /// The index of the component. - /// - /// - /// The number of bits corresponding to the nominal range of the - /// data. Fro floating-point data this value is not applicable and the - /// return value is undefined. - /// - /// - public virtual int getNomRangeBits(int c) - { - return imageData[c].getNomRangeBits(compIdx[c]); - } - - /// Returns the position of the fixed point in the specified - /// component. This is the position of the least significant integral - /// (i.e. non-fractional) bit, which is equivalent to the number of - /// fractional bits. For instance, for fixed-point values with 2 fractional - /// bits, 2 is returned. For floating-point data this value does not apply - /// and 0 should be returned. Position 0 is the position of the least - /// significant bit in the data. - /// - /// - /// The index of the component. - /// - /// - /// The position of the fixed-point, which is the same as the - /// number of fractional bits. For floating-point data 0 is returned. - /// - /// - public virtual int getFixedPoint(int c) - { - return imageData[c].getFixedPoint(compIdx[c]); - } - - /// Returns, in the blk argument, a block of image data containing the - /// specifed rectangular area, in the specified component. The data is - /// returned, as a reference to the internal data, if any, instead of as a - /// copy, therefore the returned data should not be modified. - /// - ///

The rectangular area to return is specified by the 'ulx', 'uly', 'w' - /// and 'h' members of the 'blk' argument, relative to the current - /// tile. These members are not modified by this method. The 'offset' and - /// 'scanw' of the returned data can be arbitrary. See the 'DataBlk' class. - /// - ///

This method, in general, is more efficient than the 'getCompData()' - /// method since it may not copy the data. However if the array of returned - /// data is to be modified by the caller then the other method is probably - /// preferable. - /// - ///

If the data array in blk is null, then a new one - /// is created if necessary. The implementation of this interface may - /// choose to return the same array or a new one, depending on what is more - /// efficient. Therefore, the data array in blk prior to the - /// method call should not be considered to contain the returned data, a - /// new array may have been created. Instead, get the array from - /// blk after the method has returned. - /// - ///

The returned data may have its 'progressive' attribute set. In this - /// case the returned data is only an approximation of the "final" data. - /// - ///

- /// Its coordinates and dimensions specify the area to return, - /// relative to the current tile. Some fields in this object are modified - /// to return the data. - /// - /// - /// The index of the component from which to get the data. - /// - /// - /// The requested DataBlk - /// - /// - /// - /// - /// - public virtual DataBlk getInternCompData(DataBlk blk, int c) - { - return imageData[c].getInternCompData(blk, compIdx[c]); - } - - /// Returns, in the blk argument, a block of image data containing the - /// specifed rectangular area, in the specified component. The data is - /// returned, as a copy of the internal data, therefore the returned data - /// can be modified "in place". - /// - ///

The rectangular area to return is specified by the 'ulx', 'uly', 'w' - /// and 'h' members of the 'blk' argument, relative to the current - /// tile. These members are not modified by this method. The 'offset' of - /// the returned data is 0, and the 'scanw' is the same as the block's - /// width. See the 'DataBlk' class. - /// - ///

This method, in general, is less efficient than the - /// 'getInternCompData()' method since, in general, it copies the - /// data. However if the array of returned data is to be modified by the - /// caller then this method is preferable. - /// - ///

If the data array in 'blk' is 'null', then a new one is created. If - /// the data array is not 'null' then it is reused, and it must be large - /// enough to contain the block's data. Otherwise an 'ArrayStoreException' - /// or an 'IndexOutOfBoundsException' is thrown by the Java system. - /// - ///

The returned data may have its 'progressive' attribute set. In this - /// case the returned data is only an approximation of the "final" data. - /// - ///

- /// Its coordinates and dimensions specify the area to return, - /// relative to the current tile. If it contains a non-null data array, - /// then it must be large enough. If it contains a null data array a new - /// one is created. Some fields in this object are modified to return the - /// data. - /// - /// - /// The index of the component from which to get the data. - /// - /// - /// The requested DataBlk - /// - /// - /// - /// - /// - public virtual DataBlk getCompData(DataBlk blk, int c) - { - return imageData[c].getCompData(blk, compIdx[c]); - } - - /// Changes the current tile, given the new coordinates. An - /// IllegalArgumentException is thrown if the coordinates do not correspond - /// to a valid tile. - /// - /// - /// The horizontal coordinate of the tile. - /// - /// - /// The vertical coordinate of the new tile. - /// - /// - public virtual void setTile(int x, int y) - { - if (x != 0 || y != 0) - { - throw new System.ArgumentException(); - } - } - - /// Advances to the next tile, in standard scan-line order (by rows then - /// columns). A NoNextElementException is thrown if the current tile is the - /// last one (i.e. there is no next tile). This default implementation - /// assumes no tiling, so NoNextElementException() is always thrown. - /// - /// - public virtual void nextTile() - { - throw new NoNextElementException(); - } - - /// Returns the coordinates of the current tile. This default - /// implementation assumes no-tiling, so (0,0) is returned. - /// - /// - /// If not null this object is used to return the information. If - /// null a new one is created and returned. - /// - /// - /// The current tile's coordinates. - /// - /// - public virtual Coord getTile(Coord co) - { - if (co != null) - { - co.x = 0; - co.y = 0; - return co; - } - else - { - return new Coord(0, 0); - } - } - - /// Returns the horizontal coordinate of the upper-left corner of the - /// specified component in the current tile. - /// - /// - /// The component index. - /// - /// - public virtual int getCompULX(int c) - { - return 0; - } - - /// Returns the vertical coordinate of the upper-left corner of the - /// specified component in the current tile. - /// - /// - /// The component index. - /// - /// - public virtual int getCompULY(int c) - { - return 0; - } - - /// Returns the number of tiles in the horizontal and vertical - /// directions. This default implementation assumes no tiling, so (1,1) is - /// always returned. - /// - /// - /// If not null this object is used to return the information. If - /// null a new one is created and returned. - /// - /// - /// The number of tiles in the horizontal (Coord.x) and vertical - /// (Coord.y) directions. - /// - /// - public virtual Coord getNumTiles(Coord co) - { - if (co != null) - { - co.x = 1; - co.y = 1; - return co; - } - else - { - return new Coord(1, 1); - } - } - - /// Returns the total number of tiles in the image. This default - /// implementation assumes no tiling, so 1 is always returned. - /// - /// - /// The total number of tiles in the image. - /// - /// - public virtual int getNumTiles() - { - return 1; - } - - /// Returns a string of information about the object, more than 1 line - /// long. The information string includes information from the several - /// input ImgData (their toString() method are called one after the other). - /// - /// - /// A string of information about the object. - /// - /// - public override System.String ToString() - { - System.String string_Renamed = "ImgDataJoiner: WxH = " + w + "x" + h; - for (int i = 0; i < nc; i++) - { - //UPGRADE_TODO: The equivalent in .NET for method 'java.lang.Object.toString' may return a different value. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1043'" - string_Renamed += ("\n- Component " + i + " " + imageData[i]); - } - return string_Renamed; - } - } -} \ No newline at end of file + using System.Collections.Generic; + + using CSJ2K.j2k.image.input; + + /// This class implements the ImgData interface and allows to obtain data from + /// different sources. Here, one source is represented by an ImgData and a + /// component index. The typical use of this class is when the encoder needs + /// different components (Red, Green, Blue, alpha, ...) from different input + /// files (i.e. from different ImgReader objects). + /// + ///

All input ImgData must not be tiled (i.e. must have only 1 tile) and the + /// image origin must be the canvas origin. The different inputs can have + /// different dimensions though (this will lead to different subsampling + /// factors for each component).

+ /// + ///

The input ImgData and component index list must be defined when + /// constructing this class and can not be modified later.

+ /// + ///
+ /// + /// + /// + /// + /// + public class ImgDataJoiner : BlkImgDataSrc + { + /// Returns the overall width of the current tile in pixels. This is the + /// tile's width without accounting for any component subsampling. + /// + /// + /// The total current tile's width in pixels. + /// + /// + virtual public int TileWidth + { + get + { + return w; + } + + } + /// Returns the overall height of the current tile in pixels. This is the + /// tile's height without accounting for any component subsampling. + /// + /// + /// The total current tile's height in pixels. + /// + /// + virtual public int TileHeight + { + get + { + return h; + } + + } + /// Returns the nominal tiles width + virtual public int NomTileWidth + { + get + { + return w; + } + + } + /// Returns the nominal tiles height + virtual public int NomTileHeight + { + get + { + return h; + } + + } + /// Returns the overall width of the image in pixels. This is the image's + /// width without accounting for any component subsampling or tiling. + /// + /// + /// The total image's width in pixels. + /// + /// + virtual public int ImgWidth + { + get + { + return w; + } + + } + /// Returns the overall height of the image in pixels. This is the image's + /// height without accounting for any component subsampling or tiling. + /// + /// + /// The total image's height in pixels. + /// + /// + virtual public int ImgHeight + { + get + { + return h; + } + + } + /// Returns the number of components in the image. + /// + /// + /// The number of components in the image. + /// + /// + virtual public int NumComps + { + get + { + return nc; + } + + } + /// Returns the index of the current tile, relative to a standard scan-line + /// order. This default implementations assumes no tiling, so 0 is always + /// returned. + /// + /// + /// The current tile's index (starts at 0). + /// + /// + virtual public int TileIdx + { + get + { + return 0; + } + + } + /// Returns the horizontal tile partition offset in the reference grid + virtual public int TilePartULX + { + get + { + return 0; + } + + } + /// Returns the vertical tile partition offset in the reference grid + virtual public int TilePartULY + { + get + { + return 0; + } + + } + /// Returns the horizontal coordinate of the image origin, the top-left + /// corner, in the canvas system, on the reference grid. + /// + /// + /// The horizontal coordinate of the image origin in the canvas + /// system, on the reference grid. + /// + /// + virtual public int ImgULX + { + get + { + return 0; + } + + } + /// Returns the vertical coordinate of the image origin, the top-left + /// corner, in the canvas system, on the reference grid. + /// + /// + /// The vertical coordinate of the image origin in the canvas + /// system, on the reference grid. + /// + /// + virtual public int ImgULY + { + get + { + return 0; + } + + } + + /// The width of the image + private readonly int w; + + /// The height of the image + private readonly int h; + + /// The number of components in the image + private readonly int nc; + + /// The list of input ImgData + private readonly IList imageData; + + /// The component index associated with each ImgData + private readonly IList compIdx; + + /// The subsampling factor along the horizontal direction, for every + /// component + /// + private readonly int[] subsX; + + /// The subsampling factor along the vertical direction, for every + /// component + /// + private readonly int[] subsY; + + /// Class constructor. Each input BlkImgDataSrc and its component index + /// must appear in the order wanted for the output components.
+ /// + /// Example: Reading R,G,B components from 3 PGM files.
+ /// + /// BlkImgDataSrc[] idList =
+ /// {
+ /// new ImgReaderPGM(new BEBufferedRandomAccessFile("R.pgm", "r")),
+ /// new ImgReaderPGM(new BEBufferedRandomAccessFile("G.pgm", "r")),
+ /// new ImgReaderPGM(new BEBufferedRandomAccessFile("B.pgm", "r"))
+ /// };
+ /// int[] compIdx = {0,0,0};
+ /// ImgDataJoiner idj = new ImgDataJoiner(idList, compIdx); + ///
+ /// + ///

Of course, the 2 arrays must have the same length (This length is + /// the number of output components). The image width and height are + /// definded to be the maximum values of all the input ImgData. + /// + ///

+ /// The list of input BlkImgDataSrc in an array. + /// + /// + /// The component index associated with each ImgData. + /// + /// + public ImgDataJoiner(IList imD, IList cIdx) + { + int i; + int maxW, maxH; + + // Initializes + imageData = imD; + compIdx = cIdx; + if (imageData.Count != compIdx.Count) + throw new System.ArgumentException("imD and cIdx must have the" + " same length"); + + nc = imD.Count; + + subsX = new int[nc]; + subsY = new int[nc]; + + // Check that no source is tiled and that the image origin is at the + // canvas origin. + for (i = 0; i < nc; i++) + { + if (imD[i].getNumTiles() != 1 || imD[i].getCompULX(cIdx[i]) != 0 || imD[i].getCompULY(cIdx[i]) != 0) + { + throw new System.ArgumentException("All input components must, " + "not use tiles and must " + "have " + "the origin at the canvas " + "origin"); + } + } + + // Guess component subsampling factors based on the fact that the + // ceil() operation relates the reference grid size to the component's + // size, through the subsampling factor. + + // Mhhh, difficult problem. For now just assume that one of the + // subsampling factors is always 1 and that the component width is + // always larger than its subsampling factor, which covers most of the + // cases. We check the correctness of the solution once found to chek + // out hypothesis. + + // Look for max width and height. + maxW = 0; + maxH = 0; + for (i = 0; i < nc; i++) + { + if (imD[i].getCompImgWidth(cIdx[i]) > maxW) + maxW = imD[i].getCompImgWidth(cIdx[i]); + if (imD[i].getCompImgHeight(cIdx[i]) > maxH) + maxH = imD[i].getCompImgHeight(cIdx[i]); + } + // Set the image width and height as the maximum ones + w = maxW; + h = maxH; + + // Now get the sumsampling factors and check the subsampling factors, + // just to see if above hypothesis were correct. + for (i = 0; i < nc; i++) + { + // This calculation only holds if the subsampling factor is less + // than the component width + subsX[i] = (maxW + imD[i].getCompImgWidth(cIdx[i]) - 1) / imD[i].getCompImgWidth(cIdx[i]); + subsY[i] = (maxH + imD[i].getCompImgHeight(cIdx[i]) - 1) / imD[i].getCompImgHeight(cIdx[i]); + if ((maxW + subsX[i] - 1) / subsX[i] != imD[i].getCompImgWidth(cIdx[i]) || (maxH + subsY[i] - 1) / subsY[i] != imD[i].getCompImgHeight(cIdx[i])) + { + throw new System.InvalidOperationException("Can not compute component subsampling " + "factors: strange subsampling."); + } + } + } + + /// Returns the component subsampling factor in the horizontal direction, + /// for the specified component. This is, approximately, the ratio of + /// dimensions between the reference grid and the component itself, see the + /// 'ImgData' interface desription for details. + /// + /// + /// The index of the component (between 0 and N-1) + /// + /// + /// The horizontal subsampling factor of component 'c' + /// + /// + /// + /// + /// + public virtual int getCompSubsX(int c) + { + return subsX[c]; + } + + /// Returns the component subsampling factor in the vertical direction, for + /// the specified component. This is, approximately, the ratio of + /// dimensions between the reference grid and the component itself, see the + /// 'ImgData' interface desription for details. + /// + /// + /// The index of the component (between 0 and N-1) + /// + /// + /// The vertical subsampling factor of component 'c' + /// + /// + /// + /// + /// + public virtual int getCompSubsY(int c) + { + return subsY[c]; + } + + + /// Returns the width in pixels of the specified tile-component + /// + /// + /// Tile index + /// + /// + /// The index of the component, from 0 to N-1. + /// + /// + /// The width in pixels of component c in tilet. + /// + /// + public virtual int getTileCompWidth(int t, int c) + { + return imageData[c].getTileCompWidth(t, compIdx[c]); + } + + /// Returns the height in pixels of the specified tile-component. + /// + /// + /// The tile index. + /// + /// + /// The index of the component, from 0 to N-1. + /// + /// + /// The height in pixels of component c in the current + /// tile. + /// + /// + public virtual int getTileCompHeight(int t, int c) + { + return imageData[c].getTileCompHeight(t, compIdx[c]); + } + + /// Returns the width in pixels of the specified component in the overall + /// image. + /// + /// + /// The index of the component, from 0 to N-1. + /// + /// + /// The width in pixels of component c in the overall + /// image. + /// + /// + public virtual int getCompImgWidth(int c) + { + return imageData[c].getCompImgWidth(compIdx[c]); + } + + /// Returns the height in pixels of the specified component in the + /// overall image. + /// + /// + /// The index of the component, from 0 to N-1. + /// + /// + /// The height in pixels of component n in the overall + /// image. + /// + /// + /// + /// + public virtual int getCompImgHeight(int n) + { + return imageData[n].getCompImgHeight(compIdx[n]); + } + + ///
+ /// The index of the component. + /// + /// + /// The number of bits corresponding to the nominal range of the + /// data. Fro floating-point data this value is not applicable and the + /// return value is undefined. + /// + /// + public virtual int getNomRangeBits(int c) + { + return imageData[c].getNomRangeBits(compIdx[c]); + } + + /// Returns the position of the fixed point in the specified + /// component. This is the position of the least significant integral + /// (i.e. non-fractional) bit, which is equivalent to the number of + /// fractional bits. For instance, for fixed-point values with 2 fractional + /// bits, 2 is returned. For floating-point data this value does not apply + /// and 0 should be returned. Position 0 is the position of the least + /// significant bit in the data. + /// + /// + /// The index of the component. + /// + /// + /// The position of the fixed-point, which is the same as the + /// number of fractional bits. For floating-point data 0 is returned. + /// + /// + public virtual int getFixedPoint(int c) + { + return imageData[c].getFixedPoint(compIdx[c]); + } + + /// Returns, in the blk argument, a block of image data containing the + /// specifed rectangular area, in the specified component. The data is + /// returned, as a reference to the internal data, if any, instead of as a + /// copy, therefore the returned data should not be modified. + /// + ///

The rectangular area to return is specified by the 'ulx', 'uly', 'w' + /// and 'h' members of the 'blk' argument, relative to the current + /// tile. These members are not modified by this method. The 'offset' and + /// 'scanw' of the returned data can be arbitrary. See the 'DataBlk' class. + /// + ///

This method, in general, is more efficient than the 'getCompData()' + /// method since it may not copy the data. However if the array of returned + /// data is to be modified by the caller then the other method is probably + /// preferable. + /// + ///

If the data array in blk is null, then a new one + /// is created if necessary. The implementation of this interface may + /// choose to return the same array or a new one, depending on what is more + /// efficient. Therefore, the data array in blk prior to the + /// method call should not be considered to contain the returned data, a + /// new array may have been created. Instead, get the array from + /// blk after the method has returned. + /// + ///

The returned data may have its 'progressive' attribute set. In this + /// case the returned data is only an approximation of the "final" data. + /// + ///

+ /// Its coordinates and dimensions specify the area to return, + /// relative to the current tile. Some fields in this object are modified + /// to return the data. + /// + /// + /// The index of the component from which to get the data. + /// + /// + /// The requested DataBlk + /// + /// + /// + /// + /// + public virtual DataBlk getInternCompData(DataBlk blk, int c) + { + return imageData[c].getInternCompData(blk, compIdx[c]); + } + + /// Returns, in the blk argument, a block of image data containing the + /// specifed rectangular area, in the specified component. The data is + /// returned, as a copy of the internal data, therefore the returned data + /// can be modified "in place". + /// + ///

The rectangular area to return is specified by the 'ulx', 'uly', 'w' + /// and 'h' members of the 'blk' argument, relative to the current + /// tile. These members are not modified by this method. The 'offset' of + /// the returned data is 0, and the 'scanw' is the same as the block's + /// width. See the 'DataBlk' class. + /// + ///

This method, in general, is less efficient than the + /// 'getInternCompData()' method since, in general, it copies the + /// data. However if the array of returned data is to be modified by the + /// caller then this method is preferable. + /// + ///

If the data array in 'blk' is 'null', then a new one is created. If + /// the data array is not 'null' then it is reused, and it must be large + /// enough to contain the block's data. Otherwise an 'ArrayStoreException' + /// or an 'IndexOutOfBoundsException' is thrown by the Java system. + /// + ///

The returned data may have its 'progressive' attribute set. In this + /// case the returned data is only an approximation of the "final" data. + /// + ///

+ /// Its coordinates and dimensions specify the area to return, + /// relative to the current tile. If it contains a non-null data array, + /// then it must be large enough. If it contains a null data array a new + /// one is created. Some fields in this object are modified to return the + /// data. + /// + /// + /// The index of the component from which to get the data. + /// + /// + /// The requested DataBlk + /// + /// + /// + /// + /// + public virtual DataBlk getCompData(DataBlk blk, int c) + { + return imageData[c].getCompData(blk, compIdx[c]); + } + + /// Closes the underlying file or network connection from where the + /// image data is being read. + /// + /// + /// If an I/O error occurs. + /// + public void close() + { + foreach (var reader in imageData) + { + reader.close(); + } + } + + /// Returns true if the data read was originally signed in the specified + /// component, false if not. + /// + /// + /// The index of the component, from 0 to C-1. + /// + /// + /// true if the data was originally signed, false if not. + /// + /// + public bool isOrigSigned(int c) + { + return false; + } + + /// Changes the current tile, given the new coordinates. An + /// IllegalArgumentException is thrown if the coordinates do not correspond + /// to a valid tile. + /// + /// + /// The horizontal coordinate of the tile. + /// + /// + /// The vertical coordinate of the new tile. + /// + /// + public virtual void setTile(int x, int y) + { + if (x != 0 || y != 0) + { + throw new System.ArgumentException(); + } + } + + /// Advances to the next tile, in standard scan-line order (by rows then + /// columns). A NoNextElementException is thrown if the current tile is the + /// last one (i.e. there is no next tile). This default implementation + /// assumes no tiling, so NoNextElementException() is always thrown. + /// + /// + public virtual void nextTile() + { + throw new NoNextElementException(); + } + + /// Returns the coordinates of the current tile. This default + /// implementation assumes no-tiling, so (0,0) is returned. + /// + /// + /// If not null this object is used to return the information. If + /// null a new one is created and returned. + /// + /// + /// The current tile's coordinates. + /// + /// + public virtual Coord getTile(Coord co) + { + if (co != null) + { + co.x = 0; + co.y = 0; + return co; + } + else + { + return new Coord(0, 0); + } + } + + /// Returns the horizontal coordinate of the upper-left corner of the + /// specified component in the current tile. + /// + /// + /// The component index. + /// + /// + public virtual int getCompULX(int c) + { + return 0; + } + + /// Returns the vertical coordinate of the upper-left corner of the + /// specified component in the current tile. + /// + /// + /// The component index. + /// + /// + public virtual int getCompULY(int c) + { + return 0; + } + + /// Returns the number of tiles in the horizontal and vertical + /// directions. This default implementation assumes no tiling, so (1,1) is + /// always returned. + /// + /// + /// If not null this object is used to return the information. If + /// null a new one is created and returned. + /// + /// + /// The number of tiles in the horizontal (Coord.x) and vertical + /// (Coord.y) directions. + /// + /// + public virtual Coord getNumTiles(Coord co) + { + if (co != null) + { + co.x = 1; + co.y = 1; + return co; + } + else + { + return new Coord(1, 1); + } + } + + /// Returns the total number of tiles in the image. This default + /// implementation assumes no tiling, so 1 is always returned. + /// + /// + /// The total number of tiles in the image. + /// + /// + public virtual int getNumTiles() + { + return 1; + } + + /// Returns a string of information about the object, more than 1 line + /// long. The information string includes information from the several + /// input ImgData (their toString() method are called one after the other). + /// + /// + /// A string of information about the object. + /// + /// + public override System.String ToString() + { + System.String string_Renamed = "ImgDataJoiner: WxH = " + w + "x" + h; + for (int i = 0; i < nc; i++) + { + //UPGRADE_TODO: The equivalent in .NET for method 'java.lang.Object.toString' may return a different value. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1043'" + string_Renamed += ("\n- Component " + i + " " + imageData[i]); + } + return string_Renamed; + } + } +} diff --git a/CSJ2K/j2k/image/Tiler.cs b/CSJ2K/j2k/image/Tiler.cs index ec8ed229..0c0845c0 100644 --- a/CSJ2K/j2k/image/Tiler.cs +++ b/CSJ2K/j2k/image/Tiler.cs @@ -44,707 +44,747 @@ using System; using CSJ2K.j2k.util; using CSJ2K.j2k; + namespace CSJ2K.j2k.image { - - /// This class places an image in the canvas coordinate system, tiles it, if so - /// specified, and performs the coordinate conversions transparently. The - /// source must be a 'BlkImgDataSrc' which is not tiled and has a the image - /// origin at the canvas origin (i.e. it is not "canvased"), or an exception is - /// thrown by the constructor. A tiled and "canvased" output is given through - /// the 'BlkImgDataSrc' interface. See the 'ImgData' interface for a - /// description of the canvas and tiling. - /// - ///

All tiles produced are rectangular, non-overlapping and their union - /// covers all the image. However, the tiling may not be uniform, depending on - /// the nominal tile size, tiling origin, component subsampling and other - /// factors. Therefore it might not be assumed that all tiles are of the same - /// width and height.

- /// - ///

The nominal dimension of the tiles is the maximal one, in the reference - /// grid. All the components of the image have the same number of tiles.

- /// - ///
- /// - /// - /// - /// - /// - public class Tiler:ImgDataAdapter, BlkImgDataSrc - { - /// Returns the overall width of the current tile in pixels. This is the - /// tile's width without accounting for any component subsampling. - /// - /// - /// The total current tile width in pixels. - /// - /// - override public int TileWidth - { - get - { - return tileW; - } - - } - /// Returns the overall height of the current tile in pixels. This is the - /// tile's width without accounting for any component subsampling. - /// - /// - /// The total current tile height in pixels. - /// - /// - override public int TileHeight - { - get - { - return tileH; - } - - } - /// Returns the index of the current tile, relative to a standard scan-line - /// order. - /// - /// - /// The current tile's index (starts at 0). - /// - /// - override public int TileIdx - { - get - { - return ty * ntX + tx; - } - - } - /// Returns the horizontal tile partition offset in the reference grid - override public int TilePartULX - { - get - { - return xt0siz; - } - - } - /// Returns the vertical tile partition offset in the reference grid - override public int TilePartULY - { - get - { - return yt0siz; - } - - } - /// Returns the horizontal coordinate of the image origin, the top-left - /// corner, in the canvas system, on the reference grid. - /// - /// - /// The horizontal coordinate of the image origin in the canvas - /// system, on the reference grid. - /// - /// - override public int ImgULX - { - get - { - return x0siz; - } - - } - /// Returns the vertical coordinate of the image origin, the top-left - /// corner, in the canvas system, on the reference grid. - /// - /// - /// The vertical coordinate of the image origin in the canvas - /// system, on the reference grid. - /// - /// - override public int ImgULY - { - get - { - return y0siz; - } - - } - /// Returns the nominal width of the tiles in the reference grid. - /// - /// - /// The nominal tile width, in the reference grid. - /// - /// - override public int NomTileWidth - { - get - { - return xtsiz; - } - - } - /// Returns the nominal width of the tiles in the reference grid. - /// - /// - /// The nominal tile width, in the reference grid. - /// - /// - override public int NomTileHeight - { - get - { - return ytsiz; - } - - } - - /// The source of image data - private BlkImgDataSrc src = null; - - /// Horizontal coordinate of the upper left hand reference grid point. - private int x0siz; - - /// Vertical coordinate of the upper left hand reference grid point. - private int y0siz; - - /// The horizontal coordinate of the tiling origin in the canvas system, - /// on the reference grid. - /// - private int xt0siz; - - /// The vertical coordinate of the tiling origin in the canvas system, on - /// the reference grid. - /// - private int yt0siz; - - /// The nominal width of the tiles, on the reference grid. If 0 then there - /// is no tiling in that direction. - /// - private int xtsiz; - - /// The nominal height of the tiles, on the reference grid. If 0 then - /// there is no tiling in that direction. - /// - private int ytsiz; - - /// The number of tiles in the horizontal direction. - private int ntX; - - /// The number of tiles in the vertical direction. - private int ntY; - - /// The component width in the current active tile, for each component - private int[] compW = null; - - /// The component height in the current active tile, for each component - private int[] compH = null; - - /// The horizontal coordinates of the upper-left corner of the components - /// in the current tile - /// - private int[] tcx0 = null; - - /// The vertical coordinates of the upper-left corner of the components in - /// the current tile. - /// - private int[] tcy0 = null; - - /// The horizontal index of the current tile - private int tx; - - /// The vertical index of the current tile - private int ty; - - /// The width of the current tile, on the reference grid. - private int tileW; - - /// The height of the current tile, on the reference grid. - private int tileH; - - /// Constructs a new tiler with the specified 'BlkImgDataSrc' source, - /// image origin, tiling origin and nominal tile size. - /// - /// - /// The 'BlkImgDataSrc' source from where to get the image - /// data. It must not be tiled and the image origin must be at '(0,0)' on - /// its canvas. - /// - /// - /// The horizontal coordinate of the image origin in the canvas - /// system, on the reference grid (i.e. the image's top-left corner in the - /// reference grid). - /// - /// - /// The vertical coordinate of the image origin in the canvas - /// system, on the reference grid (i.e. the image's top-left corner in the - /// reference grid). - /// - /// - /// The horizontal tiling origin, in the canvas system, on the - /// reference grid. It must satisfy 'px<=ax'. - /// - /// - /// The vertical tiling origin, in the canvas system, on the - /// reference grid. It must satisfy 'py<=ay'. - /// - /// - /// The nominal tile width, on the reference grid. If 0 then - /// there is no tiling in that direction. - /// - /// - /// The nominal tile height, on the reference grid. If 0 then - /// there is no tiling in that direction. - /// - /// - /// If src is tiled or "canvased", or - /// if the arguments do not satisfy the specified constraints. - /// - /// - public Tiler(BlkImgDataSrc src, int ax, int ay, int px, int py, int nw, int nh):base(src) - { - - // Initialize - this.src = src; - this.x0siz = ax; - this.y0siz = ay; - this.xt0siz = px; - this.yt0siz = py; - this.xtsiz = nw; - this.ytsiz = nh; - - // Verify that input is not tiled - if (src.getNumTiles() != 1) - { - throw new System.ArgumentException("Source is tiled"); - } - // Verify that source is not "canvased" - if (src.ImgULX != 0 || src.ImgULY != 0) - { - throw new System.ArgumentException("Source is \"canvased\""); - } - // Verify that arguments satisfy trivial requirements - if (x0siz < 0 || y0siz < 0 || xt0siz < 0 || yt0siz < 0 || xtsiz < 0 || ytsiz < 0 || xt0siz > x0siz || yt0siz > y0siz) - { - throw new System.ArgumentException("Invalid image origin, " + "tiling origin or nominal " + "tile size"); - } - - // If no tiling has been specified, creates a unique tile with maximum - // dimension. - if (xtsiz == 0) - xtsiz = x0siz + src.ImgWidth - xt0siz; - if (ytsiz == 0) - ytsiz = y0siz + src.ImgHeight - yt0siz; - - // Automatically adjusts xt0siz,yt0siz so that tile (0,0) always - // overlaps with the image. - if (x0siz - xt0siz >= xtsiz) - { - xt0siz += ((x0siz - xt0siz) / xtsiz) * xtsiz; - } - if (y0siz - yt0siz >= ytsiz) - { - yt0siz += ((y0siz - yt0siz) / ytsiz) * ytsiz; - } - if (x0siz - xt0siz >= xtsiz || y0siz - yt0siz >= ytsiz) - { - FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.INFO, "Automatically adjusted tiling " + "origin to equivalent one (" + xt0siz + "," + yt0siz + ") so that " + "first tile overlaps the image"); - } - - // Calculate the number of tiles - //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'" - ntX = (int) System.Math.Ceiling((x0siz + src.ImgWidth) / (double) xtsiz); - //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'" - ntY = (int) System.Math.Ceiling((y0siz + src.ImgHeight) / (double) ytsiz); - } - - /// Returns the width in pixels of the specified tile-component. - /// - /// - /// Tile index - /// - /// - /// The index of the component, from 0 to N-1. - /// - /// - /// The width of specified tile-component. - /// - /// - public override int getTileCompWidth(int t, int c) - { - if (t != TileIdx) - { - throw new System.ApplicationException("Asking the width of a tile-component which is " + "not in the current tile (call setTile() or " + "nextTile() methods before)."); - } - return compW[c]; - } - - /// Returns the height in pixels of the specified tile-component. - /// - /// - /// The tile index. - /// - /// - /// The index of the component, from 0 to N-1. - /// - /// - /// The height of specified tile-component. - /// - /// - public override int getTileCompHeight(int t, int c) - { - if (t != TileIdx) - { - throw new System.ApplicationException("Asking the width of a tile-component which is " + "not in the current tile (call setTile() or " + "nextTile() methods before)."); - } - return compH[c]; - } - - /// Returns the position of the fixed point in the specified - /// component. This is the position of the least significant integral - /// (i.e. non-fractional) bit, which is equivalent to the number of - /// fractional bits. For instance, for fixed-point values with 2 fractional - /// bits, 2 is returned. For floating-point data this value does not apply - /// and 0 should be returned. Position 0 is the position of the least - /// significant bit in the data. - /// - /// - /// The index of the component. - /// - /// - /// The position of the fixed-point, which is the same as the - /// number of fractional bits. For floating-point data 0 is returned. - /// - /// - public virtual int getFixedPoint(int c) - { - return src.getFixedPoint(c); - } - - /// Returns, in the blk argument, a block of image data containing the - /// specifed rectangular area, in the specified component. The data is - /// returned, as a reference to the internal data, if any, instead of as a - /// copy, therefore the returned data should not be modified. - /// - ///

The rectangular area to return is specified by the 'ulx', 'uly', 'w' - /// and 'h' members of the 'blk' argument, relative to the current - /// tile. These members are not modified by this method. The 'offset' and - /// 'scanw' of the returned data can be arbitrary. See the 'DataBlk' - /// class.

- /// - ///

This method, in general, is more efficient than the 'getCompData()' - /// method since it may not copy the data. However if the array of returned - /// data is to be modified by the caller then the other method is probably - /// preferable.

- /// - ///

If the data array in blk is null, then a new one - /// is created if necessary. The implementation of this interface may - /// choose to return the same array or a new one, depending on what is more - /// efficient. Therefore, the data array in blk prior to the - /// method call should not be considered to contain the returned data, a - /// new array may have been created. Instead, get the array from - /// blk after the method has returned.

- /// - ///

The returned data may have its 'progressive' attribute set. In this - /// case the returned data is only an approximation of the "final" - /// data.

- /// - ///
- /// Its coordinates and dimensions specify the area to return, - /// relative to the current tile. Some fields in this object are modified - /// to return the data. - /// - /// - /// The index of the component from which to get the data. - /// - /// - /// The requested DataBlk - /// - /// - /// - /// - /// - public DataBlk getInternCompData(DataBlk blk, int c) - { - // Check that block is inside tile - if (blk.ulx < 0 || blk.uly < 0 || blk.w > compW[c] || blk.h > compH[c]) - { - throw new System.ArgumentException("Block is outside the tile"); - } - // Translate to the sources coordinates - //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'" - int incx = (int) System.Math.Ceiling(x0siz / (double) src.getCompSubsX(c)); - //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'" - int incy = (int) System.Math.Ceiling(y0siz / (double) src.getCompSubsY(c)); - blk.ulx -= incx; - blk.uly -= incy; - blk = src.getInternCompData(blk, c); - // Translate back to the tiled coordinates - blk.ulx += incx; - blk.uly += incy; - return blk; - } - - /// Returns, in the blk argument, a block of image data containing the - /// specifed rectangular area, in the specified component. The data is - /// returned, as a copy of the internal data, therefore the returned data - /// can be modified "in place". - /// - ///

The rectangular area to return is specified by the 'ulx', 'uly', 'w' - /// and 'h' members of the 'blk' argument, relative to the current - /// tile. These members are not modified by this method. The 'offset' of - /// the returned data is 0, and the 'scanw' is the same as the block's - /// width. See the 'DataBlk' class.

- /// - ///

This method, in general, is less efficient than the - /// 'getInternCompData()' method since, in general, it copies the - /// data. However if the array of returned data is to be modified by the - /// caller then this method is preferable.

- /// - ///

If the data array in 'blk' is 'null', then a new one is created. If - /// the data array is not 'null' then it is reused, and it must be large - /// enough to contain the block's data. Otherwise an 'ArrayStoreException' - /// or an 'IndexOutOfBoundsException' is thrown by the Java system.

- /// - ///

The returned data may have its 'progressive' attribute set. In this - /// case the returned data is only an approximation of the "final" - /// data.

- /// - ///
- /// Its coordinates and dimensions specify the area to return, - /// relative to the current tile. If it contains a non-null data array, - /// then it must be large enough. If it contains a null data array a new - /// one is created. Some fields in this object are modified to return the - /// data. - /// - /// - /// The index of the component from which to get the data. - /// - /// - /// The requested DataBlk - /// - /// - /// - /// - /// - public DataBlk getCompData(DataBlk blk, int c) - { - // Check that block is inside tile - if (blk.ulx < 0 || blk.uly < 0 || blk.w > compW[c] || blk.h > compH[c]) - { - throw new System.ArgumentException("Block is outside the tile"); - } - // Translate to the source's coordinates - //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'" - int incx = (int) System.Math.Ceiling(x0siz / (double) src.getCompSubsX(c)); - //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'" - int incy = (int) System.Math.Ceiling(y0siz / (double) src.getCompSubsY(c)); - blk.ulx -= incx; - blk.uly -= incy; - blk = src.getCompData(blk, c); - // Translate back to the tiled coordinates - blk.ulx += incx; - blk.uly += incy; - return blk; - } - - /// Changes the current tile, given the new tile indexes. An - /// IllegalArgumentException is thrown if the coordinates do not correspond - /// to a valid tile. - /// - /// - /// The horizontal index of the tile. - /// - /// - /// The vertical index of the new tile. - /// - /// - public override void setTile(int x, int y) - { - // Check tile indexes - if (x < 0 || y < 0 || x >= ntX || y >= ntY) - { - throw new System.ArgumentException("Tile's indexes out of bounds"); - } - - // Set new current tile - tx = x; - ty = y; - // Calculate tile origins - int tx0 = (x != 0)?xt0siz + x * xtsiz:x0siz; - int ty0 = (y != 0)?yt0siz + y * ytsiz:y0siz; - int tx1 = (x != ntX - 1)?(xt0siz + (x + 1) * xtsiz):(x0siz + src.ImgWidth); - int ty1 = (y != ntY - 1)?(yt0siz + (y + 1) * ytsiz):(y0siz + src.ImgHeight); - // Set general variables - tileW = tx1 - tx0; - tileH = ty1 - ty0; - // Set component specific variables - int nc = src.NumComps; - if (compW == null) - compW = new int[nc]; - if (compH == null) - compH = new int[nc]; - if (tcx0 == null) - tcx0 = new int[nc]; - if (tcy0 == null) - tcy0 = new int[nc]; - for (int i = 0; i < nc; i++) - { - //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'" - tcx0[i] = (int) System.Math.Ceiling(tx0 / (double) src.getCompSubsX(i)); - //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'" - tcy0[i] = (int) System.Math.Ceiling(ty0 / (double) src.getCompSubsY(i)); - //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'" - compW[i] = (int) System.Math.Ceiling(tx1 / (double) src.getCompSubsX(i)) - tcx0[i]; - //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'" - compH[i] = (int) System.Math.Ceiling(ty1 / (double) src.getCompSubsY(i)) - tcy0[i]; - } - } - - /// Advances to the next tile, in standard scan-line order (by rows then - /// columns). An NoNextElementException is thrown if the current tile is - /// the last one (i.e. there is no next tile). - /// - /// - public override void nextTile() - { - if (tx == ntX - 1 && ty == ntY - 1) - { - // Already at last tile - throw new NoNextElementException(); - } - else if (tx < ntX - 1) - { - // If not at end of current tile line - setTile(tx + 1, ty); - } - else - { - // First tile at next line - setTile(0, ty + 1); - } - } - - /// Returns the horizontal and vertical indexes of the current tile. - /// - /// - /// If not null this object is used to return the - /// information. If null a new one is created and returned. - /// - /// - /// The current tile's horizontal and vertical indexes.. - /// - /// - public override Coord getTile(Coord co) - { - if (co != null) - { - co.x = tx; - co.y = ty; - return co; - } - else - { - return new Coord(tx, ty); - } - } - - /// Returns the horizontal coordinate of the upper-left corner of the - /// specified component in the current tile. - /// - /// - /// The component index. - /// - /// - public override int getCompULX(int c) - { - return tcx0[c]; - } - - /// Returns the vertical coordinate of the upper-left corner of the - /// specified component in the current tile. - /// - /// - /// The component index. - /// - /// - public override int getCompULY(int c) - { - return tcy0[c]; - } - - /// Returns the number of tiles in the horizontal and vertical directions. - /// - /// - /// If not null this object is used to return the information. If - /// null a new one is created and returned. - /// - /// - /// The number of tiles in the horizontal (Coord.x) and vertical - /// (Coord.y) directions. - /// - /// - public override Coord getNumTiles(Coord co) - { - if (co != null) - { - co.x = ntX; - co.y = ntY; - return co; - } - else - { - return new Coord(ntX, ntY); - } - } - - /// Returns the total number of tiles in the image. - /// - /// - /// The total number of tiles in the image. - /// - /// - public override int getNumTiles() - { - return ntX * ntY; - } - - /// Returns the tiling origin, referred to as '(xt0siz,yt0siz)' in the - /// codestream header (SIZ marker segment). - /// - /// - /// If not null this object is used to return the information. If - /// null a new one is created and returned. - /// - /// - /// The coordinate of the tiling origin, in the canvas system, on - /// the reference grid. - /// - /// - /// - /// - /// - public Coord getTilingOrigin(Coord co) - { - if (co != null) - { - co.x = xt0siz; - co.y = yt0siz; - return co; - } - else - { - return new Coord(xt0siz, yt0siz); - } - } - - /// Returns a String object representing Tiler's informations - /// - /// - /// Tiler's infos in a string - /// - /// - public override System.String ToString() - { - //UPGRADE_TODO: The equivalent in .NET for method 'java.lang.Object.toString' may return a different value. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1043'" - return "Tiler: source= " + src + "\n" + getNumTiles() + " tile(s), nominal width=" + xtsiz + ", nominal height=" + ytsiz; - } - } -} \ No newline at end of file + + /// This class places an image in the canvas coordinate system, tiles it, if so + /// specified, and performs the coordinate conversions transparently. The + /// source must be a 'BlkImgDataSrc' which is not tiled and has a the image + /// origin at the canvas origin (i.e. it is not "canvased"), or an exception is + /// thrown by the constructor. A tiled and "canvased" output is given through + /// the 'BlkImgDataSrc' interface. See the 'ImgData' interface for a + /// description of the canvas and tiling. + /// + ///

All tiles produced are rectangular, non-overlapping and their union + /// covers all the image. However, the tiling may not be uniform, depending on + /// the nominal tile size, tiling origin, component subsampling and other + /// factors. Therefore it might not be assumed that all tiles are of the same + /// width and height.

+ /// + ///

The nominal dimension of the tiles is the maximal one, in the reference + /// grid. All the components of the image have the same number of tiles.

+ /// + ///
+ /// + /// + /// + /// + /// + public class Tiler : ImgDataAdapter, BlkImgDataSrc + { + /// Returns the overall width of the current tile in pixels. This is the + /// tile's width without accounting for any component subsampling. + /// + /// + /// The total current tile width in pixels. + /// + /// + public override int TileWidth + { + get + { + return tileW; + } + + } + + /// Returns the overall height of the current tile in pixels. This is the + /// tile's width without accounting for any component subsampling. + /// + /// + /// The total current tile height in pixels. + /// + /// + public override int TileHeight + { + get + { + return tileH; + } + + } + + /// Returns the index of the current tile, relative to a standard scan-line + /// order. + /// + /// + /// The current tile's index (starts at 0). + /// + /// + public override int TileIdx + { + get + { + return ty * ntX + tx; + } + + } + + /// Returns the horizontal tile partition offset in the reference grid + public override int TilePartULX + { + get + { + return xt0siz; + } + + } + + /// Returns the vertical tile partition offset in the reference grid + public override int TilePartULY + { + get + { + return yt0siz; + } + + } + + /// Returns the horizontal coordinate of the image origin, the top-left + /// corner, in the canvas system, on the reference grid. + /// + /// + /// The horizontal coordinate of the image origin in the canvas + /// system, on the reference grid. + /// + /// + public override int ImgULX + { + get + { + return x0siz; + } + + } + + /// Returns the vertical coordinate of the image origin, the top-left + /// corner, in the canvas system, on the reference grid. + /// + /// + /// The vertical coordinate of the image origin in the canvas + /// system, on the reference grid. + /// + /// + public override int ImgULY + { + get + { + return y0siz; + } + + } + + /// Returns the nominal width of the tiles in the reference grid. + /// + /// + /// The nominal tile width, in the reference grid. + /// + /// + public override int NomTileWidth + { + get + { + return xtsiz; + } + + } + + /// Returns the nominal width of the tiles in the reference grid. + /// + /// + /// The nominal tile width, in the reference grid. + /// + /// + public override int NomTileHeight + { + get + { + return ytsiz; + } + + } + + /// The source of image data + private BlkImgDataSrc src = null; + + /// Horizontal coordinate of the upper left hand reference grid point. + private int x0siz; + + /// Vertical coordinate of the upper left hand reference grid point. + private int y0siz; + + /// The horizontal coordinate of the tiling origin in the canvas system, + /// on the reference grid. + /// + private int xt0siz; + + /// The vertical coordinate of the tiling origin in the canvas system, on + /// the reference grid. + /// + private int yt0siz; + + /// The nominal width of the tiles, on the reference grid. If 0 then there + /// is no tiling in that direction. + /// + private int xtsiz; + + /// The nominal height of the tiles, on the reference grid. If 0 then + /// there is no tiling in that direction. + /// + private int ytsiz; + + /// The number of tiles in the horizontal direction. + private int ntX; + + /// The number of tiles in the vertical direction. + private int ntY; + + /// The component width in the current active tile, for each component + private int[] compW = null; + + /// The component height in the current active tile, for each component + private int[] compH = null; + + /// The horizontal coordinates of the upper-left corner of the components + /// in the current tile + /// + private int[] tcx0 = null; + + /// The vertical coordinates of the upper-left corner of the components in + /// the current tile. + /// + private int[] tcy0 = null; + + /// The horizontal index of the current tile + private int tx; + + /// The vertical index of the current tile + private int ty; + + /// The width of the current tile, on the reference grid. + private int tileW; + + /// The height of the current tile, on the reference grid. + private int tileH; + + /// Constructs a new tiler with the specified 'BlkImgDataSrc' source, + /// image origin, tiling origin and nominal tile size. + /// + /// + /// The 'BlkImgDataSrc' source from where to get the image + /// data. It must not be tiled and the image origin must be at '(0,0)' on + /// its canvas. + /// + /// + /// The horizontal coordinate of the image origin in the canvas + /// system, on the reference grid (i.e. the image's top-left corner in the + /// reference grid). + /// + /// + /// The vertical coordinate of the image origin in the canvas + /// system, on the reference grid (i.e. the image's top-left corner in the + /// reference grid). + /// + /// + /// The horizontal tiling origin, in the canvas system, on the + /// reference grid. It must satisfy 'px<=ax'. + /// + /// + /// The vertical tiling origin, in the canvas system, on the + /// reference grid. It must satisfy 'py<=ay'. + /// + /// + /// The nominal tile width, on the reference grid. If 0 then + /// there is no tiling in that direction. + /// + /// + /// The nominal tile height, on the reference grid. If 0 then + /// there is no tiling in that direction. + /// + /// + /// If src is tiled or "canvased", or + /// if the arguments do not satisfy the specified constraints. + /// + /// + public Tiler(BlkImgDataSrc src, int ax, int ay, int px, int py, int nw, int nh) + : base(src) + { + + // Initialize + this.src = src; + this.x0siz = ax; + this.y0siz = ay; + this.xt0siz = px; + this.yt0siz = py; + this.xtsiz = nw; + this.ytsiz = nh; + + // Verify that input is not tiled + if (src.getNumTiles() != 1) + { + throw new System.ArgumentException("Source is tiled"); + } + // Verify that source is not "canvased" + if (src.ImgULX != 0 || src.ImgULY != 0) + { + throw new System.ArgumentException("Source is \"canvased\""); + } + // Verify that arguments satisfy trivial requirements + if (x0siz < 0 || y0siz < 0 || xt0siz < 0 || yt0siz < 0 || xtsiz < 0 || ytsiz < 0 || xt0siz > x0siz + || yt0siz > y0siz) + { + throw new System.ArgumentException("Invalid image origin, " + "tiling origin or nominal " + "tile size"); + } + + // If no tiling has been specified, creates a unique tile with maximum + // dimension. + if (xtsiz == 0) xtsiz = x0siz + src.ImgWidth - xt0siz; + if (ytsiz == 0) ytsiz = y0siz + src.ImgHeight - yt0siz; + + // Automatically adjusts xt0siz,yt0siz so that tile (0,0) always + // overlaps with the image. + if (x0siz - xt0siz >= xtsiz) + { + xt0siz += ((x0siz - xt0siz) / xtsiz) * xtsiz; + } + if (y0siz - yt0siz >= ytsiz) + { + yt0siz += ((y0siz - yt0siz) / ytsiz) * ytsiz; + } + if (x0siz - xt0siz >= xtsiz || y0siz - yt0siz >= ytsiz) + { + FacilityManager.getMsgLogger() + .printmsg( + CSJ2K.j2k.util.MsgLogger_Fields.INFO, + "Automatically adjusted tiling " + "origin to equivalent one (" + xt0siz + "," + yt0siz + + ") so that " + "first tile overlaps the image"); + } + + // Calculate the number of tiles + //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'" + ntX = (int)System.Math.Ceiling((x0siz + src.ImgWidth) / (double)xtsiz); + //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'" + ntY = (int)System.Math.Ceiling((y0siz + src.ImgHeight) / (double)ytsiz); + } + + /// Returns the width in pixels of the specified tile-component. + /// + /// + /// Tile index + /// + /// + /// The index of the component, from 0 to N-1. + /// + /// + /// The width of specified tile-component. + /// + /// + public override int getTileCompWidth(int t, int c) + { + if (t != TileIdx) + { + throw new System.InvalidOperationException( + "Asking the width of a tile-component which is " + "not in the current tile (call setTile() or " + + "nextTile() methods before)."); + } + return compW[c]; + } + + /// Returns the height in pixels of the specified tile-component. + /// + /// + /// The tile index. + /// + /// + /// The index of the component, from 0 to N-1. + /// + /// + /// The height of specified tile-component. + /// + /// + public override int getTileCompHeight(int t, int c) + { + if (t != TileIdx) + { + throw new System.InvalidOperationException( + "Asking the width of a tile-component which is " + "not in the current tile (call setTile() or " + + "nextTile() methods before)."); + } + return compH[c]; + } + + /// Returns the position of the fixed point in the specified + /// component. This is the position of the least significant integral + /// (i.e. non-fractional) bit, which is equivalent to the number of + /// fractional bits. For instance, for fixed-point values with 2 fractional + /// bits, 2 is returned. For floating-point data this value does not apply + /// and 0 should be returned. Position 0 is the position of the least + /// significant bit in the data. + /// + /// + /// The index of the component. + /// + /// + /// The position of the fixed-point, which is the same as the + /// number of fractional bits. For floating-point data 0 is returned. + /// + /// + public virtual int getFixedPoint(int c) + { + return src.getFixedPoint(c); + } + + /// Returns, in the blk argument, a block of image data containing the + /// specifed rectangular area, in the specified component. The data is + /// returned, as a reference to the internal data, if any, instead of as a + /// copy, therefore the returned data should not be modified. + /// + ///

The rectangular area to return is specified by the 'ulx', 'uly', 'w' + /// and 'h' members of the 'blk' argument, relative to the current + /// tile. These members are not modified by this method. The 'offset' and + /// 'scanw' of the returned data can be arbitrary. See the 'DataBlk' + /// class.

+ /// + ///

This method, in general, is more efficient than the 'getCompData()' + /// method since it may not copy the data. However if the array of returned + /// data is to be modified by the caller then the other method is probably + /// preferable.

+ /// + ///

If the data array in blk is null, then a new one + /// is created if necessary. The implementation of this interface may + /// choose to return the same array or a new one, depending on what is more + /// efficient. Therefore, the data array in blk prior to the + /// method call should not be considered to contain the returned data, a + /// new array may have been created. Instead, get the array from + /// blk after the method has returned.

+ /// + ///

The returned data may have its 'progressive' attribute set. In this + /// case the returned data is only an approximation of the "final" + /// data.

+ /// + ///
+ /// Its coordinates and dimensions specify the area to return, + /// relative to the current tile. Some fields in this object are modified + /// to return the data. + /// + /// + /// The index of the component from which to get the data. + /// + /// + /// The requested DataBlk + /// + /// + /// + /// + /// + public DataBlk getInternCompData(DataBlk blk, int c) + { + // Check that block is inside tile + if (blk.ulx < 0 || blk.uly < 0 || blk.w > compW[c] || blk.h > compH[c]) + { + throw new System.ArgumentException("Block is outside the tile"); + } + // Translate to the sources coordinates + //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'" + int incx = (int)System.Math.Ceiling(x0siz / (double)src.getCompSubsX(c)); + //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'" + int incy = (int)System.Math.Ceiling(y0siz / (double)src.getCompSubsY(c)); + blk.ulx -= incx; + blk.uly -= incy; + blk = src.getInternCompData(blk, c); + // Translate back to the tiled coordinates + blk.ulx += incx; + blk.uly += incy; + return blk; + } + + /// Returns, in the blk argument, a block of image data containing the + /// specifed rectangular area, in the specified component. The data is + /// returned, as a copy of the internal data, therefore the returned data + /// can be modified "in place". + /// + ///

The rectangular area to return is specified by the 'ulx', 'uly', 'w' + /// and 'h' members of the 'blk' argument, relative to the current + /// tile. These members are not modified by this method. The 'offset' of + /// the returned data is 0, and the 'scanw' is the same as the block's + /// width. See the 'DataBlk' class.

+ /// + ///

This method, in general, is less efficient than the + /// 'getInternCompData()' method since, in general, it copies the + /// data. However if the array of returned data is to be modified by the + /// caller then this method is preferable.

+ /// + ///

If the data array in 'blk' is 'null', then a new one is created. If + /// the data array is not 'null' then it is reused, and it must be large + /// enough to contain the block's data. Otherwise an 'ArrayStoreException' + /// or an 'IndexOutOfBoundsException' is thrown by the Java system.

+ /// + ///

The returned data may have its 'progressive' attribute set. In this + /// case the returned data is only an approximation of the "final" + /// data.

+ /// + ///
+ /// Its coordinates and dimensions specify the area to return, + /// relative to the current tile. If it contains a non-null data array, + /// then it must be large enough. If it contains a null data array a new + /// one is created. Some fields in this object are modified to return the + /// data. + /// + /// + /// The index of the component from which to get the data. + /// + /// + /// The requested DataBlk + /// + /// + /// + /// + /// + public DataBlk getCompData(DataBlk blk, int c) + { + // Check that block is inside tile + if (blk.ulx < 0 || blk.uly < 0 || blk.w > compW[c] || blk.h > compH[c]) + { + throw new System.ArgumentException("Block is outside the tile"); + } + // Translate to the source's coordinates + //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'" + int incx = (int)System.Math.Ceiling(x0siz / (double)src.getCompSubsX(c)); + //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'" + int incy = (int)System.Math.Ceiling(y0siz / (double)src.getCompSubsY(c)); + blk.ulx -= incx; + blk.uly -= incy; + blk = src.getCompData(blk, c); + // Translate back to the tiled coordinates + blk.ulx += incx; + blk.uly += incy; + return blk; + } + + /// Closes the underlying file or network connection from where the + /// image data is being read. + /// + /// + /// If an I/O error occurs. + /// + public void close() + { + // Do nothing. + } + + /// Returns true if the data read was originally signed in the specified + /// component, false if not. + /// + /// + /// The index of the component, from 0 to C-1. + /// + /// + /// true if the data was originally signed, false if not. + /// + /// + public bool isOrigSigned(int c) + { + return false; + } + + /// Changes the current tile, given the new tile indexes. An + /// IllegalArgumentException is thrown if the coordinates do not correspond + /// to a valid tile. + /// + /// + /// The horizontal index of the tile. + /// + /// + /// The vertical index of the new tile. + /// + /// + public override void setTile(int x, int y) + { + // Check tile indexes + if (x < 0 || y < 0 || x >= ntX || y >= ntY) + { + throw new System.ArgumentException("Tile's indexes out of bounds"); + } + + // Set new current tile + tx = x; + ty = y; + // Calculate tile origins + int tx0 = (x != 0) ? xt0siz + x * xtsiz : x0siz; + int ty0 = (y != 0) ? yt0siz + y * ytsiz : y0siz; + int tx1 = (x != ntX - 1) ? (xt0siz + (x + 1) * xtsiz) : (x0siz + src.ImgWidth); + int ty1 = (y != ntY - 1) ? (yt0siz + (y + 1) * ytsiz) : (y0siz + src.ImgHeight); + // Set general variables + tileW = tx1 - tx0; + tileH = ty1 - ty0; + // Set component specific variables + int nc = src.NumComps; + if (compW == null) compW = new int[nc]; + if (compH == null) compH = new int[nc]; + if (tcx0 == null) tcx0 = new int[nc]; + if (tcy0 == null) tcy0 = new int[nc]; + for (int i = 0; i < nc; i++) + { + //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'" + tcx0[i] = (int)System.Math.Ceiling(tx0 / (double)src.getCompSubsX(i)); + //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'" + tcy0[i] = (int)System.Math.Ceiling(ty0 / (double)src.getCompSubsY(i)); + //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'" + compW[i] = (int)System.Math.Ceiling(tx1 / (double)src.getCompSubsX(i)) - tcx0[i]; + //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'" + compH[i] = (int)System.Math.Ceiling(ty1 / (double)src.getCompSubsY(i)) - tcy0[i]; + } + } + + /// Advances to the next tile, in standard scan-line order (by rows then + /// columns). An NoNextElementException is thrown if the current tile is + /// the last one (i.e. there is no next tile). + /// + /// + public override void nextTile() + { + if (tx == ntX - 1 && ty == ntY - 1) + { + // Already at last tile + throw new NoNextElementException(); + } + else if (tx < ntX - 1) + { + // If not at end of current tile line + setTile(tx + 1, ty); + } + else + { + // First tile at next line + setTile(0, ty + 1); + } + } + + /// Returns the horizontal and vertical indexes of the current tile. + /// + /// + /// If not null this object is used to return the + /// information. If null a new one is created and returned. + /// + /// + /// The current tile's horizontal and vertical indexes.. + /// + /// + public override Coord getTile(Coord co) + { + if (co != null) + { + co.x = tx; + co.y = ty; + return co; + } + else + { + return new Coord(tx, ty); + } + } + + /// Returns the horizontal coordinate of the upper-left corner of the + /// specified component in the current tile. + /// + /// + /// The component index. + /// + /// + public override int getCompULX(int c) + { + return tcx0[c]; + } + + /// Returns the vertical coordinate of the upper-left corner of the + /// specified component in the current tile. + /// + /// + /// The component index. + /// + /// + public override int getCompULY(int c) + { + return tcy0[c]; + } + + /// Returns the number of tiles in the horizontal and vertical directions. + /// + /// + /// If not null this object is used to return the information. If + /// null a new one is created and returned. + /// + /// + /// The number of tiles in the horizontal (Coord.x) and vertical + /// (Coord.y) directions. + /// + /// + public override Coord getNumTiles(Coord co) + { + if (co != null) + { + co.x = ntX; + co.y = ntY; + return co; + } + else + { + return new Coord(ntX, ntY); + } + } + + /// Returns the total number of tiles in the image. + /// + /// + /// The total number of tiles in the image. + /// + /// + public override int getNumTiles() + { + return ntX * ntY; + } + + /// Returns the tiling origin, referred to as '(xt0siz,yt0siz)' in the + /// codestream header (SIZ marker segment). + /// + /// + /// If not null this object is used to return the information. If + /// null a new one is created and returned. + /// + /// + /// The coordinate of the tiling origin, in the canvas system, on + /// the reference grid. + /// + /// + /// + /// + /// + public Coord getTilingOrigin(Coord co) + { + if (co != null) + { + co.x = xt0siz; + co.y = yt0siz; + return co; + } + else + { + return new Coord(xt0siz, yt0siz); + } + } + + /// Returns a String object representing Tiler's informations + /// + /// + /// Tiler's infos in a string + /// + /// + public override System.String ToString() + { + //UPGRADE_TODO: The equivalent in .NET for method 'java.lang.Object.toString' may return a different value. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1043'" + return "Tiler: source= " + src + "\n" + getNumTiles() + " tile(s), nominal width=" + xtsiz + + ", nominal height=" + ytsiz; + } + } +} diff --git a/CSJ2K/j2k/image/forwcomptransf/ForwCompTransf.cs b/CSJ2K/j2k/image/forwcomptransf/ForwCompTransf.cs index 00af357f..c52a540d 100644 --- a/CSJ2K/j2k/image/forwcomptransf/ForwCompTransf.cs +++ b/CSJ2K/j2k/image/forwcomptransf/ForwCompTransf.cs @@ -441,8 +441,34 @@ public virtual DataBlk getCompData(DataBlk blk, int c) return getInternCompData(blk, c); } } - - /// Apply the component transformation associated with the current tile. If + + /// Closes the underlying file or network connection from where the + /// image data is being read. + /// + /// + /// If an I/O error occurs. + /// + public void close() + { + // Do nothing. + } + + /// Returns true if the data read was originally signed in the specified + /// component, false if not. + /// + /// + /// The index of the component, from 0 to C-1. + /// + /// + /// true if the data was originally signed, false if not. + /// + /// + public bool isOrigSigned(int c) + { + return false; + } + + /// Apply the component transformation associated with the current tile. If /// no component transformation has been requested by the user, data are /// not modified. Else, appropriate method is called (forwRCT or forwICT). /// diff --git a/CSJ2K/j2k/image/input/ImgReader.cs b/CSJ2K/j2k/image/input/ImgReader.cs index 7de37453..aecb5110 100644 --- a/CSJ2K/j2k/image/input/ImgReader.cs +++ b/CSJ2K/j2k/image/input/ImgReader.cs @@ -308,7 +308,7 @@ public virtual int getTileCompWidth(int t, int c) { if (t != 0) { - throw new System.ApplicationException("Asking a tile-component width for a tile index" + " greater than 0 whereas there is only one tile"); + throw new System.InvalidOperationException("Asking a tile-component width for a tile index" + " greater than 0 whereas there is only one tile"); } return w; } @@ -333,7 +333,7 @@ public virtual int getTileCompHeight(int t, int c) { if (t != 0) { - throw new System.ApplicationException("Asking a tile-component width for a tile index" + " greater than 0 whereas there is only one tile"); + throw new System.InvalidOperationException("Asking a tile-component width for a tile index" + " greater than 0 whereas there is only one tile"); } return h; } @@ -502,9 +502,9 @@ public virtual int getNumTiles() /// /// public abstract bool isOrigSigned(int c); - public abstract int getFixedPoint(int param1); - public abstract CSJ2K.j2k.image.DataBlk getInternCompData(CSJ2K.j2k.image.DataBlk param1, int param2); - public abstract int getNomRangeBits(int param1); - public abstract CSJ2K.j2k.image.DataBlk getCompData(CSJ2K.j2k.image.DataBlk param1, int param2); + public abstract int getFixedPoint(int c); + public abstract DataBlk getInternCompData(DataBlk blk, int c); + public abstract int getNomRangeBits(int c); + public abstract DataBlk getCompData(DataBlk blk, int c); } } \ No newline at end of file diff --git a/CSJ2K/j2k/image/input/ImgReaderGDI.cs b/CSJ2K/j2k/image/input/ImgReaderGDI.cs deleted file mode 100644 index fc00ee55..00000000 --- a/CSJ2K/j2k/image/input/ImgReaderGDI.cs +++ /dev/null @@ -1,403 +0,0 @@ -/* -* -* Class: ImgWriterGDI -* -* Description: Image writer for System.Drawing.GDI streams -* -* */ - -using System; -using System.Drawing; -using System.Drawing.Imaging; -using System.IO; -using CSJ2K.j2k.image; -using CSJ2K.j2k.io; -using CSJ2K.j2k; - -namespace CSJ2K.j2k.image.input -{ - public class ImgReaderGDI : ImgReader - { - /// The number of bits that determine the nominal dynamic range - private int rb; - - /// Buffer for the components of each pixel(in the current block) - private int[][] barr; - - /// Data block used only to store coordinates of the buffered blocks - private DataBlkInt dbi = new DataBlkInt(); - - /// Temporary DataBlkInt object (needed when encoder uses floating-point - /// filters). This avoid allocating new DataBlk at each time - /// - private DataBlkInt intBlk; - - private Image image; - - public ImgReaderGDI(Image image) - { - if (image.PixelFormat != PixelFormat.Format24bppRgb) - throw new ArgumentException("Only 24bpp RGB images are currently supported"); - - this.image = image; - - w = image.Width; - h = image.Height; - - nc = 3; - rb = 8; - } - - /// Closes the underlying file from where the image data is being read. No - /// operations are possible after a call to this method. - /// - /// - /// If an I/O error occurs. - /// - /// - public override void close() - { - image.Dispose(); - image = null; - - barr = null; - } - - /// Returns the number of bits corresponding to the nominal range of the - /// data in the specified component. This is the value rb (range bits) that - /// was specified in the constructor, which normally is 8 for non bilevel - /// data, and 1 for bilevel data. - /// - ///

If this number is b then the nominal range is between - /// -2^(b-1) and 2^(b-1)-1, since unsigned data is level shifted to have a - /// nominal avergae of 0. - /// - ///

- /// The index of the component. - /// - /// - /// The number of bits corresponding to the nominal range of the - /// data. For floating-point data this value is not applicable and the - /// return value is undefined. - /// - /// - public override int getNomRangeBits(int c) - { - // Check component index - if (c < 0 || c > 2) - throw new System.ArgumentException(); - - return rb; - } - - /// Returns the position of the fixed point in the specified component - /// (i.e. the number of fractional bits), which is always 0 for this - /// ImgReader. - /// - /// - /// The index of the component. - /// - /// - /// The position of the fixed-point (i.e. the number of fractional - /// bits). Always 0 for this ImgReader. - /// - /// - public override int getFixedPoint(int c) - { - // Check component index - if (c < 0 || c > 2) - throw new System.ArgumentException(); - return 0; - } - - /// Returns, in the blk argument, the block of image data containing the - /// specifed rectangular area, in the specified component. The data is - /// returned, as a reference to the internal data, if any, instead of as a - /// copy, therefore the returned data should not be modified. - /// - ///

After being read the coefficients are level shifted by subtracting - /// 2^(nominal bit range - 1) - /// - ///

The rectangular area to return is specified by the 'ulx', 'uly', 'w' - /// and 'h' members of the 'blk' argument, relative to the current - /// tile. These members are not modified by this method. The 'offset' and - /// 'scanw' of the returned data can be arbitrary. See the 'DataBlk' class. - /// - ///

If the data array in blk is null, then a new one - /// is created if necessary. The implementation of this interface may - /// choose to return the same array or a new one, depending on what is more - /// efficient. Therefore, the data array in blk prior to the - /// method call should not be considered to contain the returned data, a - /// new array may have been created. Instead, get the array from - /// blk after the method has returned. - /// - ///

The returned data always has its 'progressive' attribute unset - /// (i.e. false). - /// - ///

When an I/O exception is encountered the JJ2KExceptionHandler is - /// used. The exception is passed to its handleException method. The action - /// that is taken depends on the action that has been registered in - /// JJ2KExceptionHandler. See JJ2KExceptionHandler for details. - /// - ///

This method implements buffering for the 3 components: When the - /// first one is asked, all the 3 components are read and stored until they - /// are needed. - /// - ///

- /// Its coordinates and dimensions specify the area to - /// return. Some fields in this object are modified to return the data. - /// - /// - /// The index of the component from which to get the data. Only 0, - /// 1 and 3 are valid. - /// - /// - /// The requested DataBlk - /// - /// - /// - /// - /// - /// - /// - /// - public override DataBlk getInternCompData(DataBlk blk, int c) - { - // Check component index - if (c < 0 || c > 2) - throw new System.ArgumentException(); - - // Check type of block provided as an argument - if (blk.DataType != DataBlk.TYPE_INT) - { - if (intBlk == null) - intBlk = new DataBlkInt(blk.ulx, blk.uly, blk.w, blk.h); - else - { - intBlk.ulx = blk.ulx; - intBlk.uly = blk.uly; - intBlk.w = blk.w; - intBlk.h = blk.h; - } - blk = intBlk; - } - - // If asking a component for the first time for this block, read all of the components - if ((barr == null) || (dbi.ulx > blk.ulx) || (dbi.uly > blk.uly) || (dbi.ulx + dbi.w < blk.ulx + blk.w) || (dbi.uly + dbi.h < blk.uly + blk.h)) - { - int i; - int[] red, green, blue, alpha; - int componentCount = (image.PixelFormat == PixelFormat.Format32bppArgb) ? 4 : 3; - - barr = new int[componentCount][]; - - // Reset data arrays if needed - if (barr[c] == null || barr[c].Length < blk.w * blk.h) - { - barr[c] = new int[blk.w * blk.h]; - } - blk.Data = barr[c]; - - i = (c + 1) % 3; - if (barr[i] == null || barr[i].Length < blk.w * blk.h) - { - barr[i] = new int[blk.w * blk.h]; - } - i = (c + 2) % 3; - if (barr[i] == null || barr[i].Length < blk.w * blk.h) - { - barr[i] = new int[blk.w * blk.h]; - } - - if (componentCount == 4) - { - if (barr[3] == null || barr[3].Length < blk.w * blk.h) - barr[3] = new int[blk.w * blk.h]; - } - - // set attributes of the DataBlk used for buffering - dbi.ulx = blk.ulx; - dbi.uly = blk.uly; - dbi.w = blk.w; - dbi.h = blk.h; - - red = barr[0]; - green = barr[1]; - blue = barr[2]; - alpha = (componentCount == 4) ? barr[3] : null; - - Bitmap bitmap = (Bitmap)image; - BitmapData data = bitmap.LockBits(new Rectangle(blk.ulx, blk.uly, blk.w, blk.h), ImageLockMode.ReadOnly, - (componentCount == 3) ? PixelFormat.Format24bppRgb : PixelFormat.Format32bppArgb); - unsafe - { - byte* ptr = (byte*)data.Scan0.ToPointer(); - - int k = 0; - for (int j = 0; j < blk.w * blk.h; j++) - { - blue[k] = ((byte)*(ptr + 0) & 0xFF) - 128; - green[k] = ((byte)*(ptr + 1) & 0xFF) - 128; - red[k] = ((byte)*(ptr + 2) & 0xFF) - 128; - if (componentCount == 4) - alpha[k] = ((byte)*(ptr + 3) & 0xFF) - 128; - - ++k; - ptr += 3; - } - } - bitmap.UnlockBits(data); - - barr[0] = red; - barr[1] = green; - barr[2] = blue; - if (componentCount == 4) - barr[3] = alpha; - - // Set buffer attributes - blk.Data = barr[c]; - blk.offset = 0; - blk.scanw = blk.w; - } - else - { - //Asking for the 2nd or 3rd (or 4th) block component - blk.Data = barr[c]; - blk.offset = (blk.ulx - dbi.ulx) * dbi.w + blk.ulx - dbi.ulx; - blk.scanw = dbi.scanw; - } - - // Turn off the progressive attribute - blk.progressive = false; - return blk; - } - - /// Returns, in the blk argument, a block of image data containing the - /// specifed rectangular area, in the specified component. The data is - /// returned, as a copy of the internal data, therefore the returned data - /// can be modified "in place". - /// - ///

After being read the coefficients are level shifted by subtracting - /// 2^(nominal bit range - 1) - /// - ///

The rectangular area to return is specified by the 'ulx', 'uly', 'w' - /// and 'h' members of the 'blk' argument, relative to the current - /// tile. These members are not modified by this method. The 'offset' of - /// the returned data is 0, and the 'scanw' is the same as the block's - /// width. See the 'DataBlk' class. - /// - ///

If the data array in 'blk' is 'null', then a new one is created. If - /// the data array is not 'null' then it is reused, and it must be large - /// enough to contain the block's data. Otherwise an 'ArrayStoreException' - /// or an 'IndexOutOfBoundsException' is thrown by the Java system. - /// - ///

The returned data has its 'progressive' attribute unset - /// (i.e. false). - /// - ///

When an I/O exception is encountered the JJ2KExceptionHandler is - /// used. The exception is passed to its handleException method. The action - /// that is taken depends on the action that has been registered in - /// JJ2KExceptionHandler. See JJ2KExceptionHandler for details. - /// - ///

- /// Its coordinates and dimensions specify the area to - /// return. If it contains a non-null data array, then it must have the - /// correct dimensions. If it contains a null data array a new one is - /// created. The fields in this object are modified to return the data. - /// - /// - /// The index of the component from which to get the data. Only - /// 0,1 and 2 are valid. - /// - /// - /// The requested DataBlk - /// - /// - /// - /// - /// - /// - /// - /// - public override DataBlk getCompData(DataBlk blk, int c) - { - // NOTE: can not directly call getInterCompData since that returns - // internally buffered data. - int ulx, uly, w, h; - - // Check type of block provided as an argument - if (blk.DataType != DataBlk.TYPE_INT) - { - DataBlkInt tmp = new DataBlkInt(blk.ulx, blk.uly, blk.w, blk.h); - blk = tmp; - } - - int[] bakarr = (int[])blk.Data; - // Save requested block size - ulx = blk.ulx; - uly = blk.uly; - w = blk.w; - h = blk.h; - // Force internal data buffer to be different from external - blk.Data = null; - getInternCompData(blk, c); - // Copy the data - if (bakarr == null) - { - bakarr = new int[w * h]; - } - if (blk.offset == 0 && blk.scanw == w) - { - // Requested and returned block buffer are the same size - // CONVERSION PROBLEM? - Array.Copy((System.Array)blk.Data, 0, (System.Array)bakarr, 0, w * h); - } - else - { - // Requested and returned block are different - for (int i = h - 1; i >= 0; i--) - { - // copy line by line - // CONVERSION PROBLEM? - Array.Copy((System.Array)blk.Data, blk.offset + i * blk.scanw, (System.Array)bakarr, i * w, w); - } - } - blk.Data = bakarr; - blk.offset = 0; - blk.scanw = blk.w; - return blk; - } - - /// Returns true if the data read was originally signed in the specified - /// component, false if not. This method always returns false since PPM - /// data is always unsigned. - /// - /// - /// The index of the component, from 0 to N-1. - /// - /// - /// always false, since PPM data is always unsigned. - /// - /// - public override bool isOrigSigned(int c) - { - // Check component index - if (c < 0 || c > 2) - throw new System.ArgumentException(); - return false; - } - - /// Returns a string of information about the object, more than 1 line - /// long. The information string includes information from the underlying - /// RandomAccessFile (its toString() method is called in turn). - /// - /// - /// A string of information about the object. - /// - /// - public override System.String ToString() - { - return "ImgReaderGDI: WxH = " + w + "x" + h + ", Component = 0,1,2"; - } - } -} \ No newline at end of file diff --git a/CSJ2K/j2k/image/input/ImgReaderPGM.cs b/CSJ2K/j2k/image/input/ImgReaderPGM.cs index 3540030d..f72a7fce 100644 --- a/CSJ2K/j2k/image/input/ImgReaderPGM.cs +++ b/CSJ2K/j2k/image/input/ImgReaderPGM.cs @@ -39,6 +39,7 @@ * Copyright (c) 1999/2000 JJ2000 Partners. * */ using System; +using CSJ2K.Util; using CSJ2K.j2k.image; using CSJ2K.j2k; namespace CSJ2K.j2k.image.input @@ -66,7 +67,7 @@ public class ImgReaderPGM:ImgReader /// Where to read the data from //UPGRADE_TODO: Class 'java.io.RandomAccessFile' was converted to 'System.IO.FileStream' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javaioRandomAccessFile'" - private System.IO.FileStream in_Renamed; + private System.IO.Stream in_Renamed; /// The offset of the raw pixel data in the PGM file private int offset; @@ -83,7 +84,7 @@ public class ImgReaderPGM:ImgReader /// filters). This avoid allocating new DataBlk at each time ///
private DataBlkInt intBlk; - + /// Creates a new PGM file reader from the specified file. /// /// @@ -93,9 +94,10 @@ public class ImgReaderPGM:ImgReader /// If an error occurs while opening the file. /// /// - public ImgReaderPGM(System.IO.FileInfo file):this(SupportClass.RandomAccessFileSupport.CreateRandomAccessFile(file, "r")) + public ImgReaderPGM(IFileInfo file) + : this(SupportClass.RandomAccessFileSupport.CreateRandomAccessFile(file, "r")) { - } + } /// Creates a new PGM file reader from the specified file name. /// @@ -123,7 +125,7 @@ public ImgReaderPGM(System.String fname):this(SupportClass.RandomAccessFileSuppo /// /// //UPGRADE_TODO: Class 'java.io.RandomAccessFile' was converted to 'System.IO.FileStream' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javaioRandomAccessFile'" - public ImgReaderPGM(System.IO.FileStream in_Renamed) + public ImgReaderPGM(System.IO.Stream in_Renamed) { this.in_Renamed = in_Renamed; @@ -149,7 +151,7 @@ public ImgReaderPGM(System.IO.FileStream in_Renamed) /// public override void close() { - in_Renamed.Close(); + in_Renamed.Dispose(); in_Renamed = null; } diff --git a/CSJ2K/j2k/image/input/ImgReaderPGX.cs b/CSJ2K/j2k/image/input/ImgReaderPGX.cs index 0ccfee87..496a72cd 100644 --- a/CSJ2K/j2k/image/input/ImgReaderPGX.cs +++ b/CSJ2K/j2k/image/input/ImgReaderPGX.cs @@ -42,6 +42,7 @@ * Copyright (c) 1999/2000 JJ2000 Partners. * */ using System; +using CSJ2K.Util; using CSJ2K.j2k.image; using CSJ2K.j2k.io; using CSJ2K.j2k; @@ -109,7 +110,7 @@ public class ImgReaderPGX:ImgReader, EndianType /// The RandomAccessIO where to get datas from //UPGRADE_TODO: Class 'java.io.RandomAccessFile' was converted to 'System.IO.FileStream' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javaioRandomAccessFile'" - private System.IO.FileStream in_Renamed; + private System.IO.Stream in_Renamed; /// The bit-depth of the input file (must be between 1 and 31) private int bitDepth; @@ -145,36 +146,25 @@ public class ImgReaderPGX:ImgReader, EndianType /// If an I/O error occurs. /// /// - public ImgReaderPGX(System.IO.FileInfo in_Renamed) + public ImgReaderPGX(System.IO.Stream in_Renamed) { System.String header; - // Check if specified file exists - bool tmpBool; - if (System.IO.File.Exists(in_Renamed.FullName)) - tmpBool = true; - else - tmpBool = System.IO.Directory.Exists(in_Renamed.FullName); - if (!tmpBool) - { - throw new System.ArgumentException("PGX file " + in_Renamed.Name + " does not exist"); - } - //Opens the given file - this.in_Renamed = SupportClass.RandomAccessFileSupport.CreateRandomAccessFile(in_Renamed, "r"); + this.in_Renamed = in_Renamed; try { System.IO.StreamReader in_reader = new System.IO.StreamReader(this.in_Renamed); //UPGRADE_ISSUE: Method 'java.io.RandomAccessFile.readLine' was not converted. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1000_javaioRandomAccessFilereadLine'" header = in_reader.ReadLine(); } - catch (System.IO.IOException) + catch (System.IO.IOException e) { - throw new System.IO.IOException(in_Renamed.Name + " is not a PGX file"); + throw new System.IO.IOException("Not a PGX file"); } if (header == null) { - throw new System.IO.IOException(in_Renamed.Name + " is an empty file"); + throw new System.IO.IOException("Empty file"); } offset = (header.Length + 1); @@ -186,7 +176,7 @@ public ImgReaderPGX(System.IO.FileInfo in_Renamed) // Magic Number if (!(st.NextToken()).Equals("PG")) - throw new System.IO.IOException(in_Renamed.Name + " is not a PGX file"); + throw new System.IO.IOException("Not a PGX file"); // Endianess System.String tmp = st.NextToken(); @@ -195,7 +185,7 @@ public ImgReaderPGX(System.IO.FileInfo in_Renamed) else if (tmp.Equals("ML")) byteOrder = CSJ2K.j2k.io.EndianType_Fields.BIG_ENDIAN; else - throw new System.IO.IOException(in_Renamed.Name + " is not a PGX file"); + throw new System.IO.IOException("Not a PGX file"); // Unsigned/signed if present in the header if (nTokens == 6) @@ -206,7 +196,7 @@ public ImgReaderPGX(System.IO.FileInfo in_Renamed) else if (tmp.Equals("-")) isSigned = true; else - throw new System.IO.IOException(in_Renamed.Name + " is not a PGX file"); + throw new System.IO.IOException("Not a PGX file"); } // bit-depth, width, height @@ -215,19 +205,19 @@ public ImgReaderPGX(System.IO.FileInfo in_Renamed) bitDepth = (System.Int32.Parse(st.NextToken())); // bitDepth must be between 1 and 31 if ((bitDepth <= 0) || (bitDepth > 31)) - throw new System.IO.IOException(in_Renamed.Name + " is not a valid PGX file"); + throw new System.IO.IOException("Not a PGX file"); w = (System.Int32.Parse(st.NextToken())); h = (System.Int32.Parse(st.NextToken())); } - catch (System.FormatException) + catch (System.FormatException e) { - throw new System.IO.IOException(in_Renamed.Name + " is not a PGX file"); + throw new System.IO.IOException("Not a PGX file"); } } - catch (System.ArgumentOutOfRangeException) + catch (System.ArgumentOutOfRangeException e) { - throw new System.IO.IOException(in_Renamed.Name + " is not a PGX file"); + throw new System.IO.IOException("Not a PGX file"); } // Number of component @@ -242,14 +232,27 @@ public ImgReaderPGX(System.IO.FileInfo in_Renamed) else packBytes = 4; } - + + /// Creates a new PGX file reader from the specified File object. + /// + /// + /// The input file as File object. + /// + /// + /// If an I/O error occurs. + /// + /// + public ImgReaderPGX(IFileInfo in_Renamed) : this(SupportClass.RandomAccessFileSupport.CreateRandomAccessFile(in_Renamed, "r")) + { + } + /// Creates a new PGX file reader from the specified file name. /// /// /// The input file name. /// /// - public ImgReaderPGX(System.String inName):this(new System.IO.FileInfo(inName)) + public ImgReaderPGX(System.String inName):this(FileInfoFactory.New(inName)) { } @@ -262,7 +265,7 @@ public ImgReaderPGX(System.String inName):this(new System.IO.FileInfo(inName)) /// public override void close() { - in_Renamed.Close(); + in_Renamed.Dispose(); in_Renamed = null; buf = null; } @@ -459,7 +462,7 @@ public override DataBlk getInternCompData(DataBlk blk, int c) break; default: - throw new System.ApplicationException("Internal JJ2000 bug"); + throw new System.InvalidOperationException("Internal JJ2000 bug"); } } @@ -490,7 +493,7 @@ public override DataBlk getInternCompData(DataBlk blk, int c) break; default: - throw new System.ApplicationException("Internal JJ2000 bug"); + throw new System.InvalidOperationException("Internal JJ2000 bug"); } } @@ -526,7 +529,7 @@ public override DataBlk getInternCompData(DataBlk blk, int c) break; default: - throw new System.ApplicationException("Internal JJ2000 bug"); + throw new System.InvalidOperationException("Internal JJ2000 bug"); } } @@ -556,7 +559,7 @@ public override DataBlk getInternCompData(DataBlk blk, int c) break; default: - throw new System.ApplicationException("Internal JJ2000 bug"); + throw new System.InvalidOperationException("Internal JJ2000 bug"); } } diff --git a/CSJ2K/j2k/image/input/ImgReaderPPM.cs b/CSJ2K/j2k/image/input/ImgReaderPPM.cs index 97fdf37c..24986d19 100644 --- a/CSJ2K/j2k/image/input/ImgReaderPPM.cs +++ b/CSJ2K/j2k/image/input/ImgReaderPPM.cs @@ -39,6 +39,7 @@ * Copyright (c) 1999/2000 JJ2000 Partners. * */ using System; +using CSJ2K.Util; using CSJ2K.j2k.image; using CSJ2K.j2k.io; using CSJ2K.j2k; @@ -71,7 +72,7 @@ public class ImgReaderPPM:ImgReader /// Where to read the data from //UPGRADE_TODO: Class 'java.io.RandomAccessFile' was converted to 'System.IO.FileStream' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javaioRandomAccessFile'" - private System.IO.FileStream in_Renamed; + private System.IO.Stream in_Renamed; /// The offset of the raw pixel data in the PPM file private int offset; @@ -94,7 +95,7 @@ public class ImgReaderPPM:ImgReader /// filters). This avoid allocating new DataBlk at each time /// private DataBlkInt intBlk; - + /// Creates a new PPM file reader from the specified file. /// /// @@ -104,9 +105,10 @@ public class ImgReaderPPM:ImgReader /// If an error occurs while opening the file. /// /// - public ImgReaderPPM(System.IO.FileInfo file):this(SupportClass.RandomAccessFileSupport.CreateRandomAccessFile(file, "r")) + public ImgReaderPPM(IFileInfo file) + : this(SupportClass.RandomAccessFileSupport.CreateRandomAccessFile(file, "r")) { - } + } /// Creates a new PPM file reader from the specified file name. /// @@ -134,7 +136,7 @@ public ImgReaderPPM(System.String fname):this(SupportClass.RandomAccessFileSuppo /// /// //UPGRADE_TODO: Class 'java.io.RandomAccessFile' was converted to 'System.IO.FileStream' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javaioRandomAccessFile'" - private ImgReaderPPM(System.IO.FileStream in_Renamed) + public ImgReaderPPM(System.IO.Stream in_Renamed) { this.in_Renamed = in_Renamed; @@ -159,7 +161,7 @@ private ImgReaderPPM(System.IO.FileStream in_Renamed) /// public override void close() { - in_Renamed.Close(); + in_Renamed.Dispose(); in_Renamed = null; // Free memory barr[0] = null; diff --git a/CSJ2K/j2k/image/invcomptransf/InvCompTransf.cs b/CSJ2K/j2k/image/invcomptransf/InvCompTransf.cs index dd88510a..4402a7ad 100644 --- a/CSJ2K/j2k/image/invcomptransf/InvCompTransf.cs +++ b/CSJ2K/j2k/image/invcomptransf/InvCompTransf.cs @@ -46,766 +46,805 @@ using CSJ2K.j2k.image; using CSJ2K.j2k.util; using CSJ2K.j2k; + namespace CSJ2K.j2k.image.invcomptransf { - - /// This class apply inverse component transformations to the tiles depending - /// on specification read from the codestream header. These transformations can - /// be used to improve compression efficiency but are not related to colour - /// transforms used to map colour values for display purposes. JPEG 2000 part I - /// defines 2 component transformations: RCT (Reversible Component - /// Transformation) and ICT (Irreversible Component Transformation). - /// - /// - /// - /// - /// - public class InvCompTransf:ImgDataAdapter, BlkImgDataSrc - { - /// Returns the parameters that are used in this class and implementing - /// classes. It returns a 2D String array. Each of the 1D arrays is for a - /// different option, and they have 4 elements. The first element is the - /// option name, the second one is the synopsis, the third one is a long - /// description of what the parameter is and the fourth is its default - /// value. The synopsis or description may be 'null', in which case it is - /// assumed that there is no synopsis or description of the option, - /// respectively. Null may be returned if no options are supported. - /// - /// - /// the options name, their synopsis and their explanation, - /// or null if no options are supported. - /// - /// - public static System.String[][] ParameterInfo - { - get - { - return pinfo; - } - - } - /// Returns true if this transform is reversible in current - /// tile. Reversible component transformations are those which operation - /// can be completely reversed without any loss of information (not even - /// due to rounding). - /// - /// - /// Reversibility of component transformation in current - /// tile - /// - /// - virtual public bool Reversible - { - get - { - switch (transfType) - { - - case NONE: - case INV_RCT: - return true; - - case INV_ICT: - return false; - - default: - throw new System.ArgumentException("Non JPEG 2000 part I" + " component transformation"); - - } - } - - } - - /// Identifier for no component transformation. Value is 0. - public const int NONE = 0; - - /// The prefix for inverse component transformation options: 'M' - public const char OPT_PREFIX = 'M'; - - /// The list of parameters that is accepted by the inverse - /// component transformation module. They start with 'M'. - /// - //UPGRADE_NOTE: Final was removed from the declaration of 'pinfo'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" - private static readonly System.String[][] pinfo = null; - - /// Identifier for the Inverse Reversible Component Transformation - /// (INV_RCT). Value is 1. - /// - public const int INV_RCT = 1; - - /// Identifier for the Inverse Irreversible Component - /// Transformation (INV_ICT). Value is 2 - /// - public const int INV_ICT = 2; - - /// The source of image data - private BlkImgDataSrc src; - - /// The component transformations specifications - private CompTransfSpec cts; - - /// The wavelet filter specifications - private SynWTFilterSpec wfs; - - /// The type of the current component transformation JPEG 2000 - /// part I only support NONE, FORW_RCT and FORW_ICT types - /// - private int transfType = NONE; - - /// Buffer for each component of output data - private int[][] outdata = new int[3][]; - - /// Block used to request component 0 - private DataBlk block0; - - /// Block used to request component 1 - private DataBlk block1; - - /// Block used to request component 2 - private DataBlk block2; - - /// Data block used only to store coordinates and progressiveness - /// of the buffered blocks - /// - private DataBlkInt dbi = new DataBlkInt(); - - /// The bit-depths of un-transformed components - private int[] utdepth; - - /// Flag indicating whether the decoder should skip the component - /// transform - /// - private bool noCompTransf = false; - - /// Constructs a new ForwCompTransf object that operates on the - /// specified source of image data. - /// - /// - /// The source from where to get the data to be - /// transformed - /// - /// - /// The decoder specifications - /// - /// - /// The bit depth of the un-transformed components - /// - /// - /// The command line optinons of the decoder - /// - /// - /// - /// - /// - public InvCompTransf(BlkImgDataSrc imgSrc, DecoderSpecs decSpec, int[] utdepth, ParameterList pl):base(imgSrc) - { - this.cts = decSpec.cts; - this.wfs = decSpec.wfs; - src = imgSrc; - this.utdepth = utdepth; - noCompTransf = !(pl.getBooleanParameter("comp_transf")); - } - - /// Returns a string with a descriptive text of which inverse component - /// transformation is used. This can be either "Inverse RCT" or "Inverse - /// ICT" or "No component transformation" depending on the current tile. - /// - /// - /// A descriptive string - /// - /// - public override System.String ToString() - { - switch (transfType) - { - - case INV_RCT: - return "Inverse RCT"; - - case INV_ICT: - return "Inverse ICT"; - - case NONE: - return "No component transformation"; - - default: - throw new System.ArgumentException("Non JPEG 2000 part I" + " component transformation"); - - } - } - - /// Returns the position of the fixed point in the specified - /// component. This is the position of the least significant integral - /// (i.e. non-fractional) bit, which is equivalent to the number of - /// fractional bits. For instance, for fixed-point values with 2 fractional - /// bits, 2 is returned. For floating-point data this value does not apply - /// and 0 should be returned. Position 0 is the position of the least - /// significant bit in the data. - /// - ///

This default implementation assumes that the number of fractional - /// bits is not modified by the component mixer. - /// - ///

- /// The index of the component. - /// - /// - /// The value of the fixed point position of the source since the - /// color transform does not affect it. - /// - /// - public virtual int getFixedPoint(int c) - { - return src.getFixedPoint(c); - } - - /// Calculates the bitdepths of the transformed components, given the - /// bitdepth of the un-transformed components and the component - /// tranformation type. - /// - /// - /// The bitdepth of each un-transformed component - /// - /// - /// The type ID of the inverse component tranformation - /// - /// - /// If not null the results are stored in this - /// array, otherwise a new array is allocated and returned. - /// - /// - /// The bitdepth of each transformed component. - /// - /// - public static int[] calcMixedBitDepths(int[] utdepth, int ttype, int[] tdepth) - { - - if (utdepth.Length < 3 && ttype != NONE) - { - throw new System.ArgumentException(); - } - - if (tdepth == null) - { - tdepth = new int[utdepth.Length]; - } - - switch (ttype) - { - - case NONE: - Array.Copy(utdepth, 0, tdepth, 0, utdepth.Length); - break; - - case INV_RCT: - if (utdepth.Length > 3) - { - Array.Copy(utdepth, 3, tdepth, 3, utdepth.Length - 3); - } - // The formulas are: - // tdepth[0] = ceil(log2(2^(utdepth[0])+2^utdepth[1]+ - // 2^(utdepth[2])))-2+1 - // tdepth[1] = ceil(log2(2^(utdepth[0])+2^(utdepth[1])-1))+1 - // tdepth[2] = ceil(log2(2^(utdepth[1])+2^(utdepth[2])-1))+1 - // The MathUtil.log2(x) function calculates floor(log2(x)), so we - // use 'MathUtil.log2(2*x-1)+1', which calculates ceil(log2(x)) - // for any x>=1, x integer. - tdepth[0] = MathUtil.log2((1 << utdepth[0]) + (2 << utdepth[1]) + (1 << utdepth[2]) - 1) - 2 + 1; - tdepth[1] = MathUtil.log2((1 << utdepth[2]) + (1 << utdepth[1]) - 1) + 1; - tdepth[2] = MathUtil.log2((1 << utdepth[0]) + (1 << utdepth[1]) - 1) + 1; - break; - - case INV_ICT: - if (utdepth.Length > 3) - { - Array.Copy(utdepth, 3, tdepth, 3, utdepth.Length - 3); - } - // The MathUtil.log2(x) function calculates floor(log2(x)), so we - // use 'MathUtil.log2(2*x-1)+1', which calculates ceil(log2(x)) - // for any x>=1, x integer. - //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'" - tdepth[0] = MathUtil.log2((int) System.Math.Floor((1 << utdepth[0]) * 0.299072 + (1 << utdepth[1]) * 0.586914 + (1 << utdepth[2]) * 0.114014) - 1) + 1; - //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'" - tdepth[1] = MathUtil.log2((int) System.Math.Floor((1 << utdepth[0]) * 0.168701 + (1 << utdepth[1]) * 0.331299 + (1 << utdepth[2]) * 0.5) - 1) + 1; - //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'" - tdepth[2] = MathUtil.log2((int) System.Math.Floor((1 << utdepth[0]) * 0.5 + (1 << utdepth[1]) * 0.418701 + (1 << utdepth[2]) * 0.081299) - 1) + 1; - break; - } - - return tdepth; - } - - /// Returns the number of bits, referred to as the "range bits", - /// corresponding to the nominal range of the data in the specified - /// component. If this number is b then for unsigned data the - /// nominal range is between 0 and 2^b-1, and for signed data it is between - /// -2^(b-1) and 2^(b-1)-1. - /// - /// - /// The index of the component. - /// - /// - /// The bitdepth of un-transformed component 'c'. - /// - /// - public override int getNomRangeBits(int c) - { - return utdepth[c]; - } - - /// Apply inverse component transformation associated with the current - /// tile. If no component transformation has been requested by the user, - /// data are not modified. - /// - ///

This method calls the getInternCompData() method, but respects the - /// definitions of the getCompData() method defined in the BlkImgDataSrc - /// interface. - /// - ///

- /// Determines the rectangular area to return, and the - /// data is returned in this object. - /// - /// - /// Index of the output component. - /// - /// - /// The requested DataBlk - /// - /// - /// - /// - /// - public virtual DataBlk getCompData(DataBlk blk, int c) - { - // If requesting a component whose index is greater than 3 or there is - // no transform return a copy of data (getInternCompData returns the - // actual data in those cases) - if (c >= 3 || transfType == NONE || noCompTransf) - { - return src.getCompData(blk, c); - } - else - { - // We can use getInternCompData (since data is a copy anyways) - return getInternCompData(blk, c); - } - } - - /// Apply the inverse component transformation associated with the current - /// tile. If no component transformation has been requested by the user, - /// data are not modified. Else, appropriate method is called (invRCT or - /// invICT). - /// - /// - /// - /// - /// - /// - /// - /// - /// Determines the rectangular area to return. - /// - /// - /// Index of the output component. - /// - /// - /// The requested DataBlk - /// - /// - public virtual DataBlk getInternCompData(DataBlk blk, int c) - { - // if specified in the command line that no component transform should - // be made, return original data - if (noCompTransf) - return src.getInternCompData(blk, c); - - switch (transfType) - { - - case NONE: - return src.getInternCompData(blk, c); - - - case INV_RCT: - return invRCT(blk, c); - - case INV_ICT: - return invICT(blk, c); - - default: - throw new System.ArgumentException("Non JPEG 2000 part I" + " component transformation"); - - } - } - - /// Apply inverse component transformation to obtain requested component - /// from specified block of data. Whatever the type of requested DataBlk, - /// it always returns a DataBlkInt. - /// - /// - /// Determine the rectangular area to return - /// - /// - /// The index of the requested component - /// - /// - /// Data of requested component - /// - /// - private DataBlk invRCT(DataBlk blk, int c) - { - // If the component number is three or greater, return original data - if (c >= 3 && c < NumComps) - { - // Requesting a component whose index is greater than 3 - return src.getInternCompData(blk, c); - } - // If asking a component for the first time for this block, - // do transform for the 3 components - else if ((outdata[c] == null) || (dbi.ulx > blk.ulx) || (dbi.uly > blk.uly) || (dbi.ulx + dbi.w < blk.ulx + blk.w) || (dbi.uly + dbi.h < blk.uly + blk.h)) - { - int k, k0, k1, k2, mink, i; - int w = blk.w; //width of output block - int h = blk.h; //height of ouput block - - //Reference to output block data array - outdata[c] = (int[]) blk.Data; - - //Create data array of blk if necessary - if (outdata[c] == null || outdata[c].Length != h * w) - { - outdata[c] = new int[h * w]; - blk.Data = outdata[c]; - } - - outdata[(c + 1) % 3] = new int[outdata[c].Length]; - outdata[(c + 2) % 3] = new int[outdata[c].Length]; - - if (block0 == null || block0.DataType != DataBlk.TYPE_INT) - block0 = new DataBlkInt(); - if (block1 == null || block1.DataType != DataBlk.TYPE_INT) - block1 = new DataBlkInt(); - if (block2 == null || block2.DataType != DataBlk.TYPE_INT) - block2 = new DataBlkInt(); - block0.w = block1.w = block2.w = blk.w; - block0.h = block1.h = block2.h = blk.h; - block0.ulx = block1.ulx = block2.ulx = blk.ulx; - block0.uly = block1.uly = block2.uly = blk.uly; - - int[] data0, data1, data2; // input data arrays - - // Fill in buffer blocks (to be read only) - // Returned blocks may have different size and position - block0 = (DataBlkInt) src.getInternCompData(block0, 0); - data0 = (int[]) block0.Data; - block1 = (DataBlkInt) src.getInternCompData(block1, 1); - data1 = (int[]) block1.Data; - block2 = (DataBlkInt) src.getInternCompData(block2, 2); - data2 = (int[]) block2.Data; - - // Set the progressiveness of the output data - blk.progressive = block0.progressive || block1.progressive || block2.progressive; - blk.offset = 0; - blk.scanw = w; - - // set attributes of the DataBlk used for buffering - dbi.progressive = blk.progressive; - dbi.ulx = blk.ulx; - dbi.uly = blk.uly; - dbi.w = blk.w; - dbi.h = blk.h; - - // Perform conversion - - // Initialize general indexes - k = w * h - 1; - k0 = block0.offset + (h - 1) * block0.scanw + w - 1; - k1 = block1.offset + (h - 1) * block1.scanw + w - 1; - k2 = block2.offset + (h - 1) * block2.scanw + w - 1; - - for (i = h - 1; i >= 0; i--) - { - for (mink = k - w; k > mink; k--, k0--, k1--, k2--) - { - outdata[1][k] = (data0[k0] - ((data1[k1] + data2[k2]) >> 2)); - outdata[0][k] = data2[k2] + outdata[1][k]; - outdata[2][k] = data1[k1] + outdata[1][k]; - } - // Jump to beggining of previous line in input - k0 -= (block0.scanw - w); - k1 -= (block1.scanw - w); - k2 -= (block2.scanw - w); - } - outdata[c] = null; - } - else if ((c >= 0) && (c < 3)) - { - //Asking for the 2nd or 3rd block component - blk.Data = outdata[c]; - blk.progressive = dbi.progressive; - blk.offset = (blk.uly - dbi.uly) * dbi.w + blk.ulx - dbi.ulx; - blk.scanw = dbi.w; - outdata[c] = null; - } - else - { - // Requesting a non valid component index - throw new System.ArgumentException(); - } - return blk; - } - - /// Apply inverse irreversible component transformation to obtain requested - /// component from specified block of data. Whatever the type of requested - /// DataBlk, it always returns a DataBlkFloat. - /// - /// - /// Determine the rectangular area to return - /// - /// - /// The index of the requested component - /// - /// - /// Data of requested component - /// - /// - private DataBlk invICT(DataBlk blk, int c) - { - if (c >= 3 && c < NumComps) - { - // Requesting a component whose index is greater than 3 + + /// This class apply inverse component transformations to the tiles depending + /// on specification read from the codestream header. These transformations can + /// be used to improve compression efficiency but are not related to colour + /// transforms used to map colour values for display purposes. JPEG 2000 part I + /// defines 2 component transformations: RCT (Reversible Component + /// Transformation) and ICT (Irreversible Component Transformation). + /// + /// + /// + /// + /// + public class InvCompTransf : ImgDataAdapter, BlkImgDataSrc + { + /// Returns the parameters that are used in this class and implementing + /// classes. It returns a 2D String array. Each of the 1D arrays is for a + /// different option, and they have 4 elements. The first element is the + /// option name, the second one is the synopsis, the third one is a long + /// description of what the parameter is and the fourth is its default + /// value. The synopsis or description may be 'null', in which case it is + /// assumed that there is no synopsis or description of the option, + /// respectively. Null may be returned if no options are supported. + /// + /// + /// the options name, their synopsis and their explanation, + /// or null if no options are supported. + /// + /// + public static System.String[][] ParameterInfo + { + get + { + return pinfo; + } + + } + + /// Returns true if this transform is reversible in current + /// tile. Reversible component transformations are those which operation + /// can be completely reversed without any loss of information (not even + /// due to rounding). + /// + /// + /// Reversibility of component transformation in current + /// tile + /// + /// + public virtual bool Reversible + { + get + { + switch (transfType) + { + + case NONE: + case INV_RCT: + return true; + + case INV_ICT: + return false; + + default: + throw new System.ArgumentException("Non JPEG 2000 part I" + " component transformation"); + + } + } + + } + + /// Identifier for no component transformation. Value is 0. + public const int NONE = 0; + + /// The prefix for inverse component transformation options: 'M' + public const char OPT_PREFIX = 'M'; + + /// The list of parameters that is accepted by the inverse + /// component transformation module. They start with 'M'. + /// + //UPGRADE_NOTE: Final was removed from the declaration of 'pinfo'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" + private static readonly System.String[][] pinfo = null; + + /// Identifier for the Inverse Reversible Component Transformation + /// (INV_RCT). Value is 1. + /// + public const int INV_RCT = 1; + + /// Identifier for the Inverse Irreversible Component + /// Transformation (INV_ICT). Value is 2 + /// + public const int INV_ICT = 2; + + /// The source of image data + private BlkImgDataSrc src; + + /// The component transformations specifications + private CompTransfSpec cts; + + /// The wavelet filter specifications + private SynWTFilterSpec wfs; + + /// The type of the current component transformation JPEG 2000 + /// part I only support NONE, FORW_RCT and FORW_ICT types + /// + private int transfType = NONE; + + /// Buffer for each component of output data + private int[][] outdata = new int[3][]; + + /// Block used to request component 0 + private DataBlk block0; + + /// Block used to request component 1 + private DataBlk block1; + + /// Block used to request component 2 + private DataBlk block2; + + /// Data block used only to store coordinates and progressiveness + /// of the buffered blocks + /// + private DataBlkInt dbi = new DataBlkInt(); + + /// The bit-depths of un-transformed components + private int[] utdepth; + + /// Flag indicating whether the decoder should skip the component + /// transform + /// + private bool noCompTransf = false; + + /// Constructs a new ForwCompTransf object that operates on the + /// specified source of image data. + /// + /// + /// The source from where to get the data to be + /// transformed + /// + /// + /// The decoder specifications + /// + /// + /// The bit depth of the un-transformed components + /// + /// + /// The command line optinons of the decoder + /// + /// + /// + /// + /// + public InvCompTransf(BlkImgDataSrc imgSrc, DecoderSpecs decSpec, int[] utdepth, ParameterList pl) + : base(imgSrc) + { + this.cts = decSpec.cts; + this.wfs = decSpec.wfs; + src = imgSrc; + this.utdepth = utdepth; + noCompTransf = !(pl.getBooleanParameter("comp_transf")); + } + + /// Returns a string with a descriptive text of which inverse component + /// transformation is used. This can be either "Inverse RCT" or "Inverse + /// ICT" or "No component transformation" depending on the current tile. + /// + /// + /// A descriptive string + /// + /// + public override System.String ToString() + { + switch (transfType) + { + + case INV_RCT: + return "Inverse RCT"; + + case INV_ICT: + return "Inverse ICT"; + + case NONE: + return "No component transformation"; + + default: + throw new System.ArgumentException("Non JPEG 2000 part I" + " component transformation"); + + } + } + + /// Returns the position of the fixed point in the specified + /// component. This is the position of the least significant integral + /// (i.e. non-fractional) bit, which is equivalent to the number of + /// fractional bits. For instance, for fixed-point values with 2 fractional + /// bits, 2 is returned. For floating-point data this value does not apply + /// and 0 should be returned. Position 0 is the position of the least + /// significant bit in the data. + /// + ///

This default implementation assumes that the number of fractional + /// bits is not modified by the component mixer. + /// + ///

+ /// The index of the component. + /// + /// + /// The value of the fixed point position of the source since the + /// color transform does not affect it. + /// + /// + public virtual int getFixedPoint(int c) + { + return src.getFixedPoint(c); + } + + /// Calculates the bitdepths of the transformed components, given the + /// bitdepth of the un-transformed components and the component + /// tranformation type. + /// + /// + /// The bitdepth of each un-transformed component + /// + /// + /// The type ID of the inverse component tranformation + /// + /// + /// If not null the results are stored in this + /// array, otherwise a new array is allocated and returned. + /// + /// + /// The bitdepth of each transformed component. + /// + /// + public static int[] calcMixedBitDepths(int[] utdepth, int ttype, int[] tdepth) + { + + if (utdepth.Length < 3 && ttype != NONE) + { + throw new System.ArgumentException(); + } + + if (tdepth == null) + { + tdepth = new int[utdepth.Length]; + } + + switch (ttype) + { + + case NONE: + Array.Copy(utdepth, 0, tdepth, 0, utdepth.Length); + break; + + case INV_RCT: + if (utdepth.Length > 3) + { + Array.Copy(utdepth, 3, tdepth, 3, utdepth.Length - 3); + } + // The formulas are: + // tdepth[0] = ceil(log2(2^(utdepth[0])+2^utdepth[1]+ + // 2^(utdepth[2])))-2+1 + // tdepth[1] = ceil(log2(2^(utdepth[0])+2^(utdepth[1])-1))+1 + // tdepth[2] = ceil(log2(2^(utdepth[1])+2^(utdepth[2])-1))+1 + // The MathUtil.log2(x) function calculates floor(log2(x)), so we + // use 'MathUtil.log2(2*x-1)+1', which calculates ceil(log2(x)) + // for any x>=1, x integer. + tdepth[0] = MathUtil.log2((1 << utdepth[0]) + (2 << utdepth[1]) + (1 << utdepth[2]) - 1) - 2 + 1; + tdepth[1] = MathUtil.log2((1 << utdepth[2]) + (1 << utdepth[1]) - 1) + 1; + tdepth[2] = MathUtil.log2((1 << utdepth[0]) + (1 << utdepth[1]) - 1) + 1; + break; + + case INV_ICT: + if (utdepth.Length > 3) + { + Array.Copy(utdepth, 3, tdepth, 3, utdepth.Length - 3); + } + // The MathUtil.log2(x) function calculates floor(log2(x)), so we + // use 'MathUtil.log2(2*x-1)+1', which calculates ceil(log2(x)) + // for any x>=1, x integer. + //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'" + tdepth[0] = + MathUtil.log2( + (int) + System.Math.Floor( + (1 << utdepth[0]) * 0.299072 + (1 << utdepth[1]) * 0.586914 + + (1 << utdepth[2]) * 0.114014) - 1) + 1; + //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'" + tdepth[1] = + MathUtil.log2( + (int) + System.Math.Floor( + (1 << utdepth[0]) * 0.168701 + (1 << utdepth[1]) * 0.331299 + (1 << utdepth[2]) * 0.5) + - 1) + 1; + //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'" + tdepth[2] = + MathUtil.log2( + (int) + System.Math.Floor( + (1 << utdepth[0]) * 0.5 + (1 << utdepth[1]) * 0.418701 + (1 << utdepth[2]) * 0.081299) + - 1) + 1; + break; + } + + return tdepth; + } + + /// Returns the number of bits, referred to as the "range bits", + /// corresponding to the nominal range of the data in the specified + /// component. If this number is b then for unsigned data the + /// nominal range is between 0 and 2^b-1, and for signed data it is between + /// -2^(b-1) and 2^(b-1)-1. + /// + /// + /// The index of the component. + /// + /// + /// The bitdepth of un-transformed component 'c'. + /// + /// + public override int getNomRangeBits(int c) + { + return utdepth[c]; + } + + /// Apply inverse component transformation associated with the current + /// tile. If no component transformation has been requested by the user, + /// data are not modified. + /// + ///

This method calls the getInternCompData() method, but respects the + /// definitions of the getCompData() method defined in the BlkImgDataSrc + /// interface. + /// + ///

+ /// Determines the rectangular area to return, and the + /// data is returned in this object. + /// + /// + /// Index of the output component. + /// + /// + /// The requested DataBlk + /// + /// + /// + /// + /// + public virtual DataBlk getCompData(DataBlk blk, int c) + { + // If requesting a component whose index is greater than 3 or there is + // no transform return a copy of data (getInternCompData returns the + // actual data in those cases) + if (c >= 3 || transfType == NONE || noCompTransf) + { + return src.getCompData(blk, c); + } + else + { + // We can use getInternCompData (since data is a copy anyways) + return getInternCompData(blk, c); + } + } + + /// Closes the underlying file or network connection from where the + /// image data is being read. + /// + /// + /// If an I/O error occurs. + /// + public void close() + { + // Do nothing. + } + + /// Returns true if the data read was originally signed in the specified + /// component, false if not. + /// + /// + /// The index of the component, from 0 to C-1. + /// + /// + /// true if the data was originally signed, false if not. + /// + /// + public bool isOrigSigned(int c) + { + return false; + } + + /// Apply the inverse component transformation associated with the current + /// tile. If no component transformation has been requested by the user, + /// data are not modified. Else, appropriate method is called (invRCT or + /// invICT). + /// + /// + /// + /// + /// + /// + /// + /// + /// Determines the rectangular area to return. + /// + /// + /// Index of the output component. + /// + /// + /// The requested DataBlk + /// + /// + public virtual DataBlk getInternCompData(DataBlk blk, int c) + { + // if specified in the command line that no component transform should + // be made, return original data + if (noCompTransf) return src.getInternCompData(blk, c); + + switch (transfType) + { + + case NONE: + return src.getInternCompData(blk, c); + + + case INV_RCT: + return invRCT(blk, c); + + case INV_ICT: + return invICT(blk, c); + + default: + throw new System.ArgumentException("Non JPEG 2000 part I" + " component transformation"); + + } + } + + /// Apply inverse component transformation to obtain requested component + /// from specified block of data. Whatever the type of requested DataBlk, + /// it always returns a DataBlkInt. + /// + /// + /// Determine the rectangular area to return + /// + /// + /// The index of the requested component + /// + /// + /// Data of requested component + /// + /// + private DataBlk invRCT(DataBlk blk, int c) + { + // If the component number is three or greater, return original data + if (c >= 3 && c < NumComps) + { + // Requesting a component whose index is greater than 3 + return src.getInternCompData(blk, c); + } + // If asking a component for the first time for this block, + // do transform for the 3 components + else if ((outdata[c] == null) || (dbi.ulx > blk.ulx) || (dbi.uly > blk.uly) + || (dbi.ulx + dbi.w < blk.ulx + blk.w) || (dbi.uly + dbi.h < blk.uly + blk.h)) + { + int k, k0, k1, k2, mink, i; + int w = blk.w; //width of output block + int h = blk.h; //height of ouput block + + //Reference to output block data array + outdata[c] = (int[])blk.Data; + + //Create data array of blk if necessary + if (outdata[c] == null || outdata[c].Length != h * w) + { + outdata[c] = new int[h * w]; + blk.Data = outdata[c]; + } + + outdata[(c + 1) % 3] = new int[outdata[c].Length]; + outdata[(c + 2) % 3] = new int[outdata[c].Length]; + + if (block0 == null || block0.DataType != DataBlk.TYPE_INT) block0 = new DataBlkInt(); + if (block1 == null || block1.DataType != DataBlk.TYPE_INT) block1 = new DataBlkInt(); + if (block2 == null || block2.DataType != DataBlk.TYPE_INT) block2 = new DataBlkInt(); + block0.w = block1.w = block2.w = blk.w; + block0.h = block1.h = block2.h = blk.h; + block0.ulx = block1.ulx = block2.ulx = blk.ulx; + block0.uly = block1.uly = block2.uly = blk.uly; + + int[] data0, data1, data2; // input data arrays + + // Fill in buffer blocks (to be read only) + // Returned blocks may have different size and position + block0 = (DataBlkInt)src.getInternCompData(block0, 0); + data0 = (int[])block0.Data; + block1 = (DataBlkInt)src.getInternCompData(block1, 1); + data1 = (int[])block1.Data; + block2 = (DataBlkInt)src.getInternCompData(block2, 2); + data2 = (int[])block2.Data; + + // Set the progressiveness of the output data + blk.progressive = block0.progressive || block1.progressive || block2.progressive; + blk.offset = 0; + blk.scanw = w; + + // set attributes of the DataBlk used for buffering + dbi.progressive = blk.progressive; + dbi.ulx = blk.ulx; + dbi.uly = blk.uly; + dbi.w = blk.w; + dbi.h = blk.h; + + // Perform conversion + + // Initialize general indexes + k = w * h - 1; + k0 = block0.offset + (h - 1) * block0.scanw + w - 1; + k1 = block1.offset + (h - 1) * block1.scanw + w - 1; + k2 = block2.offset + (h - 1) * block2.scanw + w - 1; + + for (i = h - 1; i >= 0; i--) + { + for (mink = k - w; k > mink; k--, k0--, k1--, k2--) + { + outdata[1][k] = (data0[k0] - ((data1[k1] + data2[k2]) >> 2)); + outdata[0][k] = data2[k2] + outdata[1][k]; + outdata[2][k] = data1[k1] + outdata[1][k]; + } + // Jump to beggining of previous line in input + k0 -= (block0.scanw - w); + k1 -= (block1.scanw - w); + k2 -= (block2.scanw - w); + } + outdata[c] = null; + } + else if ((c >= 0) && (c < 3)) + { + //Asking for the 2nd or 3rd block component + blk.Data = outdata[c]; + blk.progressive = dbi.progressive; + blk.offset = (blk.uly - dbi.uly) * dbi.w + blk.ulx - dbi.ulx; + blk.scanw = dbi.w; + outdata[c] = null; + } + else + { + // Requesting a non valid component index + throw new System.ArgumentException(); + } + return blk; + } + + /// Apply inverse irreversible component transformation to obtain requested + /// component from specified block of data. Whatever the type of requested + /// DataBlk, it always returns a DataBlkFloat. + /// + /// + /// Determine the rectangular area to return + /// + /// + /// The index of the requested component + /// + /// + /// Data of requested component + /// + /// + private DataBlk invICT(DataBlk blk, int c) + { + if (c >= 3 && c < NumComps) + { + // Requesting a component whose index is greater than 3 int k, k0, mink, i; // k1, k2 removed - int w = blk.w; //width of output block - int h = blk.h; //height of ouput block - - int[] out_data; // array of output data - - //Reference to output block data array - out_data = (int[]) blk.Data; - - //Create data array of blk if necessary - if (out_data == null) - { - out_data = new int[h * w]; - blk.Data = out_data; - } - - // Variables - DataBlkFloat indb = new DataBlkFloat(blk.ulx, blk.uly, w, h); - float[] indata; // input data array - - // Get the input data - // (returned block may be larger than requested one) - src.getInternCompData(indb, c); - indata = (float[]) indb.Data; - - // Copy the data converting from int to int - k = w * h - 1; - k0 = indb.offset + (h - 1) * indb.scanw + w - 1; - for (i = h - 1; i >= 0; i--) - { - for (mink = k - w; k > mink; k--, k0--) - { - //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'" - out_data[k] = (int) (indata[k0]); - } - // Jump to beggining of previous line in input - k0 -= (indb.scanw - w); - } - - // Set the progressivity and offset - blk.progressive = indb.progressive; - blk.offset = 0; - blk.scanw = w; - } - // If asking a component for the first time for this block, - // do transform for the 3 components - else if ((outdata[c] == null) || (dbi.ulx > blk.ulx) || (dbi.uly > blk.uly) || (dbi.ulx + dbi.w < blk.ulx + blk.w) || (dbi.uly + dbi.h < blk.uly + blk.h)) - { - int k, k0, k1, k2, mink, i; - int w = blk.w; //width of output block - int h = blk.h; //height of ouput block - - //Reference to output block data array - outdata[c] = (int[]) blk.Data; - - //Create data array of blk if necessary - if (outdata[c] == null || outdata[c].Length != w * h) - { - outdata[c] = new int[h * w]; - blk.Data = outdata[c]; - } - - outdata[(c + 1) % 3] = new int[outdata[c].Length]; - outdata[(c + 2) % 3] = new int[outdata[c].Length]; - - if (block0 == null || block0.DataType != DataBlk.TYPE_FLOAT) - block0 = new DataBlkFloat(); - if (block2 == null || block2.DataType != DataBlk.TYPE_FLOAT) - block2 = new DataBlkFloat(); - if (block1 == null || block1.DataType != DataBlk.TYPE_FLOAT) - block1 = new DataBlkFloat(); - block0.w = block2.w = block1.w = blk.w; - block0.h = block2.h = block1.h = blk.h; - block0.ulx = block2.ulx = block1.ulx = blk.ulx; - block0.uly = block2.uly = block1.uly = blk.uly; - - float[] data0, data1, data2; // input data arrays - - // Fill in buffer blocks (to be read only) - // Returned blocks may have different size and position - block0 = (DataBlkFloat) src.getInternCompData(block0, 0); - data0 = (float[]) block0.Data; - block2 = (DataBlkFloat) src.getInternCompData(block2, 1); - data2 = (float[]) block2.Data; - block1 = (DataBlkFloat) src.getInternCompData(block1, 2); - data1 = (float[]) block1.Data; - - // Set the progressiveness of the output data - blk.progressive = block0.progressive || block1.progressive || block2.progressive; - blk.offset = 0; - blk.scanw = w; - - // set attributes of the DataBlk used for buffering - dbi.progressive = blk.progressive; - dbi.ulx = blk.ulx; - dbi.uly = blk.uly; - dbi.w = blk.w; - dbi.h = blk.h; - - //Perform conversion - - // Initialize general indexes - k = w * h - 1; - k0 = block0.offset + (h - 1) * block0.scanw + w - 1; - k2 = block2.offset + (h - 1) * block2.scanw + w - 1; - k1 = block1.offset + (h - 1) * block1.scanw + w - 1; - - for (i = h - 1; i >= 0; i--) - { - for (mink = k - w; k > mink; k--, k0--, k2--, k1--) - { - //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'" - outdata[0][k] = (int) (data0[k0] + 1.402f * data1[k1] + 0.5f); - //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'" - outdata[1][k] = (int) (data0[k0] - 0.34413f * data2[k2] - 0.71414f * data1[k1] + 0.5f); - //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'" - outdata[2][k] = (int) (data0[k0] + 1.772f * data2[k2] + 0.5f); - } - // Jump to beggining of previous line in input - k0 -= (block0.scanw - w); - k2 -= (block2.scanw - w); - k1 -= (block1.scanw - w); - } - outdata[c] = null; - } - else if ((c >= 0) && (c <= 3)) - { - //Asking for the 2nd or 3rd block component - blk.Data = outdata[c]; - blk.progressive = dbi.progressive; - blk.offset = (blk.uly - dbi.uly) * dbi.w + blk.ulx - dbi.ulx; - blk.scanw = dbi.w; - outdata[c] = null; - } - else - { - // Requesting a non valid component index - throw new System.ArgumentException(); - } - return blk; - } - - /// Changes the current tile, given the new indexes. An - /// IllegalArgumentException is thrown if the indexes do not - /// correspond to a valid tile. - /// - ///

This default implementation changes the tile in the source - /// and re-initializes properly component transformation variables.. - /// - ///

- /// The horizontal index of the tile. - /// - /// - /// The vertical index of the new tile. - /// - /// - /// - public override void setTile(int x, int y) - { - src.setTile(x, y); - tIdx = TileIdx; // index of the current tile - - // initializations - if (((System.Int32) cts.getTileDef(tIdx)) == NONE) - transfType = NONE; - else - { - int nc = src.NumComps > 3?3:src.NumComps; - int rev = 0; - for (int c = 0; c < nc; c++) - { - rev += (wfs.isReversible(tIdx, c)?1:0); - } - if (rev == 3) - { - // All WT are reversible - transfType = INV_RCT; - } - else if (rev == 0) - { - // All WT irreversible - transfType = INV_ICT; - } - else - { - // Error - throw new System.ArgumentException("Wavelet transformation and " + "component transformation" + " not coherent in tile" + tIdx); - } - } - } - - /// Advances to the next tile, in standard scan-line order (by rows - /// then columns). An NoNextElementException is thrown if the - /// current tile is the last one (i.e. there is no next tile). - /// - ///

This default implementation just advances to the next tile - /// in the source and re-initializes properly component - /// transformation variables. - /// - /// - ///

- public override void nextTile() - { - src.nextTile(); - tIdx = TileIdx; // index of the current tile - - // initializations - if (((System.Int32) cts.getTileDef(tIdx)) == NONE) - transfType = NONE; - else - { - int nc = src.NumComps > 3?3:src.NumComps; - int rev = 0; - for (int c = 0; c < nc; c++) - { - rev += (wfs.isReversible(tIdx, c)?1:0); - } - if (rev == 3) - { - // All WT are reversible - transfType = INV_RCT; - } - else if (rev == 0) - { - // All WT irreversible - transfType = INV_ICT; - } - else - { - // Error - throw new System.ArgumentException("Wavelet transformation and " + "component transformation" + " not coherent in tile" + tIdx); - } - } - } - } -} \ No newline at end of file + int w = blk.w; //width of output block + int h = blk.h; //height of ouput block + + int[] out_data; // array of output data + + //Reference to output block data array + out_data = (int[])blk.Data; + + //Create data array of blk if necessary + if (out_data == null) + { + out_data = new int[h * w]; + blk.Data = out_data; + } + + // Variables + DataBlkFloat indb = new DataBlkFloat(blk.ulx, blk.uly, w, h); + float[] indata; // input data array + + // Get the input data + // (returned block may be larger than requested one) + src.getInternCompData(indb, c); + indata = (float[])indb.Data; + + // Copy the data converting from int to int + k = w * h - 1; + k0 = indb.offset + (h - 1) * indb.scanw + w - 1; + for (i = h - 1; i >= 0; i--) + { + for (mink = k - w; k > mink; k--, k0--) + { + //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'" + out_data[k] = (int)(indata[k0]); + } + // Jump to beggining of previous line in input + k0 -= (indb.scanw - w); + } + + // Set the progressivity and offset + blk.progressive = indb.progressive; + blk.offset = 0; + blk.scanw = w; + } + // If asking a component for the first time for this block, + // do transform for the 3 components + else if ((outdata[c] == null) || (dbi.ulx > blk.ulx) || (dbi.uly > blk.uly) + || (dbi.ulx + dbi.w < blk.ulx + blk.w) || (dbi.uly + dbi.h < blk.uly + blk.h)) + { + int k, k0, k1, k2, mink, i; + int w = blk.w; //width of output block + int h = blk.h; //height of ouput block + + //Reference to output block data array + outdata[c] = (int[])blk.Data; + + //Create data array of blk if necessary + if (outdata[c] == null || outdata[c].Length != w * h) + { + outdata[c] = new int[h * w]; + blk.Data = outdata[c]; + } + + outdata[(c + 1) % 3] = new int[outdata[c].Length]; + outdata[(c + 2) % 3] = new int[outdata[c].Length]; + + if (block0 == null || block0.DataType != DataBlk.TYPE_FLOAT) block0 = new DataBlkFloat(); + if (block2 == null || block2.DataType != DataBlk.TYPE_FLOAT) block2 = new DataBlkFloat(); + if (block1 == null || block1.DataType != DataBlk.TYPE_FLOAT) block1 = new DataBlkFloat(); + block0.w = block2.w = block1.w = blk.w; + block0.h = block2.h = block1.h = blk.h; + block0.ulx = block2.ulx = block1.ulx = blk.ulx; + block0.uly = block2.uly = block1.uly = blk.uly; + + float[] data0, data1, data2; // input data arrays + + // Fill in buffer blocks (to be read only) + // Returned blocks may have different size and position + block0 = (DataBlkFloat)src.getInternCompData(block0, 0); + data0 = (float[])block0.Data; + block2 = (DataBlkFloat)src.getInternCompData(block2, 1); + data2 = (float[])block2.Data; + block1 = (DataBlkFloat)src.getInternCompData(block1, 2); + data1 = (float[])block1.Data; + + // Set the progressiveness of the output data + blk.progressive = block0.progressive || block1.progressive || block2.progressive; + blk.offset = 0; + blk.scanw = w; + + // set attributes of the DataBlk used for buffering + dbi.progressive = blk.progressive; + dbi.ulx = blk.ulx; + dbi.uly = blk.uly; + dbi.w = blk.w; + dbi.h = blk.h; + + //Perform conversion + + // Initialize general indexes + k = w * h - 1; + k0 = block0.offset + (h - 1) * block0.scanw + w - 1; + k2 = block2.offset + (h - 1) * block2.scanw + w - 1; + k1 = block1.offset + (h - 1) * block1.scanw + w - 1; + + for (i = h - 1; i >= 0; i--) + { + for (mink = k - w; k > mink; k--, k0--, k2--, k1--) + { + //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'" + outdata[0][k] = (int)(data0[k0] + 1.402f * data1[k1] + 0.5f); + //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'" + outdata[1][k] = (int)(data0[k0] - 0.34413f * data2[k2] - 0.71414f * data1[k1] + 0.5f); + //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'" + outdata[2][k] = (int)(data0[k0] + 1.772f * data2[k2] + 0.5f); + } + // Jump to beggining of previous line in input + k0 -= (block0.scanw - w); + k2 -= (block2.scanw - w); + k1 -= (block1.scanw - w); + } + outdata[c] = null; + } + else if ((c >= 0) && (c <= 3)) + { + //Asking for the 2nd or 3rd block component + blk.Data = outdata[c]; + blk.progressive = dbi.progressive; + blk.offset = (blk.uly - dbi.uly) * dbi.w + blk.ulx - dbi.ulx; + blk.scanw = dbi.w; + outdata[c] = null; + } + else + { + // Requesting a non valid component index + throw new System.ArgumentException(); + } + return blk; + } + + /// Changes the current tile, given the new indexes. An + /// IllegalArgumentException is thrown if the indexes do not + /// correspond to a valid tile. + /// + ///

This default implementation changes the tile in the source + /// and re-initializes properly component transformation variables.. + /// + ///

+ /// The horizontal index of the tile. + /// + /// + /// The vertical index of the new tile. + /// + /// + /// + public override void setTile(int x, int y) + { + src.setTile(x, y); + tIdx = TileIdx; // index of the current tile + + // initializations + if (((System.Int32)cts.getTileDef(tIdx)) == NONE) transfType = NONE; + else + { + int nc = src.NumComps > 3 ? 3 : src.NumComps; + int rev = 0; + for (int c = 0; c < nc; c++) + { + rev += (wfs.isReversible(tIdx, c) ? 1 : 0); + } + if (rev == 3) + { + // All WT are reversible + transfType = INV_RCT; + } + else if (rev == 0) + { + // All WT irreversible + transfType = INV_ICT; + } + else + { + // Error + throw new System.ArgumentException( + "Wavelet transformation and " + "component transformation" + " not coherent in tile" + tIdx); + } + } + } + + /// Advances to the next tile, in standard scan-line order (by rows + /// then columns). An NoNextElementException is thrown if the + /// current tile is the last one (i.e. there is no next tile). + /// + ///

This default implementation just advances to the next tile + /// in the source and re-initializes properly component + /// transformation variables. + /// + /// + ///

+ public override void nextTile() + { + src.nextTile(); + tIdx = TileIdx; // index of the current tile + + // initializations + if (((System.Int32)cts.getTileDef(tIdx)) == NONE) transfType = NONE; + else + { + int nc = src.NumComps > 3 ? 3 : src.NumComps; + int rev = 0; + for (int c = 0; c < nc; c++) + { + rev += (wfs.isReversible(tIdx, c) ? 1 : 0); + } + if (rev == 3) + { + // All WT are reversible + transfType = INV_RCT; + } + else if (rev == 0) + { + // All WT irreversible + transfType = INV_ICT; + } + else + { + // Error + throw new System.ArgumentException( + "Wavelet transformation and " + "component transformation" + " not coherent in tile" + tIdx); + } + } + } + } +} diff --git a/CSJ2K/j2k/image/output/ImgWriterPGM.cs b/CSJ2K/j2k/image/output/ImgWriterPGM.cs index 121a1e62..043705e5 100644 --- a/CSJ2K/j2k/image/output/ImgWriterPGM.cs +++ b/CSJ2K/j2k/image/output/ImgWriterPGM.cs @@ -42,6 +42,7 @@ * Copyright (c) 1999/2000 JJ2000 Partners. * */ using System; +using CSJ2K.Util; using CSJ2K.j2k.image; using CSJ2K.j2k.util; namespace CSJ2K.j2k.image.output @@ -73,7 +74,7 @@ public class ImgWriterPGM:ImgWriter /// Where to write the data //UPGRADE_TODO: Class 'java.io.RandomAccessFile' was converted to 'System.IO.FileStream' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javaioRandomAccessFile'" - private System.IO.FileStream out_Renamed; + private System.IO.Stream out_Renamed; /// The index of the component from where to get the data private int c; @@ -111,7 +112,7 @@ public class ImgWriterPGM:ImgWriter /// The index of the component from where to get the data. /// /// - public ImgWriterPGM(System.IO.FileInfo out_Renamed, BlkImgDataSrc imgSrc, int c) + public ImgWriterPGM(IFileInfo out_Renamed, BlkImgDataSrc imgSrc, int c) { // Check that imgSrc is of the correct type // Check that the component index is valid @@ -127,25 +128,7 @@ public ImgWriterPGM(System.IO.FileInfo out_Renamed, BlkImgDataSrc imgSrc, int c) } // Initialize - bool tmpBool; - if (System.IO.File.Exists(out_Renamed.FullName)) - tmpBool = true; - else - tmpBool = System.IO.Directory.Exists(out_Renamed.FullName); - bool tmpBool2; - if (System.IO.File.Exists(out_Renamed.FullName)) - { - System.IO.File.Delete(out_Renamed.FullName); - tmpBool2 = true; - } - else if (System.IO.Directory.Exists(out_Renamed.FullName)) - { - System.IO.Directory.Delete(out_Renamed.FullName); - tmpBool2 = true; - } - else - tmpBool2 = false; - if (tmpBool && !tmpBool2) + if (out_Renamed.Exists && !out_Renamed.Delete()) { throw new System.IO.IOException("Could not reset file"); } @@ -177,7 +160,7 @@ public ImgWriterPGM(System.IO.FileInfo out_Renamed, BlkImgDataSrc imgSrc, int c) /// The index of the component from where to get the data. /// /// - public ImgWriterPGM(System.String fname, BlkImgDataSrc imgSrc, int c):this(new System.IO.FileInfo(fname), imgSrc, c) + public ImgWriterPGM(System.String fname, BlkImgDataSrc imgSrc, int c):this(FileInfoFactory.New(fname), imgSrc, c) { } @@ -204,7 +187,7 @@ public override void close() out_Renamed.WriteByte((System.Byte) 0); } } - out_Renamed.Close(); + out_Renamed.Dispose(); src = null; out_Renamed = null; db = null; @@ -375,7 +358,7 @@ private void writeHeaderInfo() offset = 3; // Write width in ASCII val = System.Convert.ToString(w); - byteVals = System.Text.ASCIIEncoding.ASCII.GetBytes(val); + byteVals = System.Text.Encoding.UTF8.GetBytes(val); for (i = 0; i < byteVals.Length; i++) { out_Renamed.WriteByte((byte) byteVals[i]); @@ -385,7 +368,7 @@ private void writeHeaderInfo() offset++; // Write height in ASCII val = System.Convert.ToString(h); - byteVals = System.Text.ASCIIEncoding.ASCII.GetBytes(val); + byteVals = System.Text.Encoding.UTF8.GetBytes(val); for (i = 0; i < byteVals.Length; i++) { out_Renamed.WriteByte((byte) byteVals[i]); diff --git a/CSJ2K/j2k/image/output/ImgWriterPGX.cs b/CSJ2K/j2k/image/output/ImgWriterPGX.cs index ceb4ad18..01563ee5 100644 --- a/CSJ2K/j2k/image/output/ImgWriterPGX.cs +++ b/CSJ2K/j2k/image/output/ImgWriterPGX.cs @@ -42,6 +42,7 @@ * Copyright (c) 1999/2000 JJ2000 Partners. * */ using System; +using CSJ2K.Util; using CSJ2K.j2k.image; using CSJ2K.j2k.util; namespace CSJ2K.j2k.image.output @@ -115,7 +116,7 @@ public class ImgWriterPGX:ImgWriter /// Where to write the data //UPGRADE_TODO: Class 'java.io.RandomAccessFile' was converted to 'System.IO.FileStream' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javaioRandomAccessFile'" - private System.IO.FileStream out_Renamed; + private System.IO.Stream out_Renamed; /// The offset of the raw pixel data in the PGX file private int offset; @@ -170,29 +171,11 @@ public class ImgWriterPGX:ImgWriter /// /// /// - public ImgWriterPGX(System.IO.FileInfo out_Renamed, BlkImgDataSrc imgSrc, int c, bool isSigned) + public ImgWriterPGX(IFileInfo out_Renamed, BlkImgDataSrc imgSrc, int c, bool isSigned) { //Initialize this.c = c; - bool tmpBool; - if (System.IO.File.Exists(out_Renamed.FullName)) - tmpBool = true; - else - tmpBool = System.IO.Directory.Exists(out_Renamed.FullName); - bool tmpBool2; - if (System.IO.File.Exists(out_Renamed.FullName)) - { - System.IO.File.Delete(out_Renamed.FullName); - tmpBool2 = true; - } - else if (System.IO.Directory.Exists(out_Renamed.FullName)) - { - System.IO.Directory.Delete(out_Renamed.FullName); - tmpBool2 = true; - } - else - tmpBool2 = false; - if (tmpBool && !tmpBool2) + if (out_Renamed.Exists && !out_Renamed.Delete()) { throw new System.IO.IOException("Could not reset file"); } @@ -225,7 +208,7 @@ public ImgWriterPGX(System.IO.FileInfo out_Renamed, BlkImgDataSrc imgSrc, int c, // Writes PGX header System.String tmpString = "PG " + "ML " + ((this.isSigned)?"- ":"+ ") + bitDepth + " " + w + " " + h + "\n"; // component height - byte[] tmpByte = System.Text.ASCIIEncoding.ASCII.GetBytes(tmpString); + byte[] tmpByte = System.Text.Encoding.UTF8.GetBytes(tmpString); for (int i = 0; i < tmpByte.Length; i++) { this.out_Renamed.WriteByte((byte) tmpByte[i]); @@ -267,7 +250,7 @@ public ImgWriterPGX(System.IO.FileInfo out_Renamed, BlkImgDataSrc imgSrc, int c, /// /// /// - public ImgWriterPGX(System.String fname, BlkImgDataSrc imgSrc, int c, bool isSigned):this(new System.IO.FileInfo(fname), imgSrc, c, isSigned) + public ImgWriterPGX(System.String fname, BlkImgDataSrc imgSrc, int c, bool isSigned):this(FileInfoFactory.New(fname), imgSrc, c, isSigned) { } @@ -294,7 +277,7 @@ public override void close() out_Renamed.WriteByte((System.Byte) 0); } } - out_Renamed.Close(); + out_Renamed.Dispose(); src = null; out_Renamed = null; db = null; diff --git a/CSJ2K/j2k/image/output/ImgWriterPPM.cs b/CSJ2K/j2k/image/output/ImgWriterPPM.cs index f4c24bc2..cb27655c 100644 --- a/CSJ2K/j2k/image/output/ImgWriterPPM.cs +++ b/CSJ2K/j2k/image/output/ImgWriterPPM.cs @@ -42,6 +42,7 @@ * Copyright (c) 1999/2000 JJ2000 Partners. * */ using System; +using CSJ2K.Util; using CSJ2K.j2k.image; using CSJ2K.j2k.util; using CSJ2K.j2k.io; @@ -81,7 +82,7 @@ public class ImgWriterPPM:ImgWriter /// Where to write the data //UPGRADE_TODO: Class 'java.io.RandomAccessFile' was converted to 'System.IO.FileStream' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javaioRandomAccessFile'" - private System.IO.FileStream out_Renamed; + private System.IO.Stream out_Renamed; /// The array of indexes of the components from where to get the data private int[] cps = new int[3]; @@ -132,7 +133,7 @@ public class ImgWriterPPM:ImgWriter /// /// /// - public ImgWriterPPM(System.IO.FileInfo out_Renamed, BlkImgDataSrc imgSrc, int n1, int n2, int n3) + public ImgWriterPPM(IFileInfo out_Renamed, BlkImgDataSrc imgSrc, int n1, int n2, int n3) { // Check that imgSrc is of the correct type // Check that the component index is valid @@ -152,25 +153,7 @@ public ImgWriterPPM(System.IO.FileInfo out_Renamed, BlkImgDataSrc imgSrc, int n1 h = imgSrc.ImgHeight; // Continue initialization - bool tmpBool; - if (System.IO.File.Exists(out_Renamed.FullName)) - tmpBool = true; - else - tmpBool = System.IO.Directory.Exists(out_Renamed.FullName); - bool tmpBool2; - if (System.IO.File.Exists(out_Renamed.FullName)) - { - System.IO.File.Delete(out_Renamed.FullName); - tmpBool2 = true; - } - else if (System.IO.Directory.Exists(out_Renamed.FullName)) - { - System.IO.Directory.Delete(out_Renamed.FullName); - tmpBool2 = true; - } - else - tmpBool2 = false; - if (tmpBool && !tmpBool2) + if (out_Renamed.Exists && !out_Renamed.Delete()) { throw new System.IO.IOException("Could not reset file"); } @@ -218,7 +201,7 @@ public ImgWriterPPM(System.IO.FileInfo out_Renamed, BlkImgDataSrc imgSrc, int n1 /// /// /// - public ImgWriterPPM(System.String fname, BlkImgDataSrc imgSrc, int n1, int n2, int n3):this(new System.IO.FileInfo(fname), imgSrc, n1, n2, n3) + public ImgWriterPPM(System.String fname, BlkImgDataSrc imgSrc, int n1, int n2, int n3):this(FileInfoFactory.New(fname), imgSrc, n1, n2, n3) { } @@ -245,7 +228,7 @@ public override void close() out_Renamed.WriteByte((System.Byte) 0); } } - out_Renamed.Close(); + out_Renamed.Dispose(); src = null; out_Renamed = null; db = null; @@ -424,7 +407,7 @@ private void writeHeaderInfo() offset = 3; // Write width in ASCII val = System.Convert.ToString(w); - byteVals = System.Text.ASCIIEncoding.ASCII.GetBytes(val); + byteVals = System.Text.Encoding.UTF8.GetBytes(val); for (i = 0; i < byteVals.Length; i++) { out_Renamed.WriteByte((byte) byteVals[i]); @@ -434,7 +417,7 @@ private void writeHeaderInfo() offset++; // Write height in ASCII val = System.Convert.ToString(h); - byteVals = System.Text.ASCIIEncoding.ASCII.GetBytes(val); + byteVals = System.Text.Encoding.UTF8.GetBytes(val); for (i = 0; i < byteVals.Length; i++) { out_Renamed.WriteByte((byte) byteVals[i]); diff --git a/CSJ2K/j2k/io/BEBufferedRandomAccessFile.cs b/CSJ2K/j2k/io/BEBufferedRandomAccessFile.cs index f55500e7..37a152d6 100644 --- a/CSJ2K/j2k/io/BEBufferedRandomAccessFile.cs +++ b/CSJ2K/j2k/io/BEBufferedRandomAccessFile.cs @@ -41,9 +41,12 @@ * Copyright (c) 1999/2000 JJ2000 Partners. * */ using System; +using CSJ2K.Util; + namespace CSJ2K.j2k.io { - + using System.IO; + /// This class defines a Buffered Random Access File, where all I/O is /// considered to be big-endian. It extends the /// BufferedRandomAccessFile class. @@ -60,51 +63,33 @@ namespace CSJ2K.j2k.io /// public class BEBufferedRandomAccessFile:BufferedRandomAccessFile, RandomAccessIO, EndianType { - /// Constructor. Always needs a size for the buffer. /// /// - /// The file associated with the buffer - /// - /// - /// "r" for read, "rw" or "rw+" for read and write mode ("rw+" - /// opens the file for update whereas "rw" removes it - /// before. So the 2 modes are different only if the file - /// already exists). - /// - /// - /// The number of bytes to buffer - /// - /// + /// The stream associated with the buffer + /// Indicates whether file is read-only or not. + /// The number of bytes to buffer /// If an I/O error ocurred. /// /// - public BEBufferedRandomAccessFile(System.IO.FileInfo file, System.String mode, int bufferSize):base(file, mode, bufferSize) + public BEBufferedRandomAccessFile(Stream stream, bool isReadOnly, int bufferSize) + : base(stream, isReadOnly, bufferSize) { byte_Ordering = CSJ2K.j2k.io.EndianType_Fields.BIG_ENDIAN; } - + /// Constructor. Uses the default value for the byte-buffer size (512 /// bytes). - /// /// - /// The file associated with the buffer - /// - /// - /// "r" for read, "rw" or "rw+" for read and write mode ("rw+" - /// opens the file for update whereas "rw" removes it - /// before. So the 2 modes are different only if the file - /// already exists). - /// - /// - /// If an I/O error ocurred. - /// - /// - public BEBufferedRandomAccessFile(System.IO.FileInfo file, System.String mode):base(file, mode) + /// The stream associated with the buffer + /// Indicates whether file is read-only or not. + /// If an I/O error ocurred. + public BEBufferedRandomAccessFile(Stream stream, bool isReadOnly) + : base(stream, isReadOnly) { byte_Ordering = CSJ2K.j2k.io.EndianType_Fields.BIG_ENDIAN; } - + /// Constructor. Always needs a size for the buffer. /// /// @@ -226,35 +211,35 @@ public override void writeLong(long v) /// public override void writeFloat(float v) { - // CONVERSION PROBLEM? OPTIMIZE!!! - //byte[] floatbytes = BitConverter.GetBytes(v); - //for (int i = floatbytes.Length-1; i >= 0 ; i--) write(floatbytes[i]); + // CONVERSION PROBLEM? OPTIMIZE!!! + //byte[] floatbytes = BitConverter.GetBytes(v); + //for (int i = floatbytes.Length-1; i >= 0 ; i--) write(floatbytes[i]); //UPGRADE_ISSUE: Method 'java.lang.Float.floatToIntBits' was not converted. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1000_javalangFloatfloatToIntBits_float'" - //int intV = Float.floatToIntBits(v); - int intV = BitConverter.ToInt32(BitConverter.GetBytes(v), 0); + //int intV = Float.floatToIntBits(v); + int intV = BitConverter.ToInt32(BitConverter.GetBytes(v), 0); write(SupportClass.URShift(intV, 24)); write(SupportClass.URShift(intV, 16)); write(SupportClass.URShift(intV, 8)); write(intV); } - /// Writes the IEEE double value v (i.e., 64 bits) to the - /// output. Prior to writing, the output should be realigned at the byte - /// level. - /// - /// - /// The value to write to the output - /// - /// - /// If an I/O error ocurred. - /// - /// - public override void writeDouble(double v) + /// Writes the IEEE double value v (i.e., 64 bits) to the + /// output. Prior to writing, the output should be realigned at the byte + /// level. + /// + /// + /// The value to write to the output + /// + /// + /// If an I/O error ocurred. + /// + /// + public override void writeDouble(double v) { - //byte[] doublebytes = BitConverter.GetBytes(v); - //for (int i = doublebytes.Length-1; i >= 0 ; i--) write(doublebytes[i]); - + //byte[] doublebytes = BitConverter.GetBytes(v); + //for (int i = doublebytes.Length-1; i >= 0 ; i--) write(doublebytes[i]); + //UPGRADE_ISSUE: Method 'java.lang.Double.doubleToLongBits' was not converted. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1000_javalangDoubledoubleToLongBits_double'" //long longV = Double.doubleToLongBits(v); long longV = BitConverter.ToInt64(BitConverter.GetBytes(v), 0); @@ -266,24 +251,24 @@ public override void writeDouble(double v) write((int) (SupportClass.URShift(longV, 16))); write((int) (SupportClass.URShift(longV, 8))); write((int) (longV)); - + } - /// Reads a signed short (i.e. 16 bit) from the input. Prior to reading, - /// the input should be realigned at the byte level. - /// - /// - /// The next byte-aligned signed short (16 bit) from the input. - /// - /// - /// If the end-of file was reached before - /// getting all the necessary data. - /// - /// - /// If an I/O error ocurred. - /// - /// - public override short readShort() + /// Reads a signed short (i.e. 16 bit) from the input. Prior to reading, + /// the input should be realigned at the byte level. + /// + /// + /// The next byte-aligned signed short (16 bit) from the input. + /// + /// + /// If the end-of file was reached before + /// getting all the necessary data. + /// + /// + /// If an I/O error ocurred. + /// + /// + public override short readShort() { return (short) ((read() << 8) | (read())); } @@ -366,9 +351,9 @@ public override long readUnsignedInt() /// public override long readLong() { - //byte[] longbytes = new byte[8]; - //for (int i = longbytes.Length-1; i >= 0; i--) longbytes[i] = read(); - //return BitConverter.ToInt64(longbytes, 0); + //byte[] longbytes = new byte[8]; + //for (int i = longbytes.Length-1; i >= 0; i--) longbytes[i] = read(); + //return BitConverter.ToInt64(longbytes, 0); return ((long)(((ulong) read() << 56) | ((ulong) read() << 48) | ((ulong) read() << 40) | ((ulong) read() << 32) | ((ulong) read() << 24) | ((ulong) read() << 16) | ((ulong) read() << 8) | ((ulong) read()))); } @@ -389,14 +374,14 @@ public override long readLong() /// public override float readFloat() { - // CONVERSION PROBLEM? OPTIMIZE!!! - //byte[] floatbytes = new byte[4]; - //for (int i = floatbytes.Length-1; i >= 0 ; i--) floatbytes[i] = (byte)read(); - //return BitConverter.ToSingle(floatbytes, 0); + // CONVERSION PROBLEM? OPTIMIZE!!! + //byte[] floatbytes = new byte[4]; + //for (int i = floatbytes.Length-1; i >= 0 ; i--) floatbytes[i] = (byte)read(); + //return BitConverter.ToSingle(floatbytes, 0); //UPGRADE_ISSUE: Method 'java.lang.Float.intBitsToFloat' was not converted. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1000_javalangFloatintBitsToFloat_int'" - //return Float.intBitsToFloat((read() << 24) | (read() << 16) | (read() << 8) | (read())); - return BitConverter.ToSingle(BitConverter.GetBytes((read() << 24) | (read() << 16) | (read() << 8) | (read())), 0); + //return Float.intBitsToFloat((read() << 24) | (read() << 16) | (read() << 8) | (read())); + return BitConverter.ToSingle(BitConverter.GetBytes((read() << 24) | (read() << 16) | (read() << 8) | (read())), 0); } @@ -417,15 +402,15 @@ public override float readFloat() /// public override double readDouble() { - // CONVERSION PROBLEM? OPTIMIZE!!! - //byte[] doublebytes = new byte[8]; - //for (int i = doublebytes.Length-1; i >=0 ; i--) doublebytes[i] = (byte)read(); - //return BitConverter.ToDouble(doublebytes, 0); + // CONVERSION PROBLEM? OPTIMIZE!!! + //byte[] doublebytes = new byte[8]; + //for (int i = doublebytes.Length-1; i >=0 ; i--) doublebytes[i] = (byte)read(); + //return BitConverter.ToDouble(doublebytes, 0); //UPGRADE_ISSUE: Method 'java.lang.Double.longBitsToDouble' was not converted. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1000_javalangDoublelongBitsToDouble_long'" //return Double.longBitsToDouble(((long) read() << 56) | ((long) read() << 48) | ((long) read() << 40) | ((long) read() << 32) | ((long) read() << 24) | ((long) read() << 16) | ((long) read() << 8) | ((long) read())); - - return BitConverter.ToDouble(BitConverter.GetBytes(((long) read() << 56) | ((long) read() << 48) | ((long) read() << 40) | ((long) read() << 32) | ((long) read() << 24) | ((long) read() << 16) | ((long) read() << 8) | ((long) read())), 0); + + return BitConverter.ToDouble(BitConverter.GetBytes(((long) read() << 56) | ((long) read() << 48) | ((long) read() << 40) | ((long) read() << 32) | ((long) read() << 24) | ((long) read() << 16) | ((long) read() << 8) | ((long) read())), 0); } diff --git a/CSJ2K/j2k/io/BufferedRandomAccessFile.cs b/CSJ2K/j2k/io/BufferedRandomAccessFile.cs index b97d7150..ee337297 100644 --- a/CSJ2K/j2k/io/BufferedRandomAccessFile.cs +++ b/CSJ2K/j2k/io/BufferedRandomAccessFile.cs @@ -40,10 +40,13 @@ * * Copyright (c) 1999/2000 JJ2000 Partners. * */ -using System; namespace CSJ2K.j2k.io { - + using System; + using System.IO; + + using CSJ2K.Util; + /// This class defines a Buffered Random Access File. It implements the /// BinaryDataInput and BinaryDataOutput interfaces so that /// binary data input/output can be performed. This class is abstract since no @@ -116,7 +119,7 @@ virtual public int ByteOrdering /// /// //UPGRADE_TODO: Class 'java.io.RandomAccessFile' was converted to 'System.IO.FileStream' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javaioRandomAccessFile'" - private System.IO.FileStream theFile; + private System.IO.Stream theFile; /// Buffer of bytes containing the part of the file that is currently being /// accessed @@ -153,7 +156,45 @@ virtual public int ByteOrdering /* The endianess of the class */ protected internal int byte_Ordering; - + + /// Constructor. Always needs a size for the buffer. + /// + /// + /// The stream associated with the buffer + /// + /// + /// Indicates whether file is read-only or not. + /// The number of bytes to buffer + /// + /// + /// If an I/O error ocurred. + /// + /// + protected internal BufferedRandomAccessFile(Stream stream, bool isReadOnly, int bufferSize) + { + fileName = String.Empty; + theFile = stream; + this.isReadOnly = isReadOnly; + byteBuffer = new byte[bufferSize]; + readNewBuffer(0); + } + + /// Constructor. Uses the default value for the byte-buffer + /// size (512 bytes). + /// + /// + /// The stream associated with the buffer + /// + /// + /// Indicates whether file is read-only or not. + /// If an I/O error ocurred. + /// + /// + protected internal BufferedRandomAccessFile(Stream stream, bool isReadOnly) + : this(stream, isReadOnly, 512) + { + } + /// Constructor. Always needs a size for the buffer. /// /// @@ -169,10 +210,10 @@ virtual public int ByteOrdering /// The number of bytes to buffer /// /// - /// If an I/O error ocurred. + /// If an I/O error ocurred. /// /// - protected internal BufferedRandomAccessFile(System.IO.FileInfo file, System.String mode, int bufferSize) + protected internal BufferedRandomAccessFile(IFileInfo file, System.String mode, int bufferSize) { fileName = file.Name; @@ -182,29 +223,9 @@ protected internal BufferedRandomAccessFile(System.IO.FileInfo file, System.Stri isReadOnly = false; if (mode.Equals("rw")) { - // mode read / (over)write - bool tmpBool; - if (System.IO.File.Exists(file.FullName)) - tmpBool = true; - else - tmpBool = System.IO.Directory.Exists(file.FullName); - if (tmpBool) - // Output file already exists + if (file.Exists && !file.Delete()) { - bool tmpBool2; - if (System.IO.File.Exists(file.FullName)) - { - System.IO.File.Delete(file.FullName); - tmpBool2 = true; - } - else if (System.IO.Directory.Exists(file.FullName)) - { - System.IO.Directory.Delete(file.FullName); - tmpBool2 = true; - } - else - tmpBool2 = false; - bool generatedAux = tmpBool2; + throw new System.IO.IOException("Could not delete existing file"); } } mode = "rw"; @@ -227,10 +248,10 @@ protected internal BufferedRandomAccessFile(System.IO.FileInfo file, System.Stri /// file already exists). /// /// - /// If an I/O error ocurred. + /// If an I/O error ocurred. /// /// - protected internal BufferedRandomAccessFile(System.IO.FileInfo file, System.String mode):this(file, mode, 512) + protected internal BufferedRandomAccessFile(IFileInfo file, System.String mode):this(file, mode, 512) { } @@ -249,10 +270,10 @@ protected internal BufferedRandomAccessFile(System.IO.FileInfo file, System.Stri /// The number of bytes to buffer /// /// - /// If an I/O error ocurred. + /// If an I/O error ocurred. /// /// - protected internal BufferedRandomAccessFile(System.String name, System.String mode, int bufferSize):this(new System.IO.FileInfo(name), mode, bufferSize) + protected internal BufferedRandomAccessFile(System.String name, System.String mode, int bufferSize):this(FileInfoFactory.New(name), mode, bufferSize) { } @@ -269,7 +290,7 @@ protected internal BufferedRandomAccessFile(System.String name, System.String mo /// file already exists). /// /// - /// If an I/O error ocurred. + /// If an I/O error ocurred. /// /// protected internal BufferedRandomAccessFile(System.String name, System.String mode):this(name, mode, 512) @@ -284,7 +305,7 @@ protected internal BufferedRandomAccessFile(System.String name, System.String mo /// The offset where to move to. /// /// - /// If an I/O error ocurred. + /// If an I/O error ocurred. /// /// protected internal void readNewBuffer(int off) @@ -328,7 +349,7 @@ protected internal void readNewBuffer(int off) /// Closes the buffered random access file /// /// - /// If an I/O error ocurred. + /// If an I/O error ocurred. /// /// public virtual void close() @@ -338,7 +359,6 @@ public virtual void close() */ flush(); byteBuffer = null; // Release the byte-buffer reference - theFile.Close(); } /// Returns the current length of the stream, in bytes, taking into @@ -348,7 +368,7 @@ public virtual void close() /// The length of the stream, in bytes. /// /// - /// If an I/O error ocurred. + /// If an I/O error ocurred. /// /// public virtual int length() @@ -381,7 +401,7 @@ public virtual int length() /// If in read-only and seeking beyond EOF. /// /// - /// If an I/O error ocurred. + /// If an I/O error ocurred. /// /// public virtual void seek(int off) @@ -410,14 +430,14 @@ public virtual void seek(int off) /// The byte read. /// /// - /// If an I/O error ocurred. + /// If an I/O error ocurred. /// /// /// If the end of file was reached /// /// - public byte readByte() { return read(); } - public byte readUnsignedByte() { return read(); } + public byte readByte() { return read(); } + public byte readUnsignedByte() { return read(); } public byte read() { if (position < maxByte) @@ -501,7 +521,7 @@ public void readFully(byte[] b, int off, int len) /// written. /// /// - /// If an I/O error ocurred. + /// If an I/O error ocurred. /// /// public void write(int b) @@ -535,7 +555,7 @@ public void write(int b) /// The byte to write. /// /// - /// If an I/O error ocurred. + /// If an I/O error ocurred. /// /// public void write(byte b) @@ -575,7 +595,7 @@ public void write(byte b) /// The number of bytes from b to write /// /// - /// If an I/O error ocurred. + /// If an I/O error ocurred. /// /// public void write(byte[] b, int offset, int length) @@ -604,7 +624,7 @@ public void write(byte[] b, int offset, int length) /// The value to write to the output /// /// - /// If an I/O error ocurred. + /// If an I/O error ocurred. /// /// public void writeByte(int v) @@ -617,7 +637,7 @@ public void writeByte(int v) /// at the byte level. /// /// - /// If an I/O error ocurred. + /// If an I/O error ocurred. /// /// public void flush() @@ -700,7 +720,7 @@ public int readUnsignedByte() /// all the bytes could be skipped. /// /// - /// If an I/O error ocurred. + /// If an I/O error ocurred. /// /// public virtual int skipBytes(int n) diff --git a/CSJ2K/j2k/quantization/GuardBitsSpec.cs b/CSJ2K/j2k/quantization/GuardBitsSpec.cs index b630e5ca..3c7a40b5 100644 --- a/CSJ2K/j2k/quantization/GuardBitsSpec.cs +++ b/CSJ2K/j2k/quantization/GuardBitsSpec.cs @@ -138,7 +138,7 @@ public GuardBitsSpec(int nt, int nc, byte type, ParameterList pl):base(nt, nc, t { value_Renamed = System.Int32.Parse(word); } - catch (System.FormatException) + catch (System.FormatException e) { throw new System.ArgumentException("Bad parameter for " + "-Qguard_bits option" + " : " + word); } diff --git a/CSJ2K/j2k/quantization/QuantStepSizeSpec.cs b/CSJ2K/j2k/quantization/QuantStepSizeSpec.cs index 7856325a..a725f47d 100644 --- a/CSJ2K/j2k/quantization/QuantStepSizeSpec.cs +++ b/CSJ2K/j2k/quantization/QuantStepSizeSpec.cs @@ -138,7 +138,7 @@ public QuantStepSizeSpec(int nt, int nc, byte type, ParameterList pl):base(nt, n //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'" value_Renamed = System.Single.Parse(word); } - catch (System.FormatException) + catch (System.FormatException e) { throw new System.ArgumentException("Bad parameter for " + "-Qstep option : " + word); } diff --git a/CSJ2K/j2k/roi/encoder/ROIScaler.cs b/CSJ2K/j2k/roi/encoder/ROIScaler.cs index 44fd19b1..93ad6fff 100644 --- a/CSJ2K/j2k/roi/encoder/ROIScaler.cs +++ b/CSJ2K/j2k/roi/encoder/ROIScaler.cs @@ -42,6 +42,7 @@ * Copyright (c) 1999/2000 JJ2000 Partners. * */ using System; +using System.Collections.Generic; using CSJ2K.j2k.quantization.quantizer; using CSJ2K.j2k.codestream.writer; using CSJ2K.j2k.wavelet.analysis; @@ -284,7 +285,7 @@ public virtual SubbandAn getAnSubbandTree(int t, int c) /// public static ROIScaler createInstance(Quantizer src, ParameterList pl, EncoderSpecs encSpec) { - System.Collections.ArrayList roiVector = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10)); + System.Collections.Generic.List roiVector = new List(10); ROIMaskGenerator maskGen = null; // Check parameters @@ -364,7 +365,7 @@ public static ROIScaler createInstance(Quantizer src, ParameterList pl, EncoderS /// The ROIs specified in roiopt /// /// - protected internal static System.Collections.ArrayList parseROIs(System.String roiopt, int nc, System.Collections.ArrayList roiVector) + protected internal static System.Collections.Generic.List parseROIs(System.String roiopt, int nc, System.Collections.Generic.List roiVector) { //ROI[] ROIs; ROI roi; @@ -402,11 +403,11 @@ protected internal static System.Collections.ArrayList parseROIs(System.String r word = stok.NextToken(); h = (System.Int32.Parse(word)); } - catch (System.FormatException) + catch (System.FormatException e) { throw new System.ArgumentException("Bad parameter for " + "'-Rroi R' option : " + word); } - catch (System.ArgumentOutOfRangeException) + catch (System.ArgumentOutOfRangeException f) { throw new System.ArgumentException("Wrong number of " + "parameters for " + "h'-Rroi R' option."); } @@ -444,11 +445,11 @@ protected internal static System.Collections.ArrayList parseROIs(System.String r word = stok.NextToken(); rad = (System.Int32.Parse(word)); } - catch (System.FormatException) + catch (System.FormatException e) { throw new System.ArgumentException("Bad parameter for " + "'-Rroi C' option : " + word); } - catch (System.ArgumentOutOfRangeException) + catch (System.ArgumentOutOfRangeException f) { throw new System.ArgumentException("Wrong number of " + "parameters for " + "'-Rroi C' option."); } @@ -484,7 +485,7 @@ protected internal static System.Collections.ArrayList parseROIs(System.String r { filename = stok.NextToken(); } - catch (System.ArgumentOutOfRangeException) + catch (System.ArgumentOutOfRangeException e) { throw new System.ArgumentException("Wrong number of " + "parameters for " + "'-Rroi A' option."); } @@ -492,9 +493,9 @@ protected internal static System.Collections.ArrayList parseROIs(System.String r { maskPGM = new ImgReaderPGM(filename); } - catch (System.IO.IOException) + catch (System.IO.IOException e) { - throw new System.ApplicationException("Cannot read PGM file with ROI"); + throw new System.InvalidOperationException("Cannot read PGM file with ROI"); } // If the ROI is component-specific, check which comps. @@ -519,7 +520,7 @@ protected internal static System.Collections.ArrayList parseROIs(System.String r break; default: - throw new System.ApplicationException("Bad parameters for ROI nr " + roiVector.Count); + throw new System.InvalidOperationException("Bad parameters for ROI nr " + roiVector.Count); } } diff --git a/CSJ2K/j2k/util/ArrayUtil.cs b/CSJ2K/j2k/util/ArrayUtil.cs index f8f024dc..2bbe89ab 100644 --- a/CSJ2K/j2k/util/ArrayUtil.cs +++ b/CSJ2K/j2k/util/ArrayUtil.cs @@ -44,22 +44,125 @@ * */ using System; -using System.Runtime.CompilerServices; - namespace CSJ2K.j2k.util { - public class ArrayUtil - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void intArraySet(int[] arr, int val) - { - Array.Fill(arr, val); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void byteArraySet(byte[] arr, byte val) - { - Array.Fill(arr, val); - } - } + + /// This class contains a colleaction of utility static methods for arrays. + /// + /// + public class ArrayUtil + { + + /// The maximum array size to do element by element copying, larger + /// arrays are copyied in a n optimized way. + /// + public const int MAX_EL_COPYING = 8; + + /// The number of elements to copy initially in an optimized array copy + public const int INIT_EL_COPYING = 4; + + /// Reinitializes an int array to the given value in an optimized way. If + /// the length of the array is less than MAX_EL_COPYING, then the array + /// is set element by element in the normal way, otherwise the first + /// INIT_EL_COPYING elements are set element by element and then + /// System.arraycopy is used to set the other parts of the array. + /// + /// + /// The array to set. + /// + /// + /// The value to set the array to. + /// + /// + /// + /// + public static void intArraySet(int[] arr, int val) + { + int i, len, len2; + + len = arr.Length; + // Set array to 'val' in an optimized way + if (len < MAX_EL_COPYING) + { + // Not worth doing optimized way + for (i = len - 1; i >= 0; i--) + { + // Set elements + arr[i] = val; + } + } + else + { + // Do in optimized way + len2 = len >> 1; + for (i = 0; i < INIT_EL_COPYING; i++) + { + // Set first elements + arr[i] = val; + } + for (; i <= len2; i <<= 1) + { + // Copy values doubling size each time + Array.Copy(arr, 0, arr, i, i); + } + if (i < len) + { + // Copy values to end + Array.Copy(arr, 0, arr, i, len - i); + } + } + } + + /// Reinitializes a byte array to the given value in an optimized way. If + /// the length of the array is less than MAX_EL_COPYING, then the array + /// is set element by element in the normal way, otherwise the first + /// INIT_EL_COPYING elements are set element by element and then + /// System.arraycopy is used to set the other parts of the array. + /// + /// + /// The array to set. + /// + /// + /// The value to set the array to. + /// + /// + /// + /// + public static void byteArraySet(byte[] arr, byte val) + { + int i, len, len2; + + len = arr.Length; + // Set array to 'val' in an optimized way + if (len < MAX_EL_COPYING) + { + // Not worth doing optimized way + for (i = len - 1; i >= 0; i--) + { + // Set elements + arr[i] = val; + } + } + else + { + // Do in optimized way + len2 = len >> 1; + for (i = 0; i < INIT_EL_COPYING; i++) + { + // Set first elements + arr[i] = val; + } + for (; i <= len2; i <<= 1) + { + // Copy values doubling size each time + Array.Copy(arr, 0, arr, i, i); + } + if (i < len) + { + // Copy values to end + Array.Copy(arr, 0, arr, i, len - i); + } + } + } + } } \ No newline at end of file diff --git a/CSJ2K/j2k/util/CodestreamManipulator.cs b/CSJ2K/j2k/util/CodestreamManipulator.cs index 72459073..1b351ee2 100644 --- a/CSJ2K/j2k/util/CodestreamManipulator.cs +++ b/CSJ2K/j2k/util/CodestreamManipulator.cs @@ -40,12 +40,13 @@ * * Copyright (c) 1999/2000 JJ2000 Partners. * */ -using System; -using CSJ2K.j2k.codestream; -using CSJ2K.j2k.io; namespace CSJ2K.j2k.util { - + using System.Collections.Generic; + using System.IO; + + using CSJ2K.j2k.io; + /// This class takes a legal JPEG 2000 codestream and performs some /// manipulation on it. Currently the manipulations supported are: Tile-parts /// @@ -60,35 +61,35 @@ private void InitBlock() /// Flag indicating whether packed packet headers in main header is used /// /// - private bool ppmUsed; + private readonly bool ppmUsed; /// Flag indicating whether packed packet headers in tile headers is used /// /// - private bool pptUsed; + private readonly bool pptUsed; /// Flag indicating whether SOP marker was only intended for parsing in /// This class and should be removed /// - private bool tempSop; + private readonly bool tempSop; /// Flag indicating whether EPH marker was only intended for parsing in /// This class and should be removed /// - private bool tempEph; + private readonly bool tempEph; /// The number of tiles in the image - private int nt; + private readonly int nt; /// The number of packets per tile-part private int pptp; /// The name of the outfile - private System.String outname; - + private readonly Stream stream; + /// The length of a SOT plus a SOD marker - private static int TP_HEAD_LEN = 14; - + private const int TP_HEAD_LEN = 14; + /// The maximum number of a tile part index (TPsot) //private static int MAX_TPSOT = 16; @@ -123,7 +124,7 @@ private void InitBlock() /// Instantiates a codestream manipulator.. /// /// - /// The name of the original outfile + /// The output stream /// /// /// The number of tiles in the image @@ -145,10 +146,10 @@ private void InitBlock() /// Flag indicating whether EPH merker should be removed /// /// - public CodestreamManipulator(System.String outname, int nt, int pptp, bool ppm, bool ppt, bool tempSop, bool tempEph) + public CodestreamManipulator(Stream stream, int nt, int pptp, bool ppm, bool ppt, bool tempSop, bool tempEph) { InitBlock(); - this.outname = outname; + this.stream = stream; this.nt = nt; this.pptp = pptp; this.ppmUsed = ppm; @@ -164,7 +165,7 @@ public CodestreamManipulator(System.String outname, int nt, int pptp, bool ppm, /// The number of bytes that the file has increased by /// /// - /// If an I/O error ocurred. + /// If an I/O error ocurred. /// /// public virtual int doCodestreamManipulation() @@ -183,7 +184,7 @@ public virtual int doCodestreamManipulation() return 0; // Open file for reading and writing - fi = new BEBufferedRandomAccessFile(outname, "rw+"); + fi = new BEBufferedRandomAccessFile(stream, false); addedHeaderBytes -= fi.length(); // Parse the codestream for SOT, SOP and EPH markers @@ -192,9 +193,8 @@ public virtual int doCodestreamManipulation() // Read and buffer the tile headers, packet headers and packet data readAndBuffer(fi); - // Close file and overwrite with new file - fi.close(); - fi = new BEBufferedRandomAccessFile(outname, "rw"); + // Rewind and overwrite with new contents + fi.seek(0); // Create tile-parts createTileParts(); @@ -218,7 +218,7 @@ public virtual int doCodestreamManipulation() /// The file to parse the markers from /// /// - /// If an I/O error ocurred. + /// If an I/O error ocurred. /// /// private void parseAndFind(BufferedRandomAccessFile fi) @@ -227,7 +227,7 @@ private void parseAndFind(BufferedRandomAccessFile fi) short marker; int halfMarker; int tileEnd; - System.Collections.ArrayList markPos = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10)); + System.Collections.Generic.List markPos = new List(10); // Find position of first SOT marker marker = (short) fi.readUnsignedShort(); // read SOC marker @@ -333,7 +333,7 @@ private void parseAndFind(BufferedRandomAccessFile fi) /// The file to read the headers and data from /// /// - /// If an I/O error ocurred. + /// If an I/O error ocurred. /// /// private void readAndBuffer(BufferedRandomAccessFile fi) @@ -410,13 +410,13 @@ private void readAndBuffer(BufferedRandomAccessFile fi) /// packet headers and packet data /// /// - /// If an I/O error ocurred. + /// If an I/O error ocurred. /// /// private void createTileParts() { int i, prem, t, length; - int pIndex; // phIndex removed + int pIndex; // phIndex removed int tppStart; int tilePart; int p, np, nomnp; @@ -569,11 +569,11 @@ private void createTileParts() } //UPGRADE_ISSUE: Method 'java.io.ByteArrayOutputStream.reset' was not converted. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1000_javaioByteArrayOutputStreamreset'" //temp.reset(); - temp.SetLength(0); + temp.SetLength(0); prem -= np; } } - temp.Close(); + temp.Dispose(); } /// This method writes the new codestream to the file. @@ -582,7 +582,7 @@ private void createTileParts() /// The file to write the new codestream to /// /// - /// If an I/O error ocurred. + /// If an I/O error ocurred. /// /// private void writeNewCodestream(BufferedRandomAccessFile fi) @@ -684,7 +684,7 @@ private void writeNewCodestream(BufferedRandomAccessFile fi) // Start new PPM marker segment //UPGRADE_ISSUE: Method 'java.io.ByteArrayOutputStream.reset' was not converted. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1000_javaioByteArrayOutputStreamreset'" //ppmMarkerSegment.reset(); - ppmMarkerSegment.SetLength(0); + ppmMarkerSegment.SetLength(0); ppmMarkerSegment.WriteByte((System.Byte) SupportClass.URShift(CSJ2K.j2k.codestream.Markers.PPM, 8)); ppmMarkerSegment.WriteByte((System.Byte) (CSJ2K.j2k.codestream.Markers.PPM & 0x00FF)); ppmMarkerSegment.WriteByte((System.Byte) 0); // Temporary Lppm value @@ -721,7 +721,7 @@ private void writeNewCodestream(BufferedRandomAccessFile fi) // Start new PPM marker segment //UPGRADE_ISSUE: Method 'java.io.ByteArrayOutputStream.reset' was not converted. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1000_javaioByteArrayOutputStreamreset'" //ppmMarkerSegment.reset(); - ppmMarkerSegment.SetLength(0); + ppmMarkerSegment.SetLength(0); ppmMarkerSegment.WriteByte((System.Byte) SupportClass.URShift(CSJ2K.j2k.codestream.Markers.PPM, 8)); ppmMarkerSegment.WriteByte((System.Byte) (CSJ2K.j2k.codestream.Markers.PPM & 0x00FF)); ppmMarkerSegment.WriteByte((System.Byte) 0); // Temp Lppm value diff --git a/CSJ2K/j2k/util/FacilityManager.cs b/CSJ2K/j2k/util/FacilityManager.cs index 661eeb5f..9dcede29 100644 --- a/CSJ2K/j2k/util/FacilityManager.cs +++ b/CSJ2K/j2k/util/FacilityManager.cs @@ -1,184 +1,102 @@ +// Copyright (c) 2007-2016 CSJ2K contributors. +// Licensed under the BSD 3-Clause License. + /* -* CVS identifier: -* -* $Id: FacilityManager.java,v 1.12 2002/05/22 15:00:24 grosbois Exp $ -* -* Class: MsgLoggerManager -* -* Description: Manages common facilities across threads -* -* -* -* COPYRIGHT: -* -* This software module was originally developed by Raphaël Grosbois and -* Diego Santa Cruz (Swiss Federal Institute of Technology-EPFL); Joel -* Askelöf (Ericsson Radio Systems AB); and Bertrand Berthelot, David -* Bouchard, Félix Henry, Gerard Mozelle and Patrice Onno (Canon Research -* Centre France S.A) in the course of development of the JPEG2000 -* standard as specified by ISO/IEC 15444 (JPEG 2000 Standard). This -* software module is an implementation of a part of the JPEG 2000 -* Standard. Swiss Federal Institute of Technology-EPFL, Ericsson Radio -* Systems AB and Canon Research Centre France S.A (collectively JJ2000 -* Partners) agree not to assert against ISO/IEC and users of the JPEG -* 2000 Standard (Users) any of their rights under the copyright, not -* including other intellectual property rights, for this software module -* with respect to the usage by ISO/IEC and Users of this software module -* or modifications thereof for use in hardware or software products -* claiming conformance to the JPEG 2000 Standard. Those intending to use -* this software module in hardware or software products are advised that -* their use may infringe existing patents. The original developers of -* this software module, JJ2000 Partners and ISO/IEC assume no liability -* for use of this software module or modifications thereof. No license -* or right to this software module is granted for non JPEG 2000 Standard -* conforming products. JJ2000 Partners have full right to use this -* software module for his/her own purpose, assign or donate this -* software module to any third party and to inhibit third parties from -* using this software module for non JPEG 2000 Standard conforming -* products. This copyright notice must be included in all copies or -* derivative works of this software module. -* -* Copyright (c) 1999/2000 JJ2000 Partners. -* */ -using System; + * JJ2000 COPYRIGHT: + * + * This software module was originally developed by Raphaël Grosbois and + * Diego Santa Cruz (Swiss Federal Institute of Technology-EPFL); Joel + * Askelöf (Ericsson Radio Systems AB); and Bertrand Berthelot, David + * Bouchard, Félix Henry, Gerard Mozelle and Patrice Onno (Canon Research + * Centre France S.A) in the course of development of the JPEG2000 + * standard as specified by ISO/IEC 15444 (JPEG 2000 Standard). This + * software module is an implementation of a part of the JPEG 2000 + * Standard. Swiss Federal Institute of Technology-EPFL, Ericsson Radio + * Systems AB and Canon Research Centre France S.A (collectively JJ2000 + * Partners) agree not to assert against ISO/IEC and users of the JPEG + * 2000 Standard (Users) any of their rights under the copyright, not + * including other intellectual property rights, for this software module + * with respect to the usage by ISO/IEC and Users of this software module + * or modifications thereof for use in hardware or software products + * claiming conformance to the JPEG 2000 Standard. Those intending to use + * this software module in hardware or software products are advised that + * their use may infringe existing patents. The original developers of + * this software module, JJ2000 Partners and ISO/IEC assume no liability + * for use of this software module or modifications thereof. No license + * or right to this software module is granted for non JPEG 2000 Standard + * conforming products. JJ2000 Partners have full right to use this + * software module for his/her own purpose, assign or donate this + * software module to any third party and to inhibit third parties from + * using this software module for non JPEG 2000 Standard conforming + * products. This copyright notice must be included in all copies or + * derivative works of this software module. + * + * Copyright (c) 1999/2000 JJ2000 Partners. + */ + namespace CSJ2K.j2k.util { - - /// This class manages common facilities for multi-threaded - /// environments, It can register different facilities for each thread, - /// and also a default one, so that they can be referred by static - /// methods, while possibly having different ones for different - /// threads. Also a default facility exists that is used for threads - /// for which no particular facility has been registerd registered. - /// - ///

Currently the only kind of facilities managed is MsgLogger.

- /// - ///

An example use of this class is if 2 instances of a decoder are running - /// in different threads and the messages of the 2 instances should be - /// separated. - /// - ///

The default MsgLogger is a StreamMsgLogger that uses System.out as - /// the 'out' stream and System.err as the 'err' stream, and a line width of - /// 78. This can be changed using the registerMsgLogger() method. - /// - ///

- /// - /// - /// - /// - /// - public class FacilityManager - { - /// Returns the ProgressWatch instance registered with the current - /// thread (the thread that calls this method). If the current - /// thread has no registered ProgressWatch, then the default one is used. - /// - /// - public static ProgressWatch ProgressWatch - { - get - { - ProgressWatch pw = (ProgressWatch) watchProgList[SupportClass.ThreadClass.Current()]; - return (pw == null)?defWatchProg:pw; - } - - } - - /// The loggers associated to different threads - //UPGRADE_NOTE: Final was removed from the declaration of 'loggerList '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" - private static readonly System.Collections.Hashtable loggerList = System.Collections.Hashtable.Synchronized(new System.Collections.Hashtable()); - - /// The default logger, for threads that have none associated with them - private static MsgLogger defMsgLogger = new StreamMsgLogger(System.Console.OpenStandardOutput(), System.Console.OpenStandardError(), 78); - - /// The ProgressWatch instance associated to different threads - //UPGRADE_NOTE: Final was removed from the declaration of 'watchProgList '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" - private static readonly System.Collections.Hashtable watchProgList = System.Collections.Hashtable.Synchronized(new System.Collections.Hashtable()); - - /// The default ProgressWatch for threads that have none - /// associated with them. - /// - private static ProgressWatch defWatchProg = null; - - - internal static void registerProgressWatch(SupportClass.ThreadClass t, ProgressWatch pw) - { - if (pw == null) - { - throw new System.NullReferenceException(); - } - if (t == null) - { - defWatchProg = pw; - } - else - { - watchProgList[t] = pw; - } - } - - /// Registers the MsgLogger 'ml' as the logging facility of the - /// thread 't'. If any other logging facility was registered with - /// the thread 't' it is overriden by 'ml'. If 't' is null then - /// 'ml' is taken as the default message logger that is used for - /// threads that have no MsgLogger registered. - /// - /// - /// The thread to associate with 'ml' - /// - /// - /// The MsgLogger to associate with therad ml - /// - /// - internal static void registerMsgLogger(SupportClass.ThreadClass t, MsgLogger ml) - { - if (ml == null) - { - throw new System.NullReferenceException(); - } - if (t == null) - { - defMsgLogger = ml; - } - else - { - loggerList[t] = ml; - } - } - - /// Returns the MsgLogger registered with the current thread (the - /// thread that calls this method). If the current thread has no - /// registered MsgLogger then the default message logger is - /// returned. - /// - /// - /// The MsgLogger registerd for the current thread, or the - /// default one if there is none registered for it. - /// - /// - public static MsgLogger getMsgLogger() - { - MsgLogger ml = (MsgLogger) loggerList[SupportClass.ThreadClass.Current()]; - return (ml == null)?defMsgLogger:ml; - } - - /// Returns the MsgLogger registered with the thread 't' (the - /// thread that calls this method). If the thread 't' has no - /// registered MsgLogger then the default message logger is - /// returned. - /// - /// - /// The thread for which to return the MsgLogger - /// - /// - /// The MsgLogger registerd for the current thread, or the - /// default one if there is none registered for it. - /// - /// - internal static MsgLogger getMsgLogger(SupportClass.ThreadClass t) - { - MsgLogger ml = (MsgLogger) loggerList[t]; - return (ml == null)?defMsgLogger:ml; - } - } -} \ No newline at end of file + using System; + + /// This class manages common facilities for multi-threaded + /// environments, It can register different facilities for each thread, + /// and also a default one, so that they can be referred by static + /// methods, while possibly having different ones for different + /// threads. Also a default facility exists that is used for threads + /// for which no particular facility has been registerd registered. + ///

Currently the only kind of facilities managed is MsgLogger.

+ ///

An example use of this class is if 2 instances of a decoder are running + /// in different threads and the messages of the 2 instances should be + /// separated.

+ ///

The default MsgLogger is a StreamMsgLogger that uses System.out as + /// the 'out' stream and System.err as the 'err' stream, and a line width of + /// 78. This can be changed using the registerMsgLogger() method.

+ ///
+ /// + /// + /// + /// + public static class FacilityManager + { + #region FIELDS + + private static IMsgLogger _defMsgLogger; + + #endregion + + #region CONSTRUCTORS + + static FacilityManager() + { + _defMsgLogger = J2kSetup.GetSinglePlatformInstance(); + } + + #endregion + + #region PROPERTIES + + /// The default logger, for threads that have none associated with them + public static IMsgLogger DefaultMsgLogger + { + set + { + _defMsgLogger = value; + } + } + + #endregion + + /// Returns the MsgLogger registered with the current thread (the + /// thread that calls this method). If the current thread has no + /// registered MsgLogger then the default message logger is + /// returned. + /// + /// The MsgLogger registerd for the current thread, or the + /// default one if there is none registered for it. + /// + public static IMsgLogger getMsgLogger() + { + return _defMsgLogger; + } + } +} diff --git a/CSJ2K/j2k/util/ISRandomAccessIO.cs b/CSJ2K/j2k/util/ISRandomAccessIO.cs index a3b634ef..a1d7d7e8 100644 --- a/CSJ2K/j2k/util/ISRandomAccessIO.cs +++ b/CSJ2K/j2k/util/ISRandomAccessIO.cs @@ -213,7 +213,7 @@ private void growBuffer() { newbuf = new byte[buf.Length + inc]; } - catch (System.OutOfMemoryException) + catch (System.OutOfMemoryException e) { throw new System.IO.IOException("Out of memory to cache input data"); } @@ -270,7 +270,7 @@ private void readInput() { /* we reached EOF */ complete = true; - is_Renamed.Close(); + is_Renamed.Dispose(); is_Renamed = null; } } @@ -288,7 +288,7 @@ public virtual void close() buf = null; if (!complete) { - is_Renamed.Close(); + is_Renamed.Dispose(); is_Renamed = null; } } diff --git a/CSJ2K/j2k/util/MathUtil.cs b/CSJ2K/j2k/util/MathUtil.cs index 8fdcdc0b..b9330812 100644 --- a/CSJ2K/j2k/util/MathUtil.cs +++ b/CSJ2K/j2k/util/MathUtil.cs @@ -41,7 +41,6 @@ * Copyright (c) 1999/2000 JJ2000 Partners. * */ using System; -using System.Runtime.CompilerServices; namespace CSJ2K.j2k.util { @@ -51,12 +50,34 @@ namespace CSJ2K.j2k.util ///
public class MathUtil { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int log2(int x) + + /// Method that calculates the floor of the log, base 2, of 'x'. The + /// calculation is performed in integer arithmetic, therefore, it is exact. + /// + /// + /// The value to calculate log2 on. + /// + /// + /// floor(log(x)/log(2)), calculated in an exact way. + /// + /// + public static int log2(int x) { - if (x <= 0) - throw new System.ArgumentException("" + x + " <= 0"); - return System.Numerics.BitOperations.Log2((uint)x); + int y, v; + // No log of 0 or negative + if (x <= 0) + { + throw new System.ArgumentException("" + x + " <= 0"); + } + // Calculate log2 (it's actually floor log2) + v = x; + y = - 1; + while (v > 0) + { + v >>= 1; + y++; + } + return y; } /// Method that calculates the Least Common Multiple (LCM) of two strictly @@ -93,7 +114,7 @@ public static int lcm(int x1, int x2) return i * max; } } - throw new System.ApplicationException("Cannot find the least common multiple of numbers " + x1 + " and " + x2); + throw new System.InvalidOperationException("Cannot find the least common multiple of numbers " + x1 + " and " + x2); } /// Method that calculates the Least Common Multiple (LCM) of several @@ -107,7 +128,7 @@ public static int lcm(int[] x) { if (x.Length < 2) { - throw new System.ApplicationException("Do not use this method if there are less than" + " two numbers."); + throw new System.InvalidOperationException("Do not use this method if there are less than" + " two numbers."); } int tmp = lcm(x[x.Length - 1], x[x.Length - 2]); for (int i = x.Length - 3; i >= 0; i--) @@ -169,7 +190,7 @@ public static int gcd(int[] x) { if (x.Length < 2) { - throw new System.ApplicationException("Do not use this method if there are less than" + " two numbers."); + throw new System.InvalidOperationException("Do not use this method if there are less than" + " two numbers."); } int tmp = gcd(x[x.Length - 1], x[x.Length - 2]); for (int i = x.Length - 3; i >= 0; i--) diff --git a/CSJ2K/j2k/util/MsgLogger.cs b/CSJ2K/j2k/util/MsgLogger.cs deleted file mode 100644 index 9ac63d49..00000000 --- a/CSJ2K/j2k/util/MsgLogger.cs +++ /dev/null @@ -1,135 +0,0 @@ -/* -* CVS identifier: -* -* $Id: MsgLogger.java,v 1.7 2001/08/17 16:24:51 grosbois Exp $ -* -* Class: MsgLogger -* -* Description: Facility to log messages (abstract) -* -* -* -* COPYRIGHT: -* -* This software module was originally developed by Raphaël Grosbois and -* Diego Santa Cruz (Swiss Federal Institute of Technology-EPFL); Joel -* Askelöf (Ericsson Radio Systems AB); and Bertrand Berthelot, David -* Bouchard, Félix Henry, Gerard Mozelle and Patrice Onno (Canon Research -* Centre France S.A) in the course of development of the JPEG2000 -* standard as specified by ISO/IEC 15444 (JPEG 2000 Standard). This -* software module is an implementation of a part of the JPEG 2000 -* Standard. Swiss Federal Institute of Technology-EPFL, Ericsson Radio -* Systems AB and Canon Research Centre France S.A (collectively JJ2000 -* Partners) agree not to assert against ISO/IEC and users of the JPEG -* 2000 Standard (Users) any of their rights under the copyright, not -* including other intellectual property rights, for this software module -* with respect to the usage by ISO/IEC and Users of this software module -* or modifications thereof for use in hardware or software products -* claiming conformance to the JPEG 2000 Standard. Those intending to use -* this software module in hardware or software products are advised that -* their use may infringe existing patents. The original developers of -* this software module, JJ2000 Partners and ISO/IEC assume no liability -* for use of this software module or modifications thereof. No license -* or right to this software module is granted for non JPEG 2000 Standard -* conforming products. JJ2000 Partners have full right to use this -* software module for his/her own purpose, assign or donate this -* software module to any third party and to inhibit third parties from -* using this software module for non JPEG 2000 Standard conforming -* products. This copyright notice must be included in all copies or -* derivative works of this software module. -* -* Copyright (c) 1999/2000 JJ2000 Partners. -* */ -using System; -namespace CSJ2K.j2k.util -{ - - /// This class provides a simple common abstraction of a facility that logs - /// and/or displays messages or simple strings. The underlying facility can be - /// a terminal, text file, text area in a GUI display, dialog boxes in a GUI - /// display, etc., or a combination of those. - /// - /// <>Messages are short strings (a couple of lines) that indicate some state - /// of the program, and that have a severity code associated with them (see - /// below). Simple strings is text (can be long) that has no severity code - /// associated with it. Typical use of simple strings is to display help - /// texts.

- /// - ///

Each message has a severity code, which can be one of the following: - /// LOG, INFO, WARNING, ERROR. Each implementation should treat each severity - /// code in a way which corresponds to the type of diplay used.

- /// - ///

Messages are printed via the 'printmsg()' method. Simple strings are - /// printed via the 'print()', 'println()' and 'flush()' methods, each simple - /// string is considered to be terminated once the 'flush()' method has been - /// called. The 'printmsg()' method should never be called before a previous - /// simple string has been terminated.

- /// - ///
- public struct MsgLogger_Fields{ - /// Severity of message. LOG messages are just for bookkeeping and do not - /// need to be displayed in the majority of cases - /// - public const int LOG = 0; - /// Severity of message. INFO messages should be displayed just for user - /// feedback. - /// - public const int INFO = 1; - /// Severity of message. WARNING messages denote that an unexpected state - /// has been reached and should be given as feedback to the user. - /// - public const int WARNING = 2; - /// Severity of message. ERROR messages denote that something has gone - /// wrong and probably that execution has ended. They should be definetely - /// displayed to the user. - /// - public const int ERROR = 3; - } - public interface MsgLogger - { - //UPGRADE_NOTE: Members of interface 'MsgLogger' were extracted into structure 'MsgLogger_Fields'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1045'" - - /// Prints the message 'msg' to the output device, appending a newline, - /// with severity 'sev'. Some implementations where the appended newline is - /// irrelevant may not append the newline. Depending on the implementation - /// the severity of the message may be added to it. The message is - /// reformatted as appropriate for the output devic, but any newline - /// characters are respected. - /// - /// - /// The message severity (LOG, INFO, etc.) - /// - /// - /// The message to display - /// - /// - void printmsg(int sev, System.String msg); - - /// Prints the string 'str' to the output device, appending a line - /// return. The message is reformatted as appropriate to the particular - /// diplaying device, where 'flind' and 'ind' are used as hints for - /// performing that operation. However, any newlines appearing in 'str' are - /// respected. The output device may not display the string until flush() - /// is called. Some implementations may automatically flush when this - /// method is called. This method just prints the string, the string does - /// not make part of a "message" in the sense that no severity is - /// associated to it. - /// - /// - /// The string to print - /// - /// - /// Indentation of the first line - /// - /// - /// Indentation of any other lines. - /// - /// - void println(System.String str, int flind, int ind); - - /// Writes any buffered data from the println() method to the device. - /// - /// - void flush(); - } -} \ No newline at end of file diff --git a/CSJ2K/j2k/util/ParameterList.cs b/CSJ2K/j2k/util/ParameterList.cs index a7583e32..2f050a99 100644 --- a/CSJ2K/j2k/util/ParameterList.cs +++ b/CSJ2K/j2k/util/ParameterList.cs @@ -67,8 +67,7 @@ namespace CSJ2K.j2k.util /// /// //UPGRADE_ISSUE: Class hierarchy differences between 'java.util.Properties' and 'System.Collections.Specialized.NameValueCollection' may cause compilation errors. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1186'" - [Serializable] - public class ParameterList:System.Collections.Specialized.NameValueCollection + public class ParameterList:System.Collections.Generic.Dictionary { // COVNERSION PROBLEM? private ParameterList defaults; @@ -287,14 +286,16 @@ public virtual System.String getParameter(System.String pname) { System.String pval; - pval = ((System.String) this[(System.String) pname]); //UPGRADE_ISSUE: Field 'java.util.Properties.defaults' was not converted. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1000_javautilPropertiesdefaults_f'" - if (pval == null && defaults != null) + if (!TryGetValue(pname, out pval) && defaults != null) { // if parameter is not there // Look in defaults //UPGRADE_ISSUE: Field 'java.util.Properties.defaults' was not converted. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1000_javautilPropertiesdefaults_f'" - pval = defaults.Get(pname); + if (!defaults.TryGetValue(pname, out pval)) + { + return null; + } } return pval; } @@ -450,10 +451,10 @@ public virtual float getFloatParameter(System.String pname) /// starting with 'prfx' which is not in the valid list of parameter names. /// /// - public virtual void checkList(char prfx, System.String[] plist) + public virtual void checkList(char prfx, string[] plist) { System.Collections.IEnumerator args; - System.String val; + string val; int i; bool isvalid; @@ -463,7 +464,7 @@ public virtual void checkList(char prfx, System.String[] plist) while (args.MoveNext()) { //UPGRADE_TODO: Method 'java.util.Enumeration.nextElement' was converted to 'System.Collections.IEnumerator.Current' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationnextElement'" - val = ((System.String) args.Current); + val = (string) args.Current; if (val.Length > 0 && val[0] == prfx) { isvalid = false; diff --git a/CSJ2K/j2k/util/StreamMsgLogger.cs b/CSJ2K/j2k/util/StreamMsgLogger.cs index 9734bf4c..4defda81 100644 --- a/CSJ2K/j2k/util/StreamMsgLogger.cs +++ b/CSJ2K/j2k/util/StreamMsgLogger.cs @@ -1,244 +1,175 @@ +// Copyright (c) 2007-2016 CSJ2K contributors. +// Licensed under the BSD 3-Clause License. + /* -* CVS identifier: -* -* $Id: StreamMsgLogger.java,v 1.11 2000/09/05 09:25:30 grosbois Exp $ -* -* Class: StreamMsgLogger -* -* Description: Implementation of MsgLogger for streams -* -* -* -* COPYRIGHT: -* -* This software module was originally developed by Raphaël Grosbois and -* Diego Santa Cruz (Swiss Federal Institute of Technology-EPFL); Joel -* Askelöf (Ericsson Radio Systems AB); and Bertrand Berthelot, David -* Bouchard, Félix Henry, Gerard Mozelle and Patrice Onno (Canon Research -* Centre France S.A) in the course of development of the JPEG2000 -* standard as specified by ISO/IEC 15444 (JPEG 2000 Standard). This -* software module is an implementation of a part of the JPEG 2000 -* Standard. Swiss Federal Institute of Technology-EPFL, Ericsson Radio -* Systems AB and Canon Research Centre France S.A (collectively JJ2000 -* Partners) agree not to assert against ISO/IEC and users of the JPEG -* 2000 Standard (Users) any of their rights under the copyright, not -* including other intellectual property rights, for this software module -* with respect to the usage by ISO/IEC and Users of this software module -* or modifications thereof for use in hardware or software products -* claiming conformance to the JPEG 2000 Standard. Those intending to use -* this software module in hardware or software products are advised that -* their use may infringe existing patents. The original developers of -* this software module, JJ2000 Partners and ISO/IEC assume no liability -* for use of this software module or modifications thereof. No license -* or right to this software module is granted for non JPEG 2000 Standard -* conforming products. JJ2000 Partners have full right to use this -* software module for his/her own purpose, assign or donate this -* software module to any third party and to inhibit third parties from -* using this software module for non JPEG 2000 Standard conforming -* products. This copyright notice must be included in all copies or -* derivative works of this software module. -* -* Copyright (c) 1999/2000 JJ2000 Partners. -* -* -* -*/ -using System; + * JJ2000 COPYRIGHT: + * + * This software module was originally developed by Raphaël Grosbois and + * Diego Santa Cruz (Swiss Federal Institute of Technology-EPFL); Joel + * Askelöf (Ericsson Radio Systems AB); and Bertrand Berthelot, David + * Bouchard, Félix Henry, Gerard Mozelle and Patrice Onno (Canon Research + * Centre France S.A) in the course of development of the JPEG2000 + * standard as specified by ISO/IEC 15444 (JPEG 2000 Standard). This + * software module is an implementation of a part of the JPEG 2000 + * Standard. Swiss Federal Institute of Technology-EPFL, Ericsson Radio + * Systems AB and Canon Research Centre France S.A (collectively JJ2000 + * Partners) agree not to assert against ISO/IEC and users of the JPEG + * 2000 Standard (Users) any of their rights under the copyright, not + * including other intellectual property rights, for this software module + * with respect to the usage by ISO/IEC and Users of this software module + * or modifications thereof for use in hardware or software products + * claiming conformance to the JPEG 2000 Standard. Those intending to use + * this software module in hardware or software products are advised that + * their use may infringe existing patents. The original developers of + * this software module, JJ2000 Partners and ISO/IEC assume no liability + * for use of this software module or modifications thereof. No license + * or right to this software module is granted for non JPEG 2000 Standard + * conforming products. JJ2000 Partners have full right to use this + * software module for his/her own purpose, assign or donate this + * software module to any third party and to inhibit third parties from + * using this software module for non JPEG 2000 Standard conforming + * products. This copyright notice must be included in all copies or + * derivative works of this software module. + * + * Copyright (c) 1999/2000 JJ2000 Partners. + */ + namespace CSJ2K.j2k.util { - - /// This class implements the MsgLogger interface for streams. Streams can - /// be simple files, terminals, stdout, stderr, etc. The messages or simple - /// strings are formatted using the linewidth given to the constructor. - /// - ///

Messages are printed to the 'err' stream if they are of severity WARNING - /// or ERROR, otherwise they are printed to the 'out' stream. Simple strings - /// are always printed the 'out' stream. - /// - ///

- public class StreamMsgLogger : MsgLogger - { - - /// The 'out' stream - private System.IO.StreamWriter out_Renamed; - - /// The 'err' stream - private System.IO.StreamWriter err; - - /// The printer that formats the text - private MsgPrinter mp; - - /// Constructs a StreamMsgLogger that uses 'outstr' as the 'out' stream, - /// and 'errstr' as the 'err' stream. Note that 'outstr' and 'errstr' can - /// be System.out and System.err. - /// - /// - /// Where to print simple strings and LOG and INFO messages. - /// - /// - /// Where to print WARNING and ERROR messages - /// - /// - /// The line width to use in formatting - /// - /// - /// - /// - public StreamMsgLogger(System.IO.Stream outstr, System.IO.Stream errstr, int lw) - { - System.IO.StreamWriter temp_writer; - temp_writer = new System.IO.StreamWriter(outstr, System.Text.Encoding.Default); - temp_writer.AutoFlush = true; - out_Renamed = temp_writer; - System.IO.StreamWriter temp_writer2; - temp_writer2 = new System.IO.StreamWriter(errstr, System.Text.Encoding.Default); - temp_writer2.AutoFlush = true; - err = temp_writer2; - mp = new MsgPrinter(lw); - } - - /// Constructs a StreamMsgLogger that uses 'outstr' as the 'out' stream, - /// and 'errstr' as the 'err' stream. Note that 'outstr' and 'errstr' can - /// be System.out and System.err. - /// - /// - /// Where to print simple strings and LOG and INFO messages. - /// - /// - /// Where to print WARNING and ERROR messages - /// - /// - /// The line width to use in formatting - /// - /// - /// - /// - //UPGRADE_ISSUE: Class hierarchy differences between 'java.io.Writer' and 'System.IO.StreamWriter' may cause compilation errors. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1186'" - public StreamMsgLogger(System.IO.StreamWriter outstr, System.IO.StreamWriter errstr, int lw) - { - System.IO.StreamWriter temp_writer; - temp_writer = new System.IO.StreamWriter(outstr.BaseStream, outstr.Encoding); - temp_writer.AutoFlush = true; - out_Renamed = temp_writer; - System.IO.StreamWriter temp_writer2; - temp_writer2 = new System.IO.StreamWriter(errstr.BaseStream, errstr.Encoding); - temp_writer2.AutoFlush = true; - err = temp_writer2; - mp = new MsgPrinter(lw); - } - - /// Constructs a StreamMsgLogger that uses 'outstr' as the 'out' stream, - /// and 'errstr' as the 'err' stream. Note that 'outstr' and 'errstr' can - /// be System.out and System.err. - /// - /// - /// Where to print simple strings and LOG and INFO messages. - /// - /// - /// Where to print WARNING and ERROR messages - /// - /// - /// The line width to use in formatting - /// - /// - /// - /// - /// - /* - public StreamMsgLogger(System.IO.StreamWriter outstr, System.IO.StreamWriter errstr, int lw) - { - out_Renamed = outstr; - err = errstr; - mp = new MsgPrinter(lw); - } - */ - /// Prints the message 'msg' to the output device, appending a newline, - /// with severity 'sev'. The severity of the message is prepended to the - /// message. - /// - /// - /// The message severity (LOG, INFO, etc.) - /// - /// - /// The message to display - /// - /// - /// - /// - public virtual void printmsg(int sev, System.String msg) - { - System.IO.StreamWriter lout; - //int ind; - System.String prefix; - - switch (sev) - { - - case CSJ2K.j2k.util.MsgLogger_Fields.LOG: - prefix = "[LOG]: "; - lout = out_Renamed; - break; - - case CSJ2K.j2k.util.MsgLogger_Fields.INFO: - prefix = "[INFO]: "; - lout = out_Renamed; - break; - - case CSJ2K.j2k.util.MsgLogger_Fields.WARNING: - prefix = "[WARNING]: "; - lout = err; - break; - - case CSJ2K.j2k.util.MsgLogger_Fields.ERROR: - prefix = "[ERROR]: "; - lout = err; - break; - - default: - throw new System.ArgumentException("Severity " + sev + " not valid."); - - } - - mp.print(lout, 0, prefix.Length, prefix + msg); - lout.Flush(); - } - - /// Prints the string 'str' to the 'out' stream, appending a newline. The - /// message is reformatted to the line width given to the constructors and - /// using 'flind' characters to indent the first line and 'ind' characters - /// to indent the second line. However, any newlines appearing in 'str' are - /// respected. The output device may or may not display the string until - /// flush() is called, depending on the autoflush state of the PrintWriter, - /// to be sure flush() should be called to write the string to the - /// device. This method just prints the string, the string does not make - /// part of a "message" in the sense that noe severity is associated to it. - /// - /// - /// The string to print - /// - /// - /// Indentation of the first line - /// - /// - /// Indentation of any other lines. - /// - /// - /// - /// - public virtual void println(System.String str, int flind, int ind) - { - mp.print(out_Renamed, flind, ind, str); - } - - /// Writes any buffered data from the print() and println() methods to the - /// device. - /// - /// - /// - /// - public virtual void flush() - { - out_Renamed.Flush(); - } - } -} \ No newline at end of file + using System.IO; + + /// This class implements the MsgLogger interface for streams. Streams can + /// be simple files, terminals, stdout, stderr, etc. The messages or simple + /// strings are formatted using the linewidth given to the constructor. + ///

Messages are printed to the 'err' stream if they are of severity WARNING + /// or ERROR, otherwise they are printed to the 'out' stream. Simple strings + /// are always printed the 'out' stream.

+ ///
+ public abstract class StreamMsgLogger : IMsgLogger + { + /// The 'out' stream + private StreamWriter out_Renamed; + + /// The 'err' stream + private readonly StreamWriter err; + + /// The printer that formats the text + private readonly MsgPrinter mp; + + /// Constructs a StreamMsgLogger that uses 'outstr' as the 'out' stream, + /// and 'errstr' as the 'err' stream. Note that 'outstr' and 'errstr' can + /// be System.out and System.err. + /// + /// Where to print simple strings and LOG and INFO messages. + /// + /// Where to print WARNING and ERROR messages + /// + /// The line width to use in formatting + /// + protected StreamMsgLogger(Stream outstr, Stream errstr, int lw) + { + var temp_writer = new StreamWriter(outstr, System.Text.Encoding.UTF8); + temp_writer.AutoFlush = true; + out_Renamed = temp_writer; + var temp_writer2 = new StreamWriter(errstr, System.Text.Encoding.UTF8); + temp_writer2.AutoFlush = true; + err = temp_writer2; + mp = new MsgPrinter(lw); + } + + /// Constructs a StreamMsgLogger that uses 'outstr' as the 'out' stream, + /// and 'errstr' as the 'err' stream. Note that 'outstr' and 'errstr' can + /// be System.out and System.err. + /// + /// Where to print simple strings and LOG and INFO messages. + /// + /// Where to print WARNING and ERROR messages + /// + /// The line width to use in formatting + /// + protected StreamMsgLogger(StreamWriter outstr, StreamWriter errstr, int lw) + { + var temp_writer = new StreamWriter(outstr.BaseStream, outstr.Encoding); + temp_writer.AutoFlush = true; + out_Renamed = temp_writer; + var temp_writer2 = new StreamWriter(errstr.BaseStream, errstr.Encoding); + temp_writer2.AutoFlush = true; + err = temp_writer2; + mp = new MsgPrinter(lw); + } + + /// Prints the message 'msg' to the output device, appending a newline, + /// with severity 'sev'. The severity of the message is prepended to the + /// message. + /// + /// The message severity (LOG, INFO, etc.) + /// + /// The message to display + /// + public virtual void printmsg(int sev, string msg) + { + StreamWriter lout; + string prefix; + + switch (sev) + { + + case MsgLogger_Fields.LOG: + prefix = "[LOG]: "; + lout = out_Renamed; + break; + + case MsgLogger_Fields.INFO: + prefix = "[INFO]: "; + lout = out_Renamed; + break; + + case MsgLogger_Fields.WARNING: + prefix = "[WARNING]: "; + lout = err; + break; + + case MsgLogger_Fields.ERROR: + prefix = "[ERROR]: "; + lout = err; + break; + + default: + throw new System.ArgumentException("Severity " + sev + " not valid."); + + } + + mp.print(lout, 0, prefix.Length, prefix + msg); + lout.Flush(); + } + + /// Prints the string 'str' to the 'out' stream, appending a newline. The + /// message is reformatted to the line width given to the constructors and + /// using 'flind' characters to indent the first line and 'ind' characters + /// to indent the second line. However, any newlines appearing in 'str' are + /// respected. The output device may or may not display the string until + /// flush() is called, depending on the autoflush state of the PrintWriter, + /// to be sure flush() should be called to write the string to the + /// device. This method just prints the string, the string does not make + /// part of a "message" in the sense that noe severity is associated to it. + /// + /// The string to print + /// + /// Indentation of the first line + /// + /// Indentation of any other lines. + /// + public virtual void println(string str, int flind, int ind) + { + mp.print(out_Renamed, flind, ind, str); + } + + /// Writes any buffered data from the print() and println() methods to the + /// device. + /// + public virtual void flush() + { + out_Renamed.Flush(); + } + } +} diff --git a/CSJ2K/j2k/util/StringFormatException.cs b/CSJ2K/j2k/util/StringFormatException.cs index de7fb6e1..4890557d 100644 --- a/CSJ2K/j2k/util/StringFormatException.cs +++ b/CSJ2K/j2k/util/StringFormatException.cs @@ -52,7 +52,6 @@ namespace CSJ2K.j2k.util /// badly formatted string. /// ///
- [Serializable] public class StringFormatException:System.ArgumentException { diff --git a/CSJ2K/j2k/util/ThreadPool.cs b/CSJ2K/j2k/util/ThreadPool.cs deleted file mode 100644 index 3033c76e..00000000 --- a/CSJ2K/j2k/util/ThreadPool.cs +++ /dev/null @@ -1,648 +0,0 @@ -/* -* CVS identifier: -* -* $Id: ThreadPool.java,v 1.9 2002/05/22 15:00:55 grosbois Exp $ -* -* Class: ThreadPool -* -* Description: A pool of threads -* -* -* -* COPYRIGHT: -* -* This software module was originally developed by Raphaël Grosbois and -* Diego Santa Cruz (Swiss Federal Institute of Technology-EPFL); Joel -* Askelöf (Ericsson Radio Systems AB); and Bertrand Berthelot, David -* Bouchard, Félix Henry, Gerard Mozelle and Patrice Onno (Canon Research -* Centre France S.A) in the course of development of the JPEG2000 -* standard as specified by ISO/IEC 15444 (JPEG 2000 Standard). This -* software module is an implementation of a part of the JPEG 2000 -* Standard. Swiss Federal Institute of Technology-EPFL, Ericsson Radio -* Systems AB and Canon Research Centre France S.A (collectively JJ2000 -* Partners) agree not to assert against ISO/IEC and users of the JPEG -* 2000 Standard (Users) any of their rights under the copyright, not -* including other intellectual property rights, for this software module -* with respect to the usage by ISO/IEC and Users of this software module -* or modifications thereof for use in hardware or software products -* claiming conformance to the JPEG 2000 Standard. Those intending to use -* this software module in hardware or software products are advised that -* their use may infringe existing patents. The original developers of -* this software module, JJ2000 Partners and ISO/IEC assume no liability -* for use of this software module or modifications thereof. No license -* or right to this software module is granted for non JPEG 2000 Standard -* conforming products. JJ2000 Partners have full right to use this -* software module for his/her own purpose, assign or donate this -* software module to any third party and to inhibit third parties from -* using this software module for non JPEG 2000 Standard conforming -* products. This copyright notice must be included in all copies or -* derivative works of this software module. -* -* Copyright (c) 1999/2000 JJ2000 Partners. -* */ -using System; -namespace CSJ2K.j2k.util -{ - - /// This class implements a thread pool. The thread pool contains a set of - /// threads which can be given work to do. - /// - ///

If the Java Virtual Machine (JVM) uses native threads, then the - /// different threads will be able to execute in different processors in - /// parallel on multiprocessors machines. However, under some JVMs and - /// operating systems using native threads is not sufficient to allow the JVM - /// access to multiple processors. This is the case when native threads are - /// implemented using POSIX threads on lightweight processes - /// (i.e. PTHREAD_SCOPE_PROCESS sopce scheduling), which is the case on most - /// UNIX operating systems. In order to do provide access to multiple - /// processors it is necessary to set the concurrency level to the number of - /// processors or slightly higher. This can be achieved by setting the Java - /// system property with the name defined by CONCURRENCY_PROP_NAME to some - /// non-negative number. This will make use of the 'NativeServices' class and - /// supporting native libraries. See 'NativeServices' for details. See - /// 'CONCURRENCY_PROP_NAME' for the name of the property. - /// - ///

Initially the thread pool contains a user specified number of idle - /// threads. Idle threads can be given a target which is run. While running the - /// target the thread temporarily leaves the idle list. When the target - /// finishes, it joins the idle list again, waiting for a new target. When a - /// target is finished a thread can be notified on a particular object that is - /// given as a lock. - /// - ///

Jobs can be submitted using Runnable interfaces, using the 'runTarget()' - /// methods. When the job is submitted, an idle thread will be obtained, the - /// 'run()' method of the 'Runnable' interface will be executed and when it - /// completes the thread will be returned to the idle list. In general the - /// 'run()' method should complete in a rather short time, so that the threds - /// of the pool are not starved. - /// - ///

If using the non-asynchronous calls to 'runTarget()', it is important - /// that any target's 'run()' method, or any method called from it, does not - /// use non-asynchronous calls to 'runTarget()' on the same thread pool where - /// it was started. Otherwise this could create a dead-lock when there are not - /// enough idle threads. - /// - ///

The pool also has a global error and runtime exception condition (one - /// for 'Error' and one for 'RuntimeException'). If a target's 'run()' method - /// throws an 'Error' or 'RuntimeException' the corresponding exception - /// condition is set and the exception object saved. In any subsequent call to - /// 'checkTargetErrors()' the saved exception object is thrown. Likewise, if a - /// target's 'run()' method throws any other subclass of 'Throwable' a new - /// 'RuntimeException' is created and saved. It will be thrown on a subsequent - /// call to 'checkTargetErrors()'. If more than one exception occurs between - /// calls to 'checkTargetErrors()' only the last one is saved. Any 'Error' - /// condition has precedence on all 'RuntimeException' conditions. The threads - /// in the pool are unaffected by any exceptions thrown by targets. - /// - ///

The only exception to the above is the 'ThreadDeath' exception. If a - /// target's 'run()' method throws the 'ThreadDeath' exception a warning - /// message is printed and the exception is propagated, which will terminate - /// the thread in which it occurs. This could lead to instabilities of the - /// pool. The 'ThreadDeath' exception should never be thrown by the program. It - /// is thrown by the Java(TM) Virtual Machine when Thread.stop() is - /// called. This method is deprecated and should never be called. - /// - ///

All the threads in the pool are "daemon" threads and will automatically - /// terminate when no daemon threads are running. - /// - ///

- /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - public class ThreadPool - { - /// Returns the size of the pool. That is the number of threads in this - /// pool (idle + busy). - /// - /// - /// The pool's size. - /// - /// - /// - virtual public int Size - { - get - { - return idle.Length; - } - - } - - /// The name of the property that sets the concurrency level: - /// jj2000.j2k.util.ThreadPool.concurrency - /// - public const System.String CONCURRENCY_PROP_NAME = "jj2000.j2k.util.ThreadPool.concurrency"; - - /// The array of idle threads and the lock for the manipulation of the - /// idle thread list. - /// - private ThreadPoolThread[] idle; - - /// The number of idle threads - private int nidle; - - /// The name of the pool - private System.String poolName; - - /// The priority for the pool - private int poolPriority; - - /// The last error thrown by a target. Null if none - // NOTE: needs to be volatile, so that only one copy exits in memory - private volatile System.ApplicationException targetE; - - /// The last runtime exception thrown by a target. Null if none - // NOTE: needs to be volatile, so that only one copy exits in memory - private volatile System.SystemException targetRE; - - //UPGRADE_NOTE: Field 'EnclosingInstance' was added to class 'ThreadPoolThread' to access its enclosing instance. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1019'" - /// The threads that are managed by the pool. - /// - /// - internal class ThreadPoolThread:SupportClass.ThreadClass - { - private void InitBlock(ThreadPool enclosingInstance) - { - this.enclosingInstance = enclosingInstance; - } - private ThreadPool enclosingInstance; - public ThreadPool Enclosing_Instance - { - get - { - return enclosingInstance; - } - - } - private IThreadRunnable target; - private System.Object lock_Renamed; - private bool doNotifyAll; - - /// Creates a ThreadPoolThread object, setting its name according to - /// the given 'idx', daemon type and the priority to the one of the - /// pool. - /// - /// - /// The index of this thread in the pool - /// - /// - /// The name of the thread - /// - /// - public ThreadPoolThread(ThreadPool enclosingInstance, int idx, System.String name):base(name) - { - InitBlock(enclosingInstance); - IsBackground = true; - //UPGRADE_TODO: The differences in the type of parameters for method 'java.lang.Thread.setPriority' may cause compilation errors. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1092'" - Priority = (System.Threading.ThreadPriority) Enclosing_Instance.poolPriority; - } - - /// The method that is run by the thread. This method first joins the - /// idle state in the pool and then enters an infinite loop. In this - /// loop it waits until a target to run exists and runs it. Once the - /// target's run() method is done it re-joins the idle state and - /// notifies the waiting lock object, if one exists. - /// - ///

An interrupt on this thread has no effect other than forcing a - /// check on the target. Normally the target is checked every time the - /// thread is woken up by notify, no interrupts should be done. - /// - ///

Any exception thrown by the target's 'run()' method is catched - /// and this thread is not affected, except for 'ThreadDeath'. If a - /// 'ThreadDeath' exception is catched a warning message is printed by - /// the 'FacilityManager' and the exception is propagated up. For - /// exceptions which are subclasses of 'Error' or 'RuntimeException' - /// the corresponding error condition is set and this thread is not - /// affected. For any other exceptions a new 'RuntimeException' is - /// created and the error condition is set, this thread is not affected. - /// - ///

- override public void Run() - { - // Join the idle threads list - Enclosing_Instance.putInIdleList(this); - // Permanently lock the object while running so that target can - // not be changed until we are waiting again. While waiting for a - // target the lock is released. - lock (this) - { - while (true) - { - // Wait until we get a target - while (target == null) - { - try - { - System.Threading.Monitor.Wait(this); - } - catch (System.Threading.ThreadInterruptedException) - { - } - } - // Run the target and catch all possible errors - try - { - target.Run(); - } - //UPGRADE_NOTE: Exception 'java.lang.ThreadDeath' was converted to 'System.ApplicationException' which has different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1100'" - catch (System.Threading.ThreadAbortException td) - { - // We have been instructed to abruptly terminate - // the thread, which should never be done. This can - // cause another thread, or the system, to lock. - FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.WARNING, "Thread.stop() called on a ThreadPool " + "thread or ThreadDeath thrown. This is " + "deprecated. Lock-up might occur."); - throw td; - } - catch (System.ApplicationException e) - { - Enclosing_Instance.targetE = e; - } - catch (System.SystemException re) - { - Enclosing_Instance.targetRE = re; - } - //UPGRADE_NOTE: Exception 'java.lang.Throwable' was converted to 'System.Exception' which has different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1100'" - catch (System.Exception) - { - // A totally unexpected error has occurred - // (Thread.stop(Throwable) has been used, which should - // never be. - Enclosing_Instance.targetRE = new System.SystemException("Unchecked exception " + "thrown by target's " + "run() method in pool " + Enclosing_Instance.poolName + "."); - } - // Join idle threads - Enclosing_Instance.putInIdleList(this); - // Release the target and notify lock (i.e. wakeup) - target = null; - if (lock_Renamed != null) - { - lock (lock_Renamed) - { - if (doNotifyAll) - { - System.Threading.Monitor.PulseAll(lock_Renamed); - } - else - { - System.Threading.Monitor.Pulse(lock_Renamed); - } - } - } - } - } - } - - /// Assigns a target to this thread, with an optional notify lock and a - /// notify mode. The another target is currently running the method - /// will block until it terminates. After setting the new target the - /// runner thread will be wakenup and execytion will start. - /// - /// - /// The runnable object containing the 'run()' method to - /// run. - /// - /// - /// An object on which notify will be called once the - /// target's run method has finished. A thread to be notified should be - /// waiting on that object. If null no thread is notified. - /// - /// - /// If true 'notifyAll()', instead of 'notify()', will - /// be called on tghe lock. - /// - /// - //UPGRADE_NOTE: Synchronized keyword was removed from method 'setTarget'. Lock expression was added. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1027'" - internal virtual void setTarget(IThreadRunnable target, System.Object lock_Renamed, bool notifyAll) - { - lock (this) - { - // Set the target - this.target = target; - this.lock_Renamed = lock_Renamed; - doNotifyAll = notifyAll; - // Wakeup the thread - System.Threading.Monitor.Pulse(this); - } - } - } - - /// Creates a new thread pool of the given size, thread priority and pool - /// name. - /// - ///

If the Java system property of the name defined by - /// 'CONCURRENCY_PROP_NAME' is set, then an attempt will be made to load - /// the library that supports concurrency setting (see - /// 'NativeServices'). If that succeds the concurrency level will be set to - /// the specified value. Otherwise a warning is printed. - /// - ///

- /// The size of the pool (number of threads to create in the - /// pool). - /// - /// - /// The priority to give to the threads in the pool. If - /// less than 'Thread.MIN_PRIORITY' it will be the same as the priority of - /// the calling thread. - /// - /// - /// The name of the pool. If null a default generic name is - /// chosen. - /// - /// - /// - /// - /// - /// - /// - /// - public ThreadPool(int size, int priority, System.String name) - { - int i; - ThreadPoolThread t; - //System.String prop; - //int clevel; - - // Initialize variables checking for special cases - if (size <= 0) - { - throw new System.ArgumentException("Pool must be of positive size"); - } - if (priority < (int) System.Threading.ThreadPriority.Lowest) - { - poolPriority = (System.Int32) SupportClass.ThreadClass.Current().Priority; - } - else - { - poolPriority = (priority < (int) System.Threading.ThreadPriority.Highest)?priority:(int) System.Threading.ThreadPriority.Highest; - } - if (name == null) - { - poolName = "Anonymous ThreadPool"; - } - else - { - poolName = name; - } - - // Allocate internal variables - idle = new ThreadPoolThread[size]; - nidle = 0; - - // Create and start the threads - for (i = 0; i < size; i++) - { - t = new ThreadPoolThread(this, i, poolName + "-" + i); - t.Start(); - } - } - - /// Runs the run method of the specified target in an idle thread of this - /// pool. When the target's run method completes, the thread waiting on the - /// lock object is notified, if any. If there is currently no idle thread - /// the method will block until a thread of the pool becomes idle or the - /// calling thread is interrupted. - /// - ///

This method is the same as runTarget(t,l,true,false). - /// - ///

- /// The target. The 'run()' method of this object will be run in - /// an idle thread of the pool. - /// - /// - /// The lock object. A thread waiting on the lock of the 'l' - /// object will be notified, through the 'notify()' call, when the target's - /// run method completes. If null no thread is notified. - /// - /// - /// True if the target was submitted to some thread. False if no - /// idle thread could be found and the target was not submitted for - /// execution. - /// - /// - /// - public virtual bool runTarget(IThreadRunnable t, System.Object l) - { - return runTarget(t, l, false, false); - } - - /// Runs the run method of the specified target in an idle thread of this - /// pool. When the target's run method completes, the thread waiting on the - /// lock object is notified, if any. If there is currently no idle thread - /// and the asynchronous mode is not used the method will block until a - /// thread of the pool becomes idle or the calling thread is - /// interrupted. If the asynchronous mode is used then the method will not - /// block and will return false. - /// - ///

This method is the same as runTarget(t,l,async,false). - /// - ///

- /// The target. The 'run()' method of this object will be run in - /// an idle thread of the pool. - /// - /// - /// The lock object. A thread waiting on the lock of the 'l' - /// object will be notified, through the 'notify()' call, when the target's - /// run method completes. If null no thread is notified. - /// - /// - /// If true the asynchronous mode will be used. - /// - /// - /// True if the target was submitted to some thread. False if no - /// idle thread could be found and the target was not submitted for - /// execution. - /// - /// - /// - public virtual bool runTarget(IThreadRunnable t, System.Object l, bool async) - { - return runTarget(t, l, async, false); - } - - /// Runs the run method of the specified target in an idle thread of this - /// pool. When the target's run method completes, the thread waiting on the - /// lock object is notified, if any. If there is currently no idle thread - /// and the asynchronous mode is not used the method will block until a - /// thread of the pool becomes idle or the calling thread is - /// interrupted. If the asynchronous mode is used then the method will not - /// block and will return false. - /// - /// - /// The target. The 'run()' method of this object will be run in - /// an idle thread of the pool. - /// - /// - /// The lock object. A thread waiting on the lock of the 'l' - /// object will be notified, through the 'notify()' call, when the target's - /// run method completes. If null no thread is notified. - /// - /// - /// If true the asynchronous mode will be used. - /// - /// - /// If true, threads waiting on the lock of the 'l' object - /// will be notified trough the 'notifyAll()' instead of the normal - /// 'notify()' call. This is not normally needed. - /// - /// - /// True if the target was submitted to some thread. False if no - /// idle thread could be found and the target was not submitted for - /// execution. - /// - /// - /// - public virtual bool runTarget(IThreadRunnable t, System.Object l, bool async, bool notifyAll) - { - ThreadPoolThread runner; // The thread to run the target - - // Get a thread to run - runner = getIdle(async); - // If no runner return failure - if (runner == null) - return false; - // Set the runner - runner.setTarget(t, l, notifyAll); - return true; - } - - /// Checks that no error or runtime exception in any target have occurred - /// so far. If an error or runtime exception has occurred in a target's run - /// method they are thrown by this method. - /// - /// - /// If an error condition has been thrown by a target - /// 'run()' method. - /// - /// - /// If a runtime exception has been thrown by a - /// target 'run()' method. - /// - /// - public virtual void checkTargetErrors() - { - // Check for Error - if (targetE != null) - throw targetE; - // Check for RuntimeException - if (targetRE != null) - throw targetRE; - } - - /// Clears the current target error conditions, if any. Note that a thread - /// in the pool might have set the error conditions since the last check - /// and that those error conditions will be lost. Likewise, before - /// returning from this method another thread might set the error - /// conditions. There is no guarantee that no error conditions exist when - /// returning from this method. - /// - ///

In order to ensure that no error conditions exist when returning - /// from this method cooperation from the targets and the thread using this - /// pool is necessary (i.e. currently no targets running or waiting to - /// run). - /// - ///

- public virtual void clearTargetErrors() - { - // Clear the error and runtime exception conditions - targetE = null; - targetRE = null; - } - - /// Puts the thread 't' in the idle list. The thread 't' should be in fact - /// idle and ready to accept a new target when it joins the idle list. - /// - ///

An idle thread that is already in the list should never add itself - /// to the list before it is removed. For efficiency reasons there is no - /// check to see if the thread is already in the list of idle threads. - /// - ///

If the idle list was empty 'notify()' will be called on the 'idle' - /// array, to wake up a thread that might be waiting (within the - /// 'getIdle()' method) on an idle thread to become available. - /// - ///

- /// The thread to put in the idle list. - /// - /// - private void putInIdleList(ThreadPoolThread t) - { - // NOTE: if already in idle => catastrophe! (should be OK since // - // this is private method) - // Lock the idle array to avoid races with 'getIdle()' - lock (idle) - { - idle[nidle] = t; - nidle++; - // If idle array was empty wakeup any waiting threads. - if (nidle == 1) - System.Threading.Monitor.Pulse(idle); - } - } - - /// Returns and idle thread and removes it from the list of idle - /// threads. In asynchronous mode it will immediately return an idle - /// thread, or null if none is available. In non-asynchronous mode it will - /// block until a thread of the pool becomes idle or the calling thread is - /// interrupted. - /// - ///

If in non-asynchronous mode and there are currently no idle threads - /// available the calling thread will wait on the 'idle' array lock, until - /// notified by 'putInIdleList()' that an idle thread might have become - /// available. - /// - ///

- /// If true asynchronous mode is used. - /// - /// - /// An idle thread of the pool, that has been removed from the idle - /// list, or null if none is available. - /// - /// - private ThreadPoolThread getIdle(bool async) - { - // Lock the idle array to avoid races with 'putInIdleList()' - lock (idle) - { - if (async) - { - // In asynchronous mode just return null if no idle thread - if (nidle == 0) - return null; - } - else - { - // In synchronous mode wait until a thread becomes idle - while (nidle == 0) - { - try - { - System.Threading.Monitor.Wait(idle); - } - catch (System.Threading.ThreadInterruptedException) - { - // If we were interrupted just return null - return null; - } - } - } - // Decrease the idle count and return one of the idle threads - nidle--; - return idle[nidle]; - } - } - } -} \ No newline at end of file diff --git a/CSJ2K/j2k/wavelet/Subband.cs b/CSJ2K/j2k/wavelet/Subband.cs index df90fb93..34998d51 100644 --- a/CSJ2K/j2k/wavelet/Subband.cs +++ b/CSJ2K/j2k/wavelet/Subband.cs @@ -503,7 +503,7 @@ public virtual Subband nextSubband() break; default: - throw new System.ApplicationException("You have found a bug in JJ2000"); + throw new System.InvalidOperationException("You have found a bug in JJ2000"); } while (sb.isNode) @@ -513,7 +513,7 @@ public virtual Subband nextSubband() return sb; default: - throw new System.ApplicationException("You have found a bug in JJ2000"); + throw new System.InvalidOperationException("You have found a bug in JJ2000"); } } diff --git a/CSJ2K/j2k/wavelet/WTDecompSpec.cs b/CSJ2K/j2k/wavelet/WTDecompSpec.cs index 4320c4c5..2ec56e4c 100644 --- a/CSJ2K/j2k/wavelet/WTDecompSpec.cs +++ b/CSJ2K/j2k/wavelet/WTDecompSpec.cs @@ -266,14 +266,14 @@ public virtual int getDecompType(int n) case DEC_SPEC_COMP_DEF: return compMainDefDecompType[n]; - case DEC_SPEC_TILE_DEF: - throw new NotImplementedException(); + case DEC_SPEC_TILE_DEF: + throw new NotImplementedException(); - case DEC_SPEC_TILE_COMP: - throw new NotImplementedException(); + case DEC_SPEC_TILE_COMP: + throw new NotImplementedException(); default: - throw new System.ApplicationException("Internal JJ2000 error"); + throw new System.InvalidOperationException("Internal JJ2000 error"); } } @@ -306,14 +306,14 @@ public virtual int getLevels(int n) case DEC_SPEC_COMP_DEF: return compMainDefLevels[n]; - case DEC_SPEC_TILE_DEF: - throw new NotImplementedException(); + case DEC_SPEC_TILE_DEF: + throw new NotImplementedException(); - case DEC_SPEC_TILE_COMP: - throw new NotImplementedException(); + case DEC_SPEC_TILE_COMP: + throw new NotImplementedException(); default: - throw new System.ApplicationException("Internal JJ2000 error"); + throw new System.InvalidOperationException("Internal JJ2000 error"); } } diff --git a/CSJ2K/j2k/wavelet/analysis/ForwWTFull.cs b/CSJ2K/j2k/wavelet/analysis/ForwWTFull.cs index fb8a05b2..a13b35b9 100644 --- a/CSJ2K/j2k/wavelet/analysis/ForwWTFull.cs +++ b/CSJ2K/j2k/wavelet/analysis/ForwWTFull.cs @@ -507,7 +507,7 @@ public override CBlkWTData getNextInternCodeBlock(int c, CBlkWTData cblk) break; default: - throw new System.ApplicationException("Internal JJ2000 error"); + throw new System.InvalidOperationException("Internal JJ2000 error"); } @@ -1195,7 +1195,7 @@ private void initSubbandsFields(int t, int c, Subband sb) break; default: - throw new System.ApplicationException("Internal JJ2000 error"); + throw new System.InvalidOperationException("Internal JJ2000 error"); } if (sb.ulcx - acb0x < 0 || sb.ulcy - acb0y < 0) diff --git a/CSJ2K/j2k/wavelet/analysis/ForwardWT.cs b/CSJ2K/j2k/wavelet/analysis/ForwardWT.cs index 1335eb15..67e5ec5d 100644 --- a/CSJ2K/j2k/wavelet/analysis/ForwardWT.cs +++ b/CSJ2K/j2k/wavelet/analysis/ForwardWT.cs @@ -157,7 +157,7 @@ public static ForwardWT createInstance(BlkImgDataSrc src, ParameterList pl, Enco System.String str = ""; if (pl.getParameter("Wcboff") == null) { - throw new System.ApplicationException("You must specify an argument to the '-Wcboff' " + "option. See usage with the '-u' option"); + throw new System.InvalidOperationException("You must specify an argument to the '-Wcboff' " + "option. See usage with the '-u' option"); } SupportClass.Tokenizer stk = new SupportClass.Tokenizer(pl.getParameter("Wcboff")); if (stk.Count != 2) @@ -170,7 +170,7 @@ public static ForwardWT createInstance(BlkImgDataSrc src, ParameterList pl, Enco { cb0x = (System.Int32.Parse(str)); } - catch (System.FormatException) + catch (System.FormatException e) { throw new System.ArgumentException("Bad first parameter for the " + "'-Wcboff' option: " + str); } @@ -184,7 +184,7 @@ public static ForwardWT createInstance(BlkImgDataSrc src, ParameterList pl, Enco { cb0y = (System.Int32.Parse(str)); } - catch (System.FormatException) + catch (System.FormatException e) { throw new System.ArgumentException("Bad second parameter for the " + "'-Wcboff' option: " + str); } diff --git a/CSJ2K/j2k/wavelet/analysis/SubbandAn.cs b/CSJ2K/j2k/wavelet/analysis/SubbandAn.cs index e0a68fa9..0392f79f 100644 --- a/CSJ2K/j2k/wavelet/analysis/SubbandAn.cs +++ b/CSJ2K/j2k/wavelet/analysis/SubbandAn.cs @@ -386,7 +386,7 @@ private void calcBasisWaveForms(float[][] wfs) { // There is an error! If all childs have non-negative // l2norm, then this node should have non-negative l2norm - throw new System.ApplicationException("You have found a bug in JJ2000!"); + throw new System.InvalidOperationException("You have found a bug in JJ2000!"); } } else @@ -403,7 +403,7 @@ private void calcBasisWaveForms(float[][] wfs) { // This is an error! The calcBasisWaveForms() method is never // called on an element with non-negative l2norm - throw new System.ApplicationException("You have found a bug in JJ2000!"); + throw new System.InvalidOperationException("You have found a bug in JJ2000!"); } } @@ -453,7 +453,7 @@ private void assignL2Norm(float l2n) { // There is an error! If all childs have non-negative // l2norm, then this node should have non-negative l2norm - throw new System.ApplicationException("You have found a bug in JJ2000!"); + throw new System.InvalidOperationException("You have found a bug in JJ2000!"); } } else @@ -466,7 +466,7 @@ private void assignL2Norm(float l2n) { // This is an error! The assignL2Norm() method is never called on // an element with non-negative l2norm - throw new System.ApplicationException("You have found a bug in JJ2000!"); + throw new System.InvalidOperationException("You have found a bug in JJ2000!"); } } diff --git a/CSJ2K/j2k/wavelet/synthesis/InvWTFull.cs b/CSJ2K/j2k/wavelet/synthesis/InvWTFull.cs index 0e3ba9c3..109780e3 100644 --- a/CSJ2K/j2k/wavelet/synthesis/InvWTFull.cs +++ b/CSJ2K/j2k/wavelet/synthesis/InvWTFull.cs @@ -81,15 +81,9 @@ namespace CSJ2K.j2k.wavelet.synthesis public class InvWTFull:InverseWT { - /// Reference to the ProgressWatch instance if any - private ProgressWatch pw = null; - /// The total number of code-blocks to decode private int cblkToDecode = 0; - /// The number of already decoded code-blocks - private int nDecCblk = 0; - /// the code-block buffer's source i.e. the quantizer private CBlkWTDataSrcDec src; @@ -128,7 +122,6 @@ public InvWTFull(CBlkWTDataSrcDec src, DecoderSpecs decSpec):base(src, decSpec) int nc = src.NumComps; reconstructedComps = new DataBlk[nc]; ndl = new int[nc]; - pw = FacilityManager.ProgressWatch; } /// Returns the reversibility of the current subband. It computes @@ -298,10 +291,6 @@ public override DataBlk getInternCompData(DataBlk blk, int c) } //Reconstruct source image waveletTreeReconstruction(reconstructedComps[c], src.getSynSubbandTree(tIdx, c), c); - if (pw != null && c == src.NumComps - 1) - { - pw.terminateProgressWatch(); - } } if (blk.DataType != dtype) @@ -585,11 +574,7 @@ private void waveletTreeReconstruction(DataBlk img, SubbandSyn sb, int c) { subbData = src.getInternCodeBlock(c, m, n, sb, subbData); src_data = subbData.Data; - if (pw != null) - { - nDecCblk++; - pw.updateProgressWatch(nDecCblk, null); - } + // Copy the data line by line for (i = subbData.h - 1; i >= 0; i--) { @@ -699,12 +684,6 @@ public override void setTile(int x, int y) } } // Loop on resolution levels } // Loop on components - nDecCblk = 0; - - if (pw != null) - { - pw.initProgressWatch(0, cblkToDecode, "Decoding tile " + tIdx + "..."); - } } /// Advances to the next tile, in standard scan-line order (by rows then diff --git a/CSJ2K/j2k/wavelet/synthesis/InverseWT.cs b/CSJ2K/j2k/wavelet/synthesis/InverseWT.cs index d8ffdb22..c4a0c6ac 100644 --- a/CSJ2K/j2k/wavelet/synthesis/InverseWT.cs +++ b/CSJ2K/j2k/wavelet/synthesis/InverseWT.cs @@ -48,72 +48,103 @@ using CSJ2K.j2k.image; using CSJ2K.j2k.util; using CSJ2K.j2k; + namespace CSJ2K.j2k.wavelet.synthesis { - - /// This abstract class extends the WaveletTransform one with the specifics of - /// inverse wavelet transforms. - /// - ///

The image can be reconstructed at different resolution levels. This is - /// controlled by the setResLevel() method. All the image, tile and component - /// dimensions are relative the the resolution level being used. The number of - /// resolution levels indicates the number of wavelet recompositions that will - /// be used, if it is equal as the number of decomposition levels then the full - /// resolution image is reconstructed.

- /// - ///

It is assumed in this class that all tiles and components the same - /// reconstruction resolution level. If that where not the case the - /// implementing class should have additional data structures to store those - /// values for each tile. However, the 'recResLvl' member variable always - /// contain the values applicable to the current tile, since many methods - /// implemented here rely on them.

- /// - ///
- public abstract class InverseWT:InvWTAdapter, BlkImgDataSrc - { - - /// Initializes this object with the given source of wavelet - /// coefficients. It initializes the resolution level for full resolutioin - /// reconstruction (i.e. the maximum resolution available from the 'src' - /// source). - /// - ///

It is assumed here that all tiles and components have the same - /// reconstruction resolution level. If that was not the case it should be - /// the value for the current tile of the source.

- /// - ///
- /// from where the wavelet coefficinets should be obtained. - /// - /// - /// The decoder specifications - /// - /// - public InverseWT(MultiResImgData src, DecoderSpecs decSpec):base(src, decSpec) - { - } - - /// Creates an InverseWT object that works on the data type of the source, - /// with the special additional parameters from the parameter - /// list. Currently the parameter list is ignored since no special - /// parameters can be specified for the inverse wavelet transform yet. - /// - /// - /// The source of data for the inverse wavelet - /// transform. - /// - /// - /// The parameter list containing parameters applicable to the - /// inverse wavelet transform (other parameters can also be present). - /// - /// - public static InverseWT createInstance(CBlkWTDataSrcDec src, DecoderSpecs decSpec) - { - - // full page wavelet transform - return new InvWTFull(src, decSpec); - } - public abstract int getFixedPoint(int param1); - public abstract CSJ2K.j2k.image.DataBlk getInternCompData(CSJ2K.j2k.image.DataBlk param1, int param2); - public abstract CSJ2K.j2k.image.DataBlk getCompData(CSJ2K.j2k.image.DataBlk param1, int param2); - } -} \ No newline at end of file + + /// This abstract class extends the WaveletTransform one with the specifics of + /// inverse wavelet transforms. + /// + ///

The image can be reconstructed at different resolution levels. This is + /// controlled by the setResLevel() method. All the image, tile and component + /// dimensions are relative the the resolution level being used. The number of + /// resolution levels indicates the number of wavelet recompositions that will + /// be used, if it is equal as the number of decomposition levels then the full + /// resolution image is reconstructed.

+ /// + ///

It is assumed in this class that all tiles and components the same + /// reconstruction resolution level. If that where not the case the + /// implementing class should have additional data structures to store those + /// values for each tile. However, the 'recResLvl' member variable always + /// contain the values applicable to the current tile, since many methods + /// implemented here rely on them.

+ /// + ///
+ public abstract class InverseWT : InvWTAdapter, BlkImgDataSrc + { + + /// Initializes this object with the given source of wavelet + /// coefficients. It initializes the resolution level for full resolutioin + /// reconstruction (i.e. the maximum resolution available from the 'src' + /// source). + /// + ///

It is assumed here that all tiles and components have the same + /// reconstruction resolution level. If that was not the case it should be + /// the value for the current tile of the source.

+ /// + ///
+ /// from where the wavelet coefficinets should be obtained. + /// + /// + /// The decoder specifications + /// + /// + public InverseWT(MultiResImgData src, DecoderSpecs decSpec) + : base(src, decSpec) + { + } + + /// Creates an InverseWT object that works on the data type of the source, + /// with the special additional parameters from the parameter + /// list. Currently the parameter list is ignored since no special + /// parameters can be specified for the inverse wavelet transform yet. + /// + /// + /// The source of data for the inverse wavelet + /// transform. + /// + /// + /// The parameter list containing parameters applicable to the + /// inverse wavelet transform (other parameters can also be present). + /// + /// + public static InverseWT createInstance(CBlkWTDataSrcDec src, DecoderSpecs decSpec) + { + + // full page wavelet transform + return new InvWTFull(src, decSpec); + } + + public abstract int getFixedPoint(int c); + + public abstract DataBlk getInternCompData(DataBlk blk, int c); + + public abstract DataBlk getCompData(DataBlk blk, int c); + + /// Closes the underlying file or network connection from where the + /// image data is being read. + /// + /// + /// If an I/O error occurs. + /// + public void close() + { + // Do nothing. + } + + /// Returns true if the data read was originally signed in the specified + /// component, false if not. + /// + /// + /// The index of the component, from 0 to C-1. + /// + /// + /// true if the data was originally signed, false if not. + /// + /// + public bool isOrigSigned(int c) + { + return false; + } + } +} diff --git a/prebuildCoreLib.xml b/prebuildCoreLib.xml index 91b062e5..a19b67f3 100755 --- a/prebuildCoreLib.xml +++ b/prebuildCoreLib.xml @@ -79,6 +79,7 @@ ../bin/ + From fb69fea20522b6341f0f20bb3b4dc013b9f6def7 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Sun, 22 Jun 2025 16:02:56 +0100 Subject: [PATCH 131/149] change credits --- CSJ2K/Properties/AssemblyInfo.cs | 18 +++++++++++++++ CSJ2K/Properties/SharedAssemblyInfo.cs | 32 ++++++++++++++++++++++++++ CSJ2K/README.md | 13 +++++++++++ 3 files changed, 63 insertions(+) create mode 100644 CSJ2K/Properties/AssemblyInfo.cs create mode 100644 CSJ2K/Properties/SharedAssemblyInfo.cs create mode 100644 CSJ2K/README.md diff --git a/CSJ2K/Properties/AssemblyInfo.cs b/CSJ2K/Properties/AssemblyInfo.cs new file mode 100644 index 00000000..cb4ffa4a --- /dev/null +++ b/CSJ2K/Properties/AssemblyInfo.cs @@ -0,0 +1,18 @@ +// Copyright (c) 2007-2016 CSJ2K contributors. +// Licensed under the BSD 3-Clause License. + +using System.Reflection; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. + +#if DOTNET +[assembly: AssemblyTitle("CSJ2K")] +[assembly: ComVisible(false)] +#else +[assembly: AssemblyTitle("CSJ2K.OSCore")] +#endif + +[assembly: AssemblyDescription("JPEG2000 codec class library changed for OpenSimulator")] diff --git a/CSJ2K/Properties/SharedAssemblyInfo.cs b/CSJ2K/Properties/SharedAssemblyInfo.cs new file mode 100644 index 00000000..d1618d0b --- /dev/null +++ b/CSJ2K/Properties/SharedAssemblyInfo.cs @@ -0,0 +1,32 @@ +// Copyright (c) 2007-2016 CSJ2K contributors. +// Licensed under the BSD 3-Clause License. + +using System; +using System.Reflection; +using System.Resources; + +[assembly: CLSCompliant(true)] + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("CSJ2K Contributors, OpenSimulator")] +[assembly: AssemblyProduct("CSJ2K")] +[assembly: AssemblyCopyright("Copyright © 2007-2017 CSJ2K Contributors, OpenSimulator")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] +[assembly: NeutralResourcesLanguage("en")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Revision +// Build Number +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: +[assembly: AssemblyVersion("3.0.0")] +[assembly: AssemblyInformationalVersion("3.0.0")] +[assembly: AssemblyFileVersion("3.0.0.02")] diff --git a/CSJ2K/README.md b/CSJ2K/README.md new file mode 100644 index 00000000..9c4aee13 --- /dev/null +++ b/CSJ2K/README.md @@ -0,0 +1,13 @@ +# This is a very modified version for OpenSimulator use only. See the original for other uses + + https://github.com/cureos/csj2k.git + +Copyright (c) Opensimulator + + +# CSJ2K - A Managed and Portable JPEG2000 Codec + +Copyright (c) 1999-2000 JJ2000 Partners; original C# port (c) 2007-2012 Jason S. Clary; C# encoding and adaptation to Portable Class Library with platform specific support (c) 2013-2016 Anders Gustafsson, Cureos AB + +Licensed and distributable under the terms of the [BSD license](http://www.opensource.org/licenses/bsd-license.php) + From 4d6eb7fc64f5e71dfd0b29880e9a67fae418f4f1 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Sun, 22 Jun 2025 16:35:59 +0100 Subject: [PATCH 132/149] supress some warnings --- prebuild.xml | 5 +++-- prebuildCoreLib.xml | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/prebuild.xml b/prebuild.xml index 5a8bef01..d23c9fcf 100644 --- a/prebuild.xml +++ b/prebuild.xml @@ -9,7 +9,7 @@ true 4 false - 1591,1574,0419,0618 + 1591,1574,0419,0618,CA1416 bin true true @@ -29,7 +29,7 @@ true 4 false - 1591,1574,0419,0618 + 1591,1574,0419,0618,CA1416 bin false true @@ -79,6 +79,7 @@ ../bin/ + diff --git a/prebuildCoreLib.xml b/prebuildCoreLib.xml index a19b67f3..ae2a167d 100755 --- a/prebuildCoreLib.xml +++ b/prebuildCoreLib.xml @@ -9,7 +9,7 @@ true 4 false - 1591,1574,0419,0618 + 1591,1574,0419,0618,CA1416 bin true true @@ -29,7 +29,7 @@ true 4 false - 1591,1574,0419,0618 + 1591,1574,0419,0618,CA1416 bin false true From ab1aa5d16b7dd0b2bbff866a5de1bb6cd9800518 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Sun, 22 Jun 2025 16:47:56 +0100 Subject: [PATCH 133/149] bad git... --- CSJ2K/Util/BitmapImage.cs | 40 ++++ CSJ2K/Util/BitmapImageCreator.cs | 47 +++++ CSJ2K/Util/BitmapImageSource.cs | 110 ++++++++++ CSJ2K/Util/DotnetFileInfo.cs | 71 +++++++ CSJ2K/Util/DotnetFileInfoCreator.cs | 28 +++ CSJ2K/Util/DotnetFileStreamCreator.cs | 33 +++ CSJ2K/Util/DotnetMsgLogger.cs | 36 ++++ CSJ2K/Util/FileInfoFactory.cs | 42 ++++ CSJ2K/Util/FileStreamFactory.cs | 44 ++++ CSJ2K/Util/IDefaultable.cs | 16 ++ CSJ2K/Util/IFileInfo.cs | 21 ++ CSJ2K/Util/IFileInfoCreator.cs | 11 + CSJ2K/Util/IFileStreamCreator.cs | 12 ++ CSJ2K/Util/IImage.cs | 14 ++ CSJ2K/Util/IImageCreator.cs | 14 ++ CSJ2K/Util/ImageBase.cs | 60 ++++++ CSJ2K/Util/ImageFactory.cs | 51 +++++ CSJ2K/Util/PortableImage.cs | 138 +++++++++++++ CSJ2K/Util/PortableImageSource.cs | 283 ++++++++++++++++++++++++++ 19 files changed, 1071 insertions(+) create mode 100644 CSJ2K/Util/BitmapImage.cs create mode 100644 CSJ2K/Util/BitmapImageCreator.cs create mode 100644 CSJ2K/Util/BitmapImageSource.cs create mode 100644 CSJ2K/Util/DotnetFileInfo.cs create mode 100644 CSJ2K/Util/DotnetFileInfoCreator.cs create mode 100644 CSJ2K/Util/DotnetFileStreamCreator.cs create mode 100644 CSJ2K/Util/DotnetMsgLogger.cs create mode 100644 CSJ2K/Util/FileInfoFactory.cs create mode 100644 CSJ2K/Util/FileStreamFactory.cs create mode 100644 CSJ2K/Util/IDefaultable.cs create mode 100644 CSJ2K/Util/IFileInfo.cs create mode 100644 CSJ2K/Util/IFileInfoCreator.cs create mode 100644 CSJ2K/Util/IFileStreamCreator.cs create mode 100644 CSJ2K/Util/IImage.cs create mode 100644 CSJ2K/Util/IImageCreator.cs create mode 100644 CSJ2K/Util/ImageBase.cs create mode 100644 CSJ2K/Util/ImageFactory.cs create mode 100644 CSJ2K/Util/PortableImage.cs create mode 100644 CSJ2K/Util/PortableImageSource.cs diff --git a/CSJ2K/Util/BitmapImage.cs b/CSJ2K/Util/BitmapImage.cs new file mode 100644 index 00000000..88b76bbf --- /dev/null +++ b/CSJ2K/Util/BitmapImage.cs @@ -0,0 +1,40 @@ +// Copyright (c) 2007-2016 CSJ2K contributors. +// Licensed under the BSD 3-Clause License. + +namespace CSJ2K.Util +{ + using System.Drawing; + using System.Drawing.Imaging; + + internal class BitmapImage : ImageBase + { + #region CONSTRUCTORS + + internal BitmapImage(int width, int height, byte[] bytes) + : base(width, height, bytes) + { + } + + #endregion + + #region METHODS + + protected override object GetImageObject() + { + var bitmap = new Bitmap(Width, Height, PixelFormat.Format32bppArgb); + + var dstdata = bitmap.LockBits( + new Rectangle(0, 0, Width, Height), + ImageLockMode.ReadWrite, + bitmap.PixelFormat); + + var ptr = dstdata.Scan0; + System.Runtime.InteropServices.Marshal.Copy(Bytes, 0, ptr, Bytes.Length); + bitmap.UnlockBits(dstdata); + + return bitmap; + } + + #endregion + } +} diff --git a/CSJ2K/Util/BitmapImageCreator.cs b/CSJ2K/Util/BitmapImageCreator.cs new file mode 100644 index 00000000..0975b842 --- /dev/null +++ b/CSJ2K/Util/BitmapImageCreator.cs @@ -0,0 +1,47 @@ +// Copyright (c) 2007-2016 CSJ2K contributors. +// Licensed under the BSD 3-Clause License. + +namespace CSJ2K.Util +{ + using CSJ2K.j2k.image; + + public class BitmapImageCreator : IImageCreator + { + #region FIELDS + + private static readonly IImageCreator Instance = new BitmapImageCreator(); + + #endregion + + #region PROPERTIES + + public bool IsDefault + { + get + { + return false; + } + } + + #endregion + + #region METHODS + + public static void Register() + { + ImageFactory.Register(Instance); + } + + public IImage Create(int width, int height, byte[] bytes) + { + return new BitmapImage(width, height, bytes); + } + + public BlkImgDataSrc ToPortableImageSource(object imageObject) + { + return BitmapImageSource.Create(imageObject); + } + + #endregion + } +} diff --git a/CSJ2K/Util/BitmapImageSource.cs b/CSJ2K/Util/BitmapImageSource.cs new file mode 100644 index 00000000..32b79511 --- /dev/null +++ b/CSJ2K/Util/BitmapImageSource.cs @@ -0,0 +1,110 @@ +// Copyright (c) 2007-2016 CSJ2K contributors. +// Licensed under the BSD 3-Clause License. + +namespace CSJ2K.Util +{ + using System; + using System.Drawing; + using System.Drawing.Imaging; + using System.Linq; + + using CSJ2K.j2k.image; + + internal class BitmapImageSource : PortableImageSource + { + #region CONSTRUCTORS + + private BitmapImageSource(Bitmap bitmap) + : base( + bitmap.Width, + bitmap.Height, + GetNumberOfComponents(bitmap.PixelFormat), + GetRangeBits(bitmap.PixelFormat), + GetSignedArray(bitmap.PixelFormat), + GetComponents(bitmap)) + { + } + + #endregion + + #region METHODS + + + internal static BlkImgDataSrc Create(object imageObject) + { + var bitmap = imageObject as Bitmap; + return bitmap == null ? null : new BitmapImageSource(bitmap); + } + + private static int GetNumberOfComponents(PixelFormat pixelFormat) + { + switch (pixelFormat) + { + case PixelFormat.Format16bppGrayScale: + case PixelFormat.Format1bppIndexed: + case PixelFormat.Format4bppIndexed: + case PixelFormat.Format8bppIndexed: + return 1; + case PixelFormat.Format24bppRgb: + case PixelFormat.Format32bppArgb: + case PixelFormat.Format32bppPArgb: + case PixelFormat.Format32bppRgb: + return 3; + default: + throw new ArgumentOutOfRangeException("pixelFormat"); + } + } + + private static int GetRangeBits(PixelFormat pixelFormat) + { + switch (pixelFormat) + { + case PixelFormat.Format16bppGrayScale: + return 16; + case PixelFormat.Format1bppIndexed: + return 1; + case PixelFormat.Format4bppIndexed: + return 4; + case PixelFormat.Format8bppIndexed: + case PixelFormat.Format24bppRgb: + case PixelFormat.Format32bppArgb: + case PixelFormat.Format32bppPArgb: + case PixelFormat.Format32bppRgb: + return 8; + default: + throw new ArgumentOutOfRangeException("pixelFormat"); + } + } + + private static bool[] GetSignedArray(PixelFormat pixelFormat) + { + return Enumerable.Repeat(false, GetNumberOfComponents(pixelFormat)).ToArray(); + } + + private static int[][] GetComponents(Bitmap bitmap) + { + var w = bitmap.Width; + var h = bitmap.Height; + var nc = GetNumberOfComponents(bitmap.PixelFormat); + + var comps = new int[nc][]; + for (var c = 0; c < nc; ++c) comps[c] = new int[w * h]; + + for (int y = 0, xy = 0; y < h; ++y) + { + for (var x = 0; x < w; ++x, ++xy) + { + var color = bitmap.GetPixel(x, y); + for (var c = 0; c < nc; ++c) + { + comps[c][xy] = c == 0 ? color.R : c == 1 ? color.G : color.B; + } + } + } + + return comps; + } + + #endregion + } +} diff --git a/CSJ2K/Util/DotnetFileInfo.cs b/CSJ2K/Util/DotnetFileInfo.cs new file mode 100644 index 00000000..e03d313b --- /dev/null +++ b/CSJ2K/Util/DotnetFileInfo.cs @@ -0,0 +1,71 @@ +// Copyright (c) 2007-2016 CSJ2K contributors. +// Licensed under the BSD 3-Clause License. + +namespace CSJ2K.Util +{ + using System; + using System.IO; + + internal class DotnetFileInfo : IFileInfo + { + #region FIELDS + + private readonly FileInfo _fileInfo; + + #endregion + + #region CONSTRUCTORS + + internal DotnetFileInfo(string fileName) + { + _fileInfo = new FileInfo(fileName); + } + + #endregion + + #region PROPERTIES + + public string Name + { + get + { + return _fileInfo.Name; + } + } + + public string FullName + { + get + { + return _fileInfo.FullName; + } + } + + public bool Exists + { + get + { + return _fileInfo.Exists; + } + } + + #endregion + + #region METHODS + + public bool Delete() + { + try + { + _fileInfo.Delete(); + return true; + } + catch (Exception) + { + return false; + } + } + + #endregion + } +} diff --git a/CSJ2K/Util/DotnetFileInfoCreator.cs b/CSJ2K/Util/DotnetFileInfoCreator.cs new file mode 100644 index 00000000..587351a4 --- /dev/null +++ b/CSJ2K/Util/DotnetFileInfoCreator.cs @@ -0,0 +1,28 @@ +// Copyright (c) 2007-2016 CSJ2K contributors. +// Licensed under the BSD 3-Clause License. + +namespace CSJ2K.Util +{ + public class DotnetFileInfoCreator : IFileInfoCreator + { + #region FIELDS + + private static readonly IFileInfoCreator Instance = new DotnetFileInfoCreator(); + + #endregion + + #region METHODS + + public static void Register() + { + FileInfoFactory.Register(Instance); + } + + public IFileInfo Create(string fileName) + { + return new DotnetFileInfo(fileName); + } + + #endregion + } +} diff --git a/CSJ2K/Util/DotnetFileStreamCreator.cs b/CSJ2K/Util/DotnetFileStreamCreator.cs new file mode 100644 index 00000000..9cf559db --- /dev/null +++ b/CSJ2K/Util/DotnetFileStreamCreator.cs @@ -0,0 +1,33 @@ +// Copyright (c) 2007-2016 CSJ2K contributors. +// Licensed under the BSD 3-Clause License. + +namespace CSJ2K.Util +{ + using System; + using System.IO; + + public class DotnetFileStreamCreator : IFileStreamCreator + { + #region FIELDS + + private static readonly IFileStreamCreator Instance = new DotnetFileStreamCreator(); + + #endregion + + #region METHODS + + public static void Register() + { + FileStreamFactory.Register(Instance); + } + + public Stream Create(string path, string mode) + { + if (mode.Equals("rw", StringComparison.OrdinalIgnoreCase)) return new FileStream(path, FileMode.OpenOrCreate, FileAccess.ReadWrite); + if (mode.Equals("r", StringComparison.OrdinalIgnoreCase)) return new FileStream(path, FileMode.Open, FileAccess.Read); + throw new ArgumentException(String.Format("File mode: {0} not supported.", mode), "mode"); + } + + #endregion + } +} diff --git a/CSJ2K/Util/DotnetMsgLogger.cs b/CSJ2K/Util/DotnetMsgLogger.cs new file mode 100644 index 00000000..e5844542 --- /dev/null +++ b/CSJ2K/Util/DotnetMsgLogger.cs @@ -0,0 +1,36 @@ +// Copyright (c) 2007-2016 CSJ2K contributors. +// Licensed under the BSD 3-Clause License. + +namespace CSJ2K.Util +{ + using System; + + using CSJ2K.j2k.util; + + public class DotnetMsgLogger : StreamMsgLogger + { + #region FIELDS + + private static readonly IMsgLogger Instance = new DotnetMsgLogger(); + + #endregion + + #region CONSTRUCTORS + + public DotnetMsgLogger() + : base(Console.OpenStandardOutput(), Console.OpenStandardError(), 78) + { + } + + #endregion + + #region METHODS + + public static void Register() + { + FacilityManager.DefaultMsgLogger = Instance; + } + + #endregion + } +} diff --git a/CSJ2K/Util/FileInfoFactory.cs b/CSJ2K/Util/FileInfoFactory.cs new file mode 100644 index 00000000..e6201dfa --- /dev/null +++ b/CSJ2K/Util/FileInfoFactory.cs @@ -0,0 +1,42 @@ +// Copyright (c) 2007-2016 CSJ2K contributors. +// Licensed under the BSD 3-Clause License. + +namespace CSJ2K.Util +{ + using System; + + public static class FileInfoFactory + { + #region FIELDS + + private static IFileInfoCreator _creator; + + #endregion + + #region CONSTRUCTORS + + static FileInfoFactory() + { + _creator = J2kSetup.GetSinglePlatformInstance(); + } + + #endregion + + #region METHODS + + public static void Register(IFileInfoCreator creator) + { + _creator = creator; + } + + internal static IFileInfo New(string fileName) + { + if (_creator == null) throw new InvalidOperationException("No file info creator is registered."); + if (fileName == null) throw new ArgumentNullException("fileName"); + + return _creator.Create(fileName); + } + + #endregion + } +} \ No newline at end of file diff --git a/CSJ2K/Util/FileStreamFactory.cs b/CSJ2K/Util/FileStreamFactory.cs new file mode 100644 index 00000000..89100358 --- /dev/null +++ b/CSJ2K/Util/FileStreamFactory.cs @@ -0,0 +1,44 @@ +// Copyright (c) 2007-2016 CSJ2K contributors. +// Licensed under the BSD 3-Clause License. + +namespace CSJ2K.Util +{ + using System; + using System.IO; + + public class FileStreamFactory + { + #region FIELDS + + private static IFileStreamCreator _creator; + + #endregion + + #region CONSTRUCTORS + + static FileStreamFactory() + { + _creator = J2kSetup.GetSinglePlatformInstance(); + } + + #endregion + + #region METHODS + + public static void Register(IFileStreamCreator creator) + { + _creator = creator; + } + + internal static Stream New(string path, string mode) + { + if (_creator == null) throw new InvalidOperationException("No file stream creator is registered."); + if (path == null) throw new ArgumentNullException("path"); + if (mode == null) throw new ArgumentNullException("mode"); + + return _creator.Create(path, mode); + } + + #endregion + } +} diff --git a/CSJ2K/Util/IDefaultable.cs b/CSJ2K/Util/IDefaultable.cs new file mode 100644 index 00000000..eba1150d --- /dev/null +++ b/CSJ2K/Util/IDefaultable.cs @@ -0,0 +1,16 @@ +// Copyright (c) 2012-2016 fo-dicom contributors. +// Licensed under the Microsoft Public License (MS-PL). + +namespace CSJ2K.Util +{ + /// + /// Interface for default classification of manager types. + /// + public interface IDefaultable + { + /// + /// Gets whether or not this type is classified as a default manager. + /// + bool IsDefault { get; } + } +} \ No newline at end of file diff --git a/CSJ2K/Util/IFileInfo.cs b/CSJ2K/Util/IFileInfo.cs new file mode 100644 index 00000000..47c2a635 --- /dev/null +++ b/CSJ2K/Util/IFileInfo.cs @@ -0,0 +1,21 @@ +namespace CSJ2K.Util +{ + public interface IFileInfo + { + #region PROPERTIES + + string Name { get; } + + string FullName { get; } + + bool Exists { get; } + + #endregion + + #region METHODS + + bool Delete(); + + #endregion + } +} \ No newline at end of file diff --git a/CSJ2K/Util/IFileInfoCreator.cs b/CSJ2K/Util/IFileInfoCreator.cs new file mode 100644 index 00000000..9e993b07 --- /dev/null +++ b/CSJ2K/Util/IFileInfoCreator.cs @@ -0,0 +1,11 @@ +namespace CSJ2K.Util +{ + public interface IFileInfoCreator + { + #region METHODS + + IFileInfo Create(string fileName); + + #endregion + } +} \ No newline at end of file diff --git a/CSJ2K/Util/IFileStreamCreator.cs b/CSJ2K/Util/IFileStreamCreator.cs new file mode 100644 index 00000000..88f1da69 --- /dev/null +++ b/CSJ2K/Util/IFileStreamCreator.cs @@ -0,0 +1,12 @@ +// Copyright (c) 2007-2016 CSJ2K contributors. +// Licensed under the BSD 3-Clause License. + +namespace CSJ2K.Util +{ + using System.IO; + + public interface IFileStreamCreator + { + Stream Create(string path, string mode); + } +} diff --git a/CSJ2K/Util/IImage.cs b/CSJ2K/Util/IImage.cs new file mode 100644 index 00000000..56001ccd --- /dev/null +++ b/CSJ2K/Util/IImage.cs @@ -0,0 +1,14 @@ +// Copyright (c) 2007-2016 CSJ2K contributors. +// Licensed under the BSD 3-Clause License. + +namespace CSJ2K.Util +{ + public interface IImage + { + #region METHODS + + T As(); + + #endregion + } +} diff --git a/CSJ2K/Util/IImageCreator.cs b/CSJ2K/Util/IImageCreator.cs new file mode 100644 index 00000000..07e54788 --- /dev/null +++ b/CSJ2K/Util/IImageCreator.cs @@ -0,0 +1,14 @@ +// Copyright (c) 2007-2016 CSJ2K contributors. +// Licensed under the BSD 3-Clause License. + +namespace CSJ2K.Util +{ + using CSJ2K.j2k.image; + + public interface IImageCreator : IDefaultable + { + IImage Create(int width, int height, byte[] bytes); + + BlkImgDataSrc ToPortableImageSource(object imageObject); + } +} diff --git a/CSJ2K/Util/ImageBase.cs b/CSJ2K/Util/ImageBase.cs new file mode 100644 index 00000000..ed545cb8 --- /dev/null +++ b/CSJ2K/Util/ImageBase.cs @@ -0,0 +1,60 @@ +// Copyright (c) 2007-2016 CSJ2K contributors. +// Licensed under the BSD 3-Clause License. + +namespace CSJ2K.Util +{ + using System; + using System.Reflection; + + + public abstract class ImageBase : IImage + { + #region FIELDS + + protected const int SizeOfArgb = 4; + + #endregion + + #region CONSTRUCTORS + + protected ImageBase(int width, int height, byte[] bytes) + { + Width = width; + Height = height; + Bytes = bytes; + } + + #endregion + + #region PROPERTIES + + protected int Width { get; } + + protected int Height { get; } + + protected byte[] Bytes { get; } + + #endregion + + #region METHODS + + public virtual T As() + { +#if NETFX_CORE || NETSTANDARD + if (!typeof(TBase).GetTypeInfo().IsAssignableFrom(typeof(T).GetTypeInfo())) +#else + if (!typeof(TBase).IsAssignableFrom(typeof(T))) +#endif + { + throw new InvalidCastException( + $"Cannot cast to '{typeof(T).Name}'; type must be assignable from '{typeof(TBase).Name}'"); + } + + return (T)GetImageObject(); + } + + protected abstract object GetImageObject(); + + #endregion + } +} diff --git a/CSJ2K/Util/ImageFactory.cs b/CSJ2K/Util/ImageFactory.cs new file mode 100644 index 00000000..9dd5a214 --- /dev/null +++ b/CSJ2K/Util/ImageFactory.cs @@ -0,0 +1,51 @@ +// Copyright (c) 2007-2016 CSJ2K contributors. +// Licensed under the BSD 3-Clause License. + +namespace CSJ2K.Util +{ + using CSJ2K.j2k.image; + + public static class ImageFactory + { + #region FIELDS + + private static IImageCreator _creator; + + #endregion + + #region CONSTRUCTORS + + static ImageFactory() + { + _creator = J2kSetup.GetDefaultPlatformInstance(); + } + + #endregion + + #region METHODS + + public static void Register(IImageCreator creator) + { + _creator = creator; + } + + internal static IImage New(int width, int height, byte[] bytes) + { + return _creator.Create(width, height, bytes); + } + + internal static BlkImgDataSrc ToPortableImageSource(object imageObject) + { + try + { + return _creator.ToPortableImageSource(imageObject); + } + catch + { + return null; + } + } + + #endregion + } +} diff --git a/CSJ2K/Util/PortableImage.cs b/CSJ2K/Util/PortableImage.cs new file mode 100644 index 00000000..367911ed --- /dev/null +++ b/CSJ2K/Util/PortableImage.cs @@ -0,0 +1,138 @@ +// Copyright (c) 2007-2016 CSJ2K contributors. +// Licensed under the BSD 3-Clause License. + +using System; +using System.Linq; + +namespace CSJ2K.Util +{ + public sealed class PortableImage : IImage + { + #region FIELDS + + private const int SizeOfArgb = 4; + + private readonly double[] _byteScaling; + + #endregion + + #region CONSTRUCTORS + + internal PortableImage(int width, int height, int numberOfComponents, int[] bitsUsed) + { + Width = width; + Height = height; + NumberOfComponents = numberOfComponents; + + _byteScaling = bitsUsed.Select(b => 255.0 / ((1 << b) - 1)).ToArray(); + + Data = new int[numberOfComponents * width * height]; + } + + #endregion + + #region PROPERTIES + + internal int Width { get; } + + internal int Height { get; } + + public int NumberOfComponents { get; } + + internal int[] Data { get; } + + #endregion + + #region METHODS + + public T As() + { + var image = ImageFactory.New(Width, Height, ToBytes(Width, Height, NumberOfComponents, _byteScaling, Data)); + return image.As(); + } + + public int[] GetComponent(int number) + { + if (number < 0 || number >= NumberOfComponents) + { + throw new ArgumentOutOfRangeException(nameof(number)); + } + + var length = Width * Height; + var component = new int[length]; + + for (int i = number, k = 0; k < length; i += NumberOfComponents, ++k) + { + component[k] = Data[i]; + } + + return component; + } + + internal void FillRow(int rowIndex, int lineIndex, int rowWidth, int[] rowValues) + { + Array.Copy( + rowValues, + 0, + Data, + NumberOfComponents * (rowIndex + lineIndex * rowWidth), + rowValues.Length); + } + + private static byte[] ToBytes(int width, int height, int numberOfComponents, double[] byteScaling, int[] data) + { + var count = numberOfComponents * width * height; + var bytes = new byte[SizeOfArgb * width * height]; + + switch (numberOfComponents) + { + case 1: + var scale = byteScaling[0]; + for (int i = 0, j = 0; i < count; ++i) + { + var b = (byte)(scale * data[i]); + bytes[j++] = b; + bytes[j++] = b; + bytes[j++] = b; + bytes[j++] = 0xff; + } + break; + case 3: + { + var scale0 = byteScaling[0]; + var scale1 = byteScaling[1]; + var scale2 = byteScaling[2]; + for (int i = 0, j = 0; i < count;) + { + bytes[j++] = (byte)(scale0 * data[i++]); + bytes[j++] = (byte)(scale1 * data[i++]); + bytes[j++] = (byte)(scale2 * data[i++]); + bytes[j++] = 0xff; + } + } + break; + case 4: + { + var scale0 = byteScaling[0]; + var scale1 = byteScaling[1]; + var scale2 = byteScaling[2]; + var scale3 = byteScaling[3]; + for (int i = 0, j = 0; i < count;) + { + bytes[j++] = (byte)(scale0 * data[i++]); + bytes[j++] = (byte)(scale1 * data[i++]); + bytes[j++] = (byte)(scale2 * data[i++]); + bytes[j++] = (byte)(scale3 * data[i++]); + } + } + break; + default: + throw new ArgumentOutOfRangeException(nameof(numberOfComponents), $"Invalid number of components: {numberOfComponents}"); + } + + return bytes; + } + + #endregion + } +} diff --git a/CSJ2K/Util/PortableImageSource.cs b/CSJ2K/Util/PortableImageSource.cs new file mode 100644 index 00000000..44e8d08b --- /dev/null +++ b/CSJ2K/Util/PortableImageSource.cs @@ -0,0 +1,283 @@ +// Copyright (c) 2007-2016 CSJ2K contributors. +// Licensed under the BSD 3-Clause License. + +namespace CSJ2K.Util +{ + using System; + + using CSJ2K.j2k; + using CSJ2K.j2k.image; + + public class PortableImageSource : BlkImgDataSrc + { + #region FIELDS + + private readonly int w; + + private readonly int h; + + private readonly int nc; + + private readonly int rb; + + private readonly bool[] sgnd; + + private readonly int[][] comps; + + #endregion + + #region CONSTRUCTORS + + public PortableImageSource(int w, int h, int nc, int rb, bool[] sgnd, int[][] comps) + { + this.w = w; + this.h = h; + this.nc = nc; + this.rb = rb; + this.sgnd = sgnd; + this.comps = comps; + } + + #endregion + + #region PROPERTIES + + public int TileWidth + { + get + { + return this.w; + } + } + + public int TileHeight + { + get + { + return this.h; + } + } + + public int NomTileWidth + { + get + { + return this.w; + } + } + + public int NomTileHeight { + get + { + return this.h; + } + } + + public int ImgWidth { + get + { + return this.w; + } + } + + public int ImgHeight { + get + { + return this.h; + } + } + + public int NumComps { + get + { + return this.nc; + } + } + + public int TileIdx { + get + { + return 0; + } + } + + public int TilePartULX { + get + { + return 0; + } + } + + public int TilePartULY { + get + { + return 0; + } + } + + public int ImgULX { + get + { + return 0; + } + } + + public int ImgULY { + get + { + return 0; + } + } + + #endregion + + #region METHODS + + public int getCompSubsX(int c) + { + return 1; + } + + public int getCompSubsY(int c) + { + return 1; + } + + public int getTileCompWidth(int t, int c) + { + if (t != 0) + { + throw new System.InvalidOperationException("Asking a tile-component width for a tile index" + " greater than 0 whereas there is only one tile"); + } + return this.w; + } + + public int getTileCompHeight(int t, int c) + { + if (t != 0) + { + throw new System.InvalidOperationException("Asking a tile-component width for a tile index" + " greater than 0 whereas there is only one tile"); + } + return this.h; + } + + public int getCompImgWidth(int c) + { + return this.w; + } + + public int getCompImgHeight(int c) + { + return this.h; + } + + public int getNomRangeBits(int c) + { + return this.rb; + } + + public void setTile(int x, int y) + { + if (x != 0 || y != 0) + { + throw new System.ArgumentException(); + } + } + + public void nextTile() + { + throw new NoNextElementException(); + } + + public Coord getTile(Coord co) + { + if (co != null) + { + co.x = 0; + co.y = 0; + return co; + } + + return new Coord(0, 0); + } + + public int getCompULX(int c) + { + return 0; + } + + public int getCompULY(int c) + { + return 0; + } + + public Coord getNumTiles(Coord co) + { + if (co != null) + { + co.x = 1; + co.y = 1; + return co; + } + + return new Coord(1, 1); + } + + public int getNumTiles() + { + return 1; + } + + public int getFixedPoint(int c) + { + return 0; + } + + public DataBlk getInternCompData(DataBlk blk, int c) + { + if (c < 0 || c >= this.nc) + { + throw new ArgumentOutOfRangeException("c"); + } + + var data = new int[blk.w * blk.h]; + for (int y = blk.uly, k = 0; y < blk.uly + blk.h; ++y) + { + for (int x = blk.ulx, xy = blk.uly * this.w + blk.ulx; x < blk.ulx + blk.w; ++x, ++k, ++xy) + { + data[k] = this.comps[c][xy]; + } + } + + blk.offset = 0; + blk.scanw = blk.w; + blk.progressive = false; + blk.Data = data; + + return blk; + } + + public DataBlk getCompData(DataBlk blk, int c) + { + var newBlk = new DataBlkInt(blk.ulx, blk.uly, blk.w, blk.h); + return this.getInternCompData(newBlk, c); + } + + public void close() + { + // Do nothing. + } + + public bool isOrigSigned(int c) + { + if (c < 0 || c >= this.nc) + { + throw new ArgumentOutOfRangeException("c"); + } + + return this.sgnd[c]; + } + + #endregion + } +} From 1226edc74b1116db1d9a2563a65ca70e74f4df57 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Sun, 22 Jun 2025 16:55:32 +0100 Subject: [PATCH 134/149] bad git... --- CSJ2K/j2k/util/IMsgLogger.cs | 119 +++++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 CSJ2K/j2k/util/IMsgLogger.cs diff --git a/CSJ2K/j2k/util/IMsgLogger.cs b/CSJ2K/j2k/util/IMsgLogger.cs new file mode 100644 index 00000000..c340e032 --- /dev/null +++ b/CSJ2K/j2k/util/IMsgLogger.cs @@ -0,0 +1,119 @@ +// Copyright (c) 2007-2016 CSJ2K contributors. +// Licensed under the BSD 3-Clause License. + +/* + * JJ2000 COPYRIGHT: + * + * This software module was originally developed by Raphaël Grosbois and + * Diego Santa Cruz (Swiss Federal Institute of Technology-EPFL); Joel + * Askelöf (Ericsson Radio Systems AB); and Bertrand Berthelot, David + * Bouchard, Félix Henry, Gerard Mozelle and Patrice Onno (Canon Research + * Centre France S.A) in the course of development of the JPEG2000 + * standard as specified by ISO/IEC 15444 (JPEG 2000 Standard). This + * software module is an implementation of a part of the JPEG 2000 + * Standard. Swiss Federal Institute of Technology-EPFL, Ericsson Radio + * Systems AB and Canon Research Centre France S.A (collectively JJ2000 + * Partners) agree not to assert against ISO/IEC and users of the JPEG + * 2000 Standard (Users) any of their rights under the copyright, not + * including other intellectual property rights, for this software module + * with respect to the usage by ISO/IEC and Users of this software module + * or modifications thereof for use in hardware or software products + * claiming conformance to the JPEG 2000 Standard. Those intending to use + * this software module in hardware or software products are advised that + * their use may infringe existing patents. The original developers of + * this software module, JJ2000 Partners and ISO/IEC assume no liability + * for use of this software module or modifications thereof. No license + * or right to this software module is granted for non JPEG 2000 Standard + * conforming products. JJ2000 Partners have full right to use this + * software module for his/her own purpose, assign or donate this + * software module to any third party and to inhibit third parties from + * using this software module for non JPEG 2000 Standard conforming + * products. This copyright notice must be included in all copies or + * derivative works of this software module. + * + * Copyright (c) 1999/2000 JJ2000 Partners. + */ + +namespace CSJ2K.j2k.util +{ + + /// This class provides a simple common abstraction of a facility that logs + /// and/or displays messages or simple strings. The underlying facility can be + /// a terminal, text file, text area in a GUI display, dialog boxes in a GUI + /// display, etc., or a combination of those. + ///

Messages are short strings (a couple of lines) that indicate some state + /// of the program, and that have a severity code associated with them (see + /// below). Simple strings is text (can be long) that has no severity code + /// associated with it. Typical use of simple strings is to display help + /// texts.

+ ///

Each message has a severity code, which can be one of the following: + /// LOG, INFO, WARNING, ERROR. Each implementation should treat each severity + /// code in a way which corresponds to the type of diplay used.

+ ///

Messages are printed via the 'printmsg()' method. Simple strings are + /// printed via the 'print()', 'println()' and 'flush()' methods, each simple + /// string is considered to be terminated once the 'flush()' method has been + /// called. The 'printmsg()' method should never be called before a previous + /// simple string has been terminated.

+ ///
+ public struct MsgLogger_Fields + { + /// Severity of message. LOG messages are just for bookkeeping and do not + /// need to be displayed in the majority of cases + /// + public const int LOG = 0; + + /// Severity of message. INFO messages should be displayed just for user + /// feedback. + /// + public const int INFO = 1; + + /// Severity of message. WARNING messages denote that an unexpected state + /// has been reached and should be given as feedback to the user. + /// + public const int WARNING = 2; + + /// Severity of message. ERROR messages denote that something has gone + /// wrong and probably that execution has ended. They should be definetely + /// displayed to the user. + /// + public const int ERROR = 3; + } + + public interface IMsgLogger + { + /// Prints the message 'msg' to the output device, appending a newline, + /// with severity 'sev'. Some implementations where the appended newline is + /// irrelevant may not append the newline. Depending on the implementation + /// the severity of the message may be added to it. The message is + /// reformatted as appropriate for the output devic, but any newline + /// characters are respected. + /// + /// The message severity (LOG, INFO, etc.) + /// + /// The message to display + /// + void printmsg(int sev, string msg); + + /// Prints the string 'str' to the output device, appending a line + /// return. The message is reformatted as appropriate to the particular + /// diplaying device, where 'flind' and 'ind' are used as hints for + /// performing that operation. However, any newlines appearing in 'str' are + /// respected. The output device may not display the string until flush() + /// is called. Some implementations may automatically flush when this + /// method is called. This method just prints the string, the string does + /// not make part of a "message" in the sense that no severity is + /// associated to it. + /// + /// The string to print + /// + /// Indentation of the first line + /// + /// Indentation of any other lines. + /// + void println(string str, int flind, int ind); + + /// Writes any buffered data from the println() method to the device. + /// + void flush(); + } +} From d82a402b5ee06b46560727ad2afdbe5c200ab523 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Sun, 22 Jun 2025 17:00:26 +0100 Subject: [PATCH 135/149] bad git... --- CSJ2K/J2kSetup.cs | 128 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 CSJ2K/J2kSetup.cs diff --git a/CSJ2K/J2kSetup.cs b/CSJ2K/J2kSetup.cs new file mode 100644 index 00000000..416bc9f0 --- /dev/null +++ b/CSJ2K/J2kSetup.cs @@ -0,0 +1,128 @@ +// Copyright (c) 2007-2016 CSJ2K contributors. +// Licensed under the BSD 3-Clause License. + +namespace CSJ2K +{ + using System; + using System.Collections.Generic; + using System.Linq; + using System.Reflection; + + using CSJ2K.Util; + + /// + /// Setup helper methods for initializing library. + /// + internal static class J2kSetup + { + /// + /// Gets a single instance from the platform assembly implementing the type. + /// + /// (Abstract) type for which implementation is requested. + /// The single instance from the platform assembly implementing the type, + /// or null if no or more than one implementations are available. + /// It is implicitly assumed that implementation class has a public, parameter-less constructor. + internal static T GetSinglePlatformInstance() + { + try + { + var assembly = GetCurrentAssembly(); +#if NETFX_CORE || NETSTANDARD + var type = + assembly.DefinedTypes.Single( + t => (t.IsSubclassOf(typeof(T)) || typeof(T).GetTypeInfo().IsAssignableFrom(t)) && !t.IsAbstract) + .AsType(); +#else + var type = + assembly.GetTypes() + .Single(t => (t.IsSubclassOf(typeof(T)) || typeof(T).IsAssignableFrom(t)) && !t.IsAbstract); +#endif + var instance = (T)Activator.CreateInstance(type); + + return instance; + } + catch (Exception) + { + return default(T); + } + } + + /// + /// Gets the default classified instance from the platform assembly implementing the type. + /// + /// (Abstract) type for which implementation is requested. + /// The single instance from the platform assembly implementing the type that is classified as default, + /// or null if no or more than one default classified implementations are available. + /// It is implicitly assumed that all implementation classes has a public, parameter-less constructor. + internal static T GetDefaultPlatformInstance() where T : IDefaultable + { + try + { + var assembly = GetCurrentAssembly(); + var types = GetConcreteTypes(assembly); + + return GetDefaultOrSingleInstance(types); + } + catch (Exception) + { + return default(T); + } + } + + private static Assembly GetCurrentAssembly() + { +#if NETFX_CORE || NETSTANDARD + return typeof(J2kSetup).GetTypeInfo().Assembly; +#else + return typeof(J2kSetup).Assembly; +#endif + } + + private static IEnumerable GetConcreteTypes(Assembly assembly) + { +#if NETFX_CORE || NETSTANDARD + return assembly.DefinedTypes.Where( +#else + return assembly.GetTypes().Where( +#endif + t => + { + try + { +#if NETFX_CORE || NETSTANDARD + return (t.IsSubclassOf(typeof(T)) || typeof(T).GetTypeInfo().IsAssignableFrom(t)) + && !t.IsAbstract; +#else + return (t.IsSubclassOf(typeof(T)) || typeof(T).IsAssignableFrom(t)) && !t.IsAbstract; +#endif + } + catch + { + return false; + } +#if NETFX_CORE || NETSTANDARD + }).Select(t => t.AsType()); +#else + }); +#endif + } + + private static T GetDefaultOrSingleInstance(IEnumerable types) where T : IDefaultable + { + var instances = types.Select( + t => + { + try + { + return (T)Activator.CreateInstance(t); + } + catch + { + return default(T); + } + }).ToList(); + + return instances.Count > 1 ? instances.Single(instance => instance.IsDefault) : instances.SingleOrDefault(); + } + } +} From 1a04a8be7f5170bd0913dbf4f80d4166565c8947 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Sun, 22 Jun 2025 17:40:03 +0100 Subject: [PATCH 136/149] several changes to meshing, etc --- CSJ2K/J2kImage.cs | 1 - .../MeshmerizerR.cs | 48 +- OpenMetaverse/Assets/AssetTypes/AssetMesh.cs | 88 +- OpenMetaverse/Imaging/ManagedImage.cs | 2 - OpenMetaverse/Imaging/OpenJPEG.cs | 1 - OpenMetaverse/Rendering/Rendering.cs | 298 ++- OpenMetaverseTypes/Quaternion.cs | 91 +- OpenMetaverseTypes/Vector3.cs | 129 +- OpenMetaverseTypes/Vector4.cs | 11 +- PrimMesher/ObjMesh.cs | 37 +- PrimMesher/PrimMesher.cs | 2142 ++++++++--------- PrimMesher/SculptMap.cs | 19 +- PrimMesher/SculptMesh.cs | 242 +- PrimMesher/VertexIndexer.cs | 7 +- 14 files changed, 1524 insertions(+), 1592 deletions(-) diff --git a/CSJ2K/J2kImage.cs b/CSJ2K/J2kImage.cs index acb7eb91..4b76ad7e 100644 --- a/CSJ2K/J2kImage.cs +++ b/CSJ2K/J2kImage.cs @@ -38,7 +38,6 @@ namespace CSJ2K { - public class J2kImage { diff --git a/OpenMetaverse.Rendering.Meshmerizer/MeshmerizerR.cs b/OpenMetaverse.Rendering.Meshmerizer/MeshmerizerR.cs index 31415e96..b6e1981d 100644 --- a/OpenMetaverse.Rendering.Meshmerizer/MeshmerizerR.cs +++ b/OpenMetaverse.Rendering.Meshmerizer/MeshmerizerR.cs @@ -56,16 +56,15 @@ public OMVR.SimpleMesh GenerateSimpleMesh(OMV.Primitive prim, OMVR.DetailLevel l if (newPrim == null) return null; - SimpleMesh mesh = new SimpleMesh(); - mesh.Path = new Path(); - mesh.Prim = prim; - mesh.Profile = new Profile(); - mesh.Vertices = new List(newPrim.coords.Count); - for (int i = 0; i < newPrim.coords.Count; i++) + SimpleMesh mesh = new() { - PrimMesher.Coord c = newPrim.coords[i]; - mesh.Vertices.Add(new Vertex { Position = new Vector3(c.X, c.Y, c.Z) }); - } + Path = new Path(), + Prim = prim, + Profile = new Profile(), + Vertices = new List(newPrim.coords.Count) + }; + for (int i = 0; i < newPrim.coords.Count; i++) + mesh.Vertices.Add(new Vertex { Position = newPrim.coords[i] }); mesh.Indices = new List(newPrim.faces.Count * 3); for (int i = 0; i < newPrim.faces.Count; i++) @@ -117,35 +116,36 @@ public OMVR.SimpleMesh GenerateSimpleSculptMesh(OMV.Primitive prim, System.Drawi /// The generated mesh public OMVR.FacetedMesh GenerateFacetedMesh(OMV.Primitive prim, OMVR.DetailLevel lod) { - bool isSphere = ((OMV.ProfileCurve)(prim.PrimData.profileCurve & 0x07) == OMV.ProfileCurve.HalfCircle); PrimMesher.PrimMesh newPrim = GeneratePrimMesh(prim, lod, true); if (newPrim == null) return null; // copy the vertex information into OMVR.IRendering structures - OMVR.FacetedMesh omvrmesh = new OMVR.FacetedMesh(); - omvrmesh.Faces = new List(); - omvrmesh.Prim = prim; - omvrmesh.Profile = new OMVR.Profile(); - omvrmesh.Profile.Faces = new List(); - omvrmesh.Profile.Positions = new List(); - omvrmesh.Path = new OMVR.Path(); - omvrmesh.Path.Points = new List(); + OMVR.FacetedMesh omvrmesh = new() + { + Faces = [], + Prim = prim, + Profile = new() { Faces = [], Positions = [] }, + Path = new() { Points = [] } + }; + var indexer = newPrim.GetVertexIndexer(); for (int i = 0; i < indexer.numPrimFaces; i++) { - OMVR.Face oface = new OMVR.Face(); - oface.Vertices = new List(); - oface.Indices = new List(); - oface.TextureFace = prim.Textures.GetFace((uint)i); + OMVR.Face oface = new() + { + Vertices = [], + Indices = [], + TextureFace = prim.Textures.GetFace((uint)i) + }; for (int j = 0; j < indexer.viewerVertices[i].Count; j++) { var vert = new OMVR.Vertex(); var m = indexer.viewerVertices[i][j]; - vert.Position = new Vector3(m.v.X, m.v.Y, m.v.Z); - vert.Normal = new Vector3(m.n.X, m.n.Y, m.n.Z); + vert.Position = m.v; + vert.Normal = m.n; vert.TexCoord = new OMV.Vector2(m.uv.U, 1.0f - m.uv.V); oface.Vertices.Add(vert); } diff --git a/OpenMetaverse/Assets/AssetTypes/AssetMesh.cs b/OpenMetaverse/Assets/AssetTypes/AssetMesh.cs index 164af717..2453314b 100644 --- a/OpenMetaverse/Assets/AssetTypes/AssetMesh.cs +++ b/OpenMetaverse/Assets/AssetTypes/AssetMesh.cs @@ -25,9 +25,9 @@ */ using System; +using System.Buffers; using System.IO; using System.IO.Compression; -using OpenMetaverse; using OpenMetaverse.StructuredData; namespace OpenMetaverse.Assets @@ -79,22 +79,38 @@ public override bool Decode() foreach(string partName in header.Keys) { - if (header[partName].Type != OSDType.Map) + OSD partOSD = header[partName]; + if(partOSD is not OSDMap partInfo) { - MeshData[partName] = header[partName]; + MeshData[partName] = partOSD; continue; } - OSDMap partInfo = (OSDMap)header[partName]; - if (partInfo["offset"] < 0 || partInfo["size"] == 0) + if(!partInfo.TryGetInt("offset", out int partDataOffset)) { MeshData[partName] = partInfo; continue; } - byte[] part = new byte[partInfo["size"]]; - Buffer.BlockCopy(AssetData, partInfo["offset"] + (int)start, part, 0, part.Length); - MeshData[partName] = DecompressMeshOSD(part); + partDataOffset += (int)start; + if(partDataOffset > AssetData.Length) + { + MeshData[partName] = partInfo; + continue; + } + + if(!partInfo.TryGetInt("size", out int partDataSize)) + { + MeshData[partName] = partInfo; + continue; + } + if(partDataOffset + partDataSize > AssetData.Length) + { + MeshData[partName] = partInfo; + continue; + } + + MeshData[partName] = DecompressMeshOSD(AssetData, partDataOffset, partDataSize); } } return true; @@ -106,34 +122,50 @@ public override bool Decode() } } - public static OSD DecompressMeshOSD(byte[] data) + public static OSD DecodeBlock(byte[] MeshBytes, string BlockName) { - OSD decodedOsd = null; - - using (MemoryStream inMs = new MemoryStream(data)) + try { - using (MemoryStream outMs = new MemoryStream()) - { - using (DeflateStream decompressionStream = new DeflateStream(inMs, CompressionMode.Decompress)) - { - byte[] readBuffer = new byte[2048]; - inMs.Read(readBuffer, 0, 2); // skip first 2 bytes in header - int readLen = 0; + using MemoryStream data = new(MeshBytes); - while ((readLen = decompressionStream.Read(readBuffer, 0, readBuffer.Length)) > 0) - outMs.Write(readBuffer, 0, readLen); + OSDMap header = (OSDMap)OSDParser.DeserializeLLSDBinary(data); + long start = data.Position; - outMs.Flush(); + if (!header.TryGetOSDMap(BlockName, out OSDMap LayerInfo)) + return null; - outMs.Seek(0, SeekOrigin.Begin); + if (!LayerInfo.TryGetInt("offset", out int BlockDataOffset)) + return null; - byte[] decompressedBuf = outMs.GetBuffer(); + BlockDataOffset += (int)start; + if (BlockDataOffset > MeshBytes.Length) + return null; - decodedOsd = OSDParser.DeserializeLLSDBinary(decompressedBuf); - } - } + if (!LayerInfo.TryGetInt("size", out int BlockDataSize)) + return null; + + if (BlockDataOffset + BlockDataSize > MeshBytes.Length) + return null; + + return DecompressMeshOSD(MeshBytes, BlockDataOffset, BlockDataSize); + } + catch (Exception ex) + { + Logger.Log("Failed to decode mesh asset", Helpers.LogLevel.Error, ex); + return null; + } + } + + public static OSD DecompressMeshOSD(byte[] data, int start, int len) + { + using MemoryStream outMs = new(4 * len); + using (MemoryStream inMs = new(data, start + 2, len - 2)) // skip first 2 bytes + { + using DeflateStream decompressionStream = new(inMs, CompressionMode.Decompress); + decompressionStream.CopyTo(outMs); } - return decodedOsd; + outMs.Seek(0, SeekOrigin.Begin); + return OSDParser.DeserializeLLSDBinary(outMs); } } } diff --git a/OpenMetaverse/Imaging/ManagedImage.cs b/OpenMetaverse/Imaging/ManagedImage.cs index adc12f82..27bb2d9d 100644 --- a/OpenMetaverse/Imaging/ManagedImage.cs +++ b/OpenMetaverse/Imaging/ManagedImage.cs @@ -116,7 +116,6 @@ public ManagedImage(int width, int height, ImageChannels channels) Bump = new byte[n]; } -#if !NO_UNSAFE /// /// /// @@ -218,7 +217,6 @@ public ManagedImage(System.Drawing.Bitmap bitmap) throw new NotSupportedException("Unrecognized pixel format: " + bitmap.PixelFormat.ToString()); } } -#endif /// /// Convert the channels in the image. Channels are created or destroyed as required. diff --git a/OpenMetaverse/Imaging/OpenJPEG.cs b/OpenMetaverse/Imaging/OpenJPEG.cs index 71c8c804..e4780e97 100644 --- a/OpenMetaverse/Imaging/OpenJPEG.cs +++ b/OpenMetaverse/Imaging/OpenJPEG.cs @@ -27,7 +27,6 @@ using System; using System.Drawing; using System.Drawing.Imaging; -using System.Reflection; using System.Runtime.InteropServices; namespace OpenMetaverse.Imaging diff --git a/OpenMetaverse/Rendering/Rendering.cs b/OpenMetaverse/Rendering/Rendering.cs index 0c033504..872a7296 100644 --- a/OpenMetaverse/Rendering/Rendering.cs +++ b/OpenMetaverse/Rendering/Rendering.cs @@ -116,7 +116,7 @@ public override int GetHashCode() public override bool Equals(object obj) { - return (obj is Vertex) ? this == (Vertex)obj : false; + return (obj is Vertex) && this == (Vertex)obj; } public bool Equals(Vertex other) @@ -246,162 +246,202 @@ public class FacetedMesh : Mesh /// Level of detail /// Resulting decoded FacetedMesh /// True if mesh asset decoding was successful - public static bool TryDecodeFromAsset(Primitive prim, AssetMesh meshAsset, DetailLevel LOD, out FacetedMesh mesh) + public static bool TryDecodeFromAsset(Primitive prim, AssetMesh meshAsset, DetailLevel LOD, out FacetedMesh mesh, + bool skipNormals = false) { mesh = null; try { if (!meshAsset.Decode()) - { return false; - } OSDMap MeshData = meshAsset.MeshData; - mesh = new FacetedMesh(); + mesh = new FacetedMesh + { + Faces = [], + Prim = prim + }; + mesh.Profile.Faces = []; + mesh.Profile.Positions = []; + mesh.Path.Points = []; + + OSD facesOSD = LOD switch + { + DetailLevel.High => MeshData["medium_lod"], + DetailLevel.Medium => MeshData["low_lod"], + DetailLevel.Low => MeshData["lowest_lod"], + _ => MeshData["high_lod"] + }; - mesh.Faces = new List(); - mesh.Prim = prim; - mesh.Profile.Faces = new List(); - mesh.Profile.Positions = new List(); - mesh.Path.Points = new List(); + if (facesOSD is not OSDArray decodedMeshOsdArray) + return false; - OSD facesOSD = null; + return TryDecodeOSDLODBlock(decodedMeshOsdArray, skipNormals, ref mesh); + } + catch (Exception ex) + { + Logger.Log("Failed to decode mesh asset: " + ex.Message, Helpers.LogLevel.Warning); + return false; + } + } - switch (LOD) + public static bool TryDecodeFromBytes(byte[] meshData, DetailLevel LOD, out FacetedMesh mesh, bool skipNormals = false) + { + mesh = null; + + try + { + string layername = LOD switch { - default: - case DetailLevel.Highest: - facesOSD = MeshData["high_lod"]; - break; - - case DetailLevel.High: - facesOSD = MeshData["medium_lod"]; - break; - - case DetailLevel.Medium: - facesOSD = MeshData["low_lod"]; - break; - - case DetailLevel.Low: - facesOSD = MeshData["lowest_lod"]; - break; - } + DetailLevel.High =>"medium_lod", + DetailLevel.Medium => "low_lod", + DetailLevel.Low => "lowest_lod", + _ => "high_lod" + }; + + OSD facesOSD = AssetMesh.DecodeBlock(meshData, layername); if (facesOSD is not OSDArray decodedMeshOsdArray) return false; - for (int faceNr = 0; faceNr < decodedMeshOsdArray.Count; faceNr++) + mesh = new FacetedMesh { - if(decodedMeshOsdArray[faceNr] is not OSDMap subMeshMap) - continue; - - // Decode each individual face + Faces = [] + }; - Face oface = new Face(); - oface.ID = faceNr; - oface.Vertices = new List(); - oface.Indices = new List(); - oface.TextureFace = prim.Textures.GetFace((uint)faceNr); - - Vector3 posMax; - Vector3 posMin; + return TryDecodeOSDLODBlock(decodedMeshOsdArray, skipNormals, ref mesh); + } - // If PositionDomain is not specified, the default is from -0.5 to 0.5 - if (subMeshMap.TryGetValue("PositionDomain", out OSD osdpd) && osdpd is OSDMap mappd) - { - posMax = mappd["Max"]; - posMin = mappd["Min"]; - } - else - { - posMax = new Vector3(0.5f, 0.5f, 0.5f); - posMin = new Vector3(-0.5f, -0.5f, -0.5f); - } + catch (Exception ex) + { + Logger.Log("Failed to decode mesh bytes: " + ex.Message, Helpers.LogLevel.Warning); + return false; + } + } - // Vertex positions - byte[] posBytes = subMeshMap["Position"]; + public static bool TryDecodeOSDLODBlock(OSDArray LODBlockOSDArray, bool skipNormals, ref FacetedMesh mesh) + { + const float ONE_OVER_U16_MAX = 1.0f / ushort.MaxValue; - // Normals - byte[] norBytes = null; - if (subMeshMap.TryGetValue("Normal", out OSD osdNormal)) - { - norBytes = osdNormal; - } + for (int faceNr = 0; faceNr < LODBlockOSDArray.Count; faceNr++) + { + if(LODBlockOSDArray[faceNr] is not OSDMap subMeshMap) + continue; - // UV texture map - Vector2 texPosMax = Vector2.Zero; - Vector2 texPosMin = Vector2.Zero; - byte[] texBytes = null; - if (subMeshMap.TryGetValue("TexCoord0", out OSD osdtcord0)) - { - texBytes = osdtcord0; - texPosMax = ((OSDMap)subMeshMap["TexCoord0Domain"])["Max"]; - texPosMin = ((OSDMap)subMeshMap["TexCoord0Domain"])["Min"]; - } + // Decode each individual face + Face oface = new() + { + ID = faceNr, + Vertices = [], + Indices = [], + }; + + if(subMeshMap.ContainsKey("NoGeometry")) + continue; + + // Vertex positions + if(!subMeshMap.TryGetBinary("Position", out byte[] posBytes)) + continue; + + Vector3 posMin; + Vector3 posRange; + // If PositionDomain is not specified, the default is from -0.5 to 0.5 + if (subMeshMap.TryGetOSDMap("PositionDomain", out OSDMap mappd)) + { + posMin = mappd["Min"]; + posRange = mappd["Max"] - posMin; + } + else + { + posMin = new Vector3(-0.5f, -0.5f, -0.5f); + posRange = new Vector3(1.0f, 1.0f, 1.0f); + } - // Extract the vertex position data - // If present normals and texture coordinates too - for (int i = 0; i < posBytes.Length; i += 6) - { - ushort uX = Utils.BytesToUInt16(posBytes, i); - ushort uY = Utils.BytesToUInt16(posBytes, i + 2); - ushort uZ = Utils.BytesToUInt16(posBytes, i + 4); + // Normals + if(!skipNormals && subMeshMap.TryGetBinary("Normal", out byte[] norBytes)) + { + if(norBytes.Length != posBytes.Length) + norBytes = null; + } + else + norBytes = null; - Vertex vx = new Vertex(); + // UV texture map + Vector2 texUVRange; + Vector2 texUVMin; + if (subMeshMap.TryGetBinary("TexCoord0", out byte[] texUVBytes)) + { + if(texUVBytes.Length * 3 != posBytes.Length * 2) + texUVBytes = null; + OSDMap UVdomain = (OSDMap)subMeshMap["TexCoord0Domain"]; + texUVMin = UVdomain["Min"]; + texUVRange = UVdomain["Max"] - texUVMin; + } + else + { + texUVMin = Vector2.Zero; + texUVRange = Vector2.Zero; + } - vx.Position = new Vector3( - Utils.UInt16ToFloat(uX, posMin.X, posMax.X), - Utils.UInt16ToFloat(uY, posMin.Y, posMax.Y), - Utils.UInt16ToFloat(uZ, posMin.Z, posMax.Z)); + posRange *= ONE_OVER_U16_MAX; + float normRange = 2f * ONE_OVER_U16_MAX; + texUVRange *= ONE_OVER_U16_MAX; - if (norBytes is not null && norBytes.Length >= i + 4) - { - ushort nX = Utils.BytesToUInt16(norBytes, i); - ushort nY = Utils.BytesToUInt16(norBytes, i + 2); - ushort nZ = Utils.BytesToUInt16(norBytes, i + 4); - - vx.Normal = new Vector3( - Utils.UInt16ToFloat(nX, posMin.X, posMax.X), - Utils.UInt16ToFloat(nY, posMin.Y, posMax.Y), - Utils.UInt16ToFloat(nZ, posMin.Z, posMax.Z)); - } + // Extract the vertex position data + // If present normals and texture coordinates too - var vertexIndexOffset = oface.Vertices.Count * 4; + int vertexUVOffset = 0; + for (int i = 0; i < posBytes.Length; i += 6) + { + Vertex vx = new(); - if (texBytes is not null && texBytes.Length >= vertexIndexOffset + 4) - { - ushort tX = Utils.BytesToUInt16(texBytes, vertexIndexOffset); - ushort tY = Utils.BytesToUInt16(texBytes, vertexIndexOffset + 2); + ushort uX = Utils.BytesToUInt16(posBytes, i); + ushort uY = Utils.BytesToUInt16(posBytes, i + 2); + ushort uZ = Utils.BytesToUInt16(posBytes, i + 4); - vx.TexCoord = new Vector2( - Utils.UInt16ToFloat(tX, texPosMin.X, texPosMax.X), - Utils.UInt16ToFloat(tY, texPosMin.Y, texPosMax.Y)); - } + vx.Position = new Vector3( + uX * posRange.X + posMin.X, + uY * posRange.Y + posMin.Y, + uZ * posRange.Z + posMin.Z ); - oface.Vertices.Add(vx); + if (norBytes is not null) + { + ushort nX = Utils.BytesToUInt16(norBytes, i); + ushort nY = Utils.BytesToUInt16(norBytes, i + 2); + ushort nZ = Utils.BytesToUInt16(norBytes, i + 4); + + vx.Normal = new Vector3( + nX * normRange - 1.0f, + nY * normRange - 1.0f, + nZ * normRange - 1.0f); } - byte[] triangleBytes = subMeshMap["TriangleList"]; - for (int i = 0; i < triangleBytes.Length; i += 6) + if (texUVBytes is not null) { - oface.Indices.Add(Utils.BytesToUInt16(triangleBytes, i)); - oface.Indices.Add(Utils.BytesToUInt16(triangleBytes, i + 2)); - oface.Indices.Add(Utils.BytesToUInt16(triangleBytes, i + 4)); + ushort tX = Utils.BytesToUInt16(texUVBytes, vertexUVOffset); vertexUVOffset += 2; + ushort tY = Utils.BytesToUInt16(texUVBytes, vertexUVOffset); vertexUVOffset += 2; + + vx.TexCoord = new Vector2( + tX * texUVRange.X + texUVMin.X, + tY * texUVRange.Y + texUVMin.Y); } - mesh.Faces.Add(oface); + oface.Vertices.Add(vx); } - } - catch (Exception ex) - { - Logger.Log("Failed to decode mesh asset: " + ex.Message, Helpers.LogLevel.Warning); - return false; - } + byte[] triangleBytes = subMeshMap["TriangleList"]; + for (int i = 0; i < triangleBytes.Length; i += 6) + { + oface.Indices.Add(Utils.BytesToUInt16(triangleBytes, i)); + oface.Indices.Add(Utils.BytesToUInt16(triangleBytes, i + 2)); + oface.Indices.Add(Utils.BytesToUInt16(triangleBytes, i + 4)); + } - return true; + mesh.Faces.Add(oface); + } + return true; } } @@ -416,18 +456,18 @@ public SimpleMesh() public SimpleMesh(SimpleMesh mesh) { - this.Indices = new List(mesh.Indices); - this.Path.Open = mesh.Path.Open; - this.Path.Points = new List(mesh.Path.Points); - this.Prim = mesh.Prim; - this.Profile.Concave = mesh.Profile.Concave; - this.Profile.Faces = new List(mesh.Profile.Faces); - this.Profile.MaxX = mesh.Profile.MaxX; - this.Profile.MinX = mesh.Profile.MinX; - this.Profile.Open = mesh.Profile.Open; - this.Profile.Positions = new List(mesh.Profile.Positions); - this.Profile.TotalOutsidePoints = mesh.Profile.TotalOutsidePoints; - this.Vertices = new List(mesh.Vertices); + Indices = new List(mesh.Indices); + Path.Open = mesh.Path.Open; + Path.Points = new List(mesh.Path.Points); + Prim = mesh.Prim; + Profile.Concave = mesh.Profile.Concave; + Profile.Faces = new List(mesh.Profile.Faces); + Profile.MaxX = mesh.Profile.MaxX; + Profile.MinX = mesh.Profile.MinX; + Profile.Open = mesh.Profile.Open; + Profile.Positions = new List(mesh.Profile.Positions); + Profile.TotalOutsidePoints = mesh.Profile.TotalOutsidePoints; + Vertices = new List(mesh.Vertices); } } diff --git a/OpenMetaverseTypes/Quaternion.cs b/OpenMetaverseTypes/Quaternion.cs index 1b96c248..4b4c2304 100644 --- a/OpenMetaverseTypes/Quaternion.cs +++ b/OpenMetaverseTypes/Quaternion.cs @@ -102,8 +102,7 @@ public Quaternion(float x, float y, float z) [MethodImpl(MethodImplOptions.AggressiveInlining)] public Quaternion(byte[] byteArray, int pos, bool normalized) { - X = Y = Z = 0; - W = 1; + Unsafe.SkipInit(out this); FromBytes(byteArray, pos, normalized); } @@ -114,8 +113,22 @@ public Quaternion(Quaternion q) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Quaternion(Vector128 q) : this() + public Quaternion(ref readonly Quaternion q) { + this = q; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Quaternion(Vector128 q) + { + Unsafe.SkipInit(out this); + Unsafe.As>(ref this) = q; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Quaternion(ref readonly Vector128 q) + { + Unsafe.SkipInit(out this); Unsafe.As>(ref this) = q; } @@ -219,11 +232,11 @@ public readonly bool IsIdentityOrZero() } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public readonly unsafe float Length() + public unsafe float Length() { if (Sse41.IsSupported) { - Vector128 q = Unsafe.As>(ref Unsafe.AsRef(this)); + Vector128 q = Vector128.LoadUnsafe(ref X); q = Sse41.DotProduct(q, q, 0xf1); return MathF.Sqrt(q.ToScalar()); } @@ -232,11 +245,11 @@ public readonly unsafe float Length() } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public readonly unsafe float LengthSquared() + public unsafe readonly float LengthSquared() { if (Sse41.IsSupported) { - Vector128 q = Unsafe.As>(ref Unsafe.AsRef(this)); + Vector128 q = Vector128.LoadUnsafe(in X); q = Sse41.DotProduct(q, q, 0xf1); return q.ToScalar(); } @@ -252,15 +265,13 @@ public unsafe void Normalize() { if (Sse41.IsSupported) { - Vector128 q = Unsafe.As>(ref Unsafe.AsRef(this)); + Vector128 q = Vector128.LoadUnsafe(ref X); Vector128 d = Sse41.DotProduct(q, q, 0xff); float m = d.ToScalar(); if (m > 1e-6f) { d = Sse.Sqrt(d); q = Sse.Divide(q, d); - //d = Sse.ReciprocalSqrt(d); - //q = Sse.Multiply(q, d); Unsafe.As>(ref this) = q; return; } @@ -317,46 +328,45 @@ public void Invert() } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public readonly float Dot(Quaternion q2) + public readonly float Dot(ref readonly Quaternion q2) { if (Sse41.IsSupported) { - Vector128 q = Unsafe.As>(ref Unsafe.AsRef(this)); - Vector128 d = Unsafe.As>(ref q2); - d = Sse41.DotProduct(q, d, 0xf1); - return d.ToScalar(); + Vector128 q = Vector128.LoadUnsafe(in X); + Vector128 d = Vector128.LoadUnsafe(in q2.X); + return Sse41.DotProduct(q, d, 0xf1).ToScalar(); } return (X * q2.X) + (Y * q2.Y) + (Z * q2.Z) + (W * q2.W); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Add(in Quaternion quaternion2) + public void Add(ref readonly Quaternion q2) { if (Sse41.IsSupported) { - Vector128 q = Unsafe.As>(ref Unsafe.AsRef(this)); - Vector128 d = Unsafe.As>(ref Unsafe.AsRef(quaternion2)); + Vector128 q = Vector128.LoadUnsafe(in X); + Vector128 d = Vector128.LoadUnsafe(in q2.X); d = Sse.Add(q, d); - Unsafe.As>(ref Unsafe.AsRef(this)) = d; + Unsafe.As>(ref this) = d; } else { - X += quaternion2.X; - Y += quaternion2.Y; - Z += quaternion2.Z; - W += quaternion2.W; + X += q2.X; + Y += q2.Y; + Z += q2.Z; + W += q2.W; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Sub(in Quaternion quaternion2) + public void Sub(ref readonly Quaternion quaternion2) { if (Sse41.IsSupported) { - Vector128 q = Unsafe.As>(ref Unsafe.AsRef(this)); - Vector128 d = Unsafe.As>(ref Unsafe.AsRef(quaternion2)); + Vector128 q = Vector128.LoadUnsafe(in X); + Vector128 d = Vector128.LoadUnsafe(in quaternion2.X); d = Sse.Subtract(q, d); - Unsafe.As>(ref Unsafe.AsRef(this)) = d; + Unsafe.As>(ref this) = d; } else { @@ -670,14 +680,14 @@ public readonly void GetAxisAngle(out Vector3 axis, out float angle) #region Static Methods [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Quaternion Add(in Quaternion quaternion1, in Quaternion quaternion2) + public static Quaternion Add(ref readonly Quaternion quaternion1, ref readonly Quaternion quaternion2) { if (Sse.IsSupported) { - Vector128 a = Unsafe.As>(ref Unsafe.AsRef(quaternion1)); - Vector128 b = Unsafe.As>(ref Unsafe.AsRef(quaternion2)); + Vector128 a = Vector128.LoadUnsafe(in quaternion1.X); + Vector128 b = Vector128.LoadUnsafe(in quaternion2.X); a = Sse.Add(a, b); - return new Quaternion(a); + return new Quaternion(ref a); } return new Quaternion( @@ -698,7 +708,7 @@ public static Quaternion Conjugate(in Quaternion quaternion) Vector128 d = Unsafe.As>(ref Unsafe.AsRef(quaternion)); Vector128 Mask = Vector128.Create(0x80000000, 0x80000000, 0x80000000, 0).AsSingle(); d = Sse.Xor(d, Mask); - return new Quaternion(d); + return new Quaternion(ref d); } return new Quaternion(-quaternion.X, -quaternion.Y, -quaternion.Z, quaternion.W); } @@ -1029,8 +1039,21 @@ public static Quaternion Negate(Quaternion quaternion) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Quaternion Normalize(Quaternion q) + public static Quaternion Normalize(ref readonly Quaternion q) { + if(Sse41.IsSupported) + { + Vector128 t = Vector128.LoadUnsafe(in q.X); + Vector128 d = Sse41.DotProduct(t, t, 0xff); + float m = d.ToScalar(); + if (m > 1e-6f) + { + t = Sse.Divide(t, Sse.Sqrt(d)); + return new(ref t); + } + return Identity; + } + float mag = q.LengthSquared(); if (mag > 1e-6f) { @@ -1041,7 +1064,7 @@ public static Quaternion Normalize(Quaternion q) q.Z * oomag, q.W * oomag); } - return Quaternion.Identity; + return Identity; } [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/OpenMetaverseTypes/Vector3.cs b/OpenMetaverseTypes/Vector3.cs index 0c0c5d48..a49bfb21 100644 --- a/OpenMetaverseTypes/Vector3.cs +++ b/OpenMetaverseTypes/Vector3.cs @@ -44,7 +44,7 @@ public struct Vector3 : IComparable, IEquatable { /// x value public float X; - /// Y value + /// Y value public float Y; /// Z value public float Z; @@ -54,6 +54,7 @@ public struct Vector3 : IComparable, IEquatable [MethodImpl(MethodImplOptions.AggressiveInlining)] public Vector3(float x, float y, float z) { + Unsafe.SkipInit(out this); X = x; Y = y; Z = z; @@ -62,6 +63,7 @@ public Vector3(float x, float y, float z) [MethodImpl(MethodImplOptions.AggressiveInlining)] public Vector3(float value) { + Unsafe.SkipInit(out this); X = value; Y = value; Z = value; @@ -70,6 +72,7 @@ public Vector3(float value) [MethodImpl(MethodImplOptions.AggressiveInlining)] public Vector3(Vector2 value, float z) { + Unsafe.SkipInit(out this); X = value.X; Y = value.Y; Z = z; @@ -78,6 +81,7 @@ public Vector3(Vector2 value, float z) [MethodImpl(MethodImplOptions.AggressiveInlining)] public Vector3(Vector3d vector) { + Unsafe.SkipInit(out this); X = (float)vector.X; Y = (float)vector.Y; Z = (float)vector.Z; @@ -86,20 +90,18 @@ public Vector3(Vector3d vector) [MethodImpl(MethodImplOptions.AggressiveInlining)] public Vector3(Vector3 vector) { + Unsafe.SkipInit(out this); X = vector.X; Y = vector.Y; Z = vector.Z; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Vector3(Vector128 v) + public unsafe Vector3(ref readonly Vector128 v) { Unsafe.SkipInit(out this); - unsafe - { - Sse2.StoreScalar((double*)Unsafe.AsPointer(ref X), v.AsDouble()); - Sse2.StoreScalar((float*)Unsafe.AsPointer(ref Z), Sse2.Shuffle(v.AsInt32(), 0x02).AsSingle()); - } + Unsafe.As(ref X) = v.AsDouble().ToScalar(); + Z = Sse41.Extract(v, 0x02); } /// @@ -192,31 +194,76 @@ public void Clamp(float min, float max) [MethodImpl(MethodImplOptions.AggressiveInlining)] public readonly float Length() { - return MathF.Sqrt(X * X + Y * Y + Z * Z); + if(Sse41.IsSupported) + { + Vector128 ma = Vector128.LoadUnsafe(in X); + ma = Sse41.DotProduct(ma, ma, 0x71); + return MathF.Sqrt(ma.ToScalar()); + } + else + return MathF.Sqrt(X * X + Y * Y + Z * Z); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public readonly float LengthSquared() { - return (X * X + Y * Y + Z * Z); + if(Sse41.IsSupported) + { + unsafe + { + Vector128 ma = Sse2.LoadScalarVector128((double *)Unsafe.AsPointer(ref Unsafe.AsRef(in X))).AsSingle(); + ma = Sse41.Insert(ma.AsUInt32(),Unsafe.As(ref Unsafe.AsRef(in Z)),0x02).AsSingle(); + ma = Sse41.DotProduct(ma, ma, 0x71); + return ma.ToScalar(); + } + } + else + return (X * X + Y * Y + Z * Z); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Normalize() { - float factor = X * X + Y * Y + Z * Z; - if (factor > 1e-6f) - { - factor = 1f / MathF.Sqrt(factor); - X *= factor; - Y *= factor; - Z *= factor; - } - else + if(Sse41.IsSupported) { + unsafe + { + Vector128 ma = Sse2.LoadScalarVector128((double*)Unsafe.AsPointer(ref Unsafe.AsRef(in X))).AsSingle(); + ma = Sse41.Insert(ma.AsUInt32(),Unsafe.As(ref Unsafe.AsRef(in Z)),0x02).AsSingle(); + + Vector128 mb = Sse41.DotProduct(ma, ma, 0x7f); + if(mb.ToScalar() > 1e-6f) + { + mb = Sse.Sqrt(mb); + ma = Sse.Divide(ma, mb); + + Unsafe.As(ref X) = ma.AsDouble().ToScalar(); + Z = Sse41.Extract(ma,0x02); + return; + } + } + X = 0f; Y = 0f; Z = 0f; + return; + } + else + { + float factor = X * X + Y * Y + Z * Z; + if (factor > 1e-6f) + { + factor = 1f / MathF.Sqrt(factor); + X *= factor; + Y *= factor; + Z *= factor; + } + else + { + X = 0f; + Y = 0f; + Z = 0f; + } } } @@ -759,15 +806,43 @@ public static Vector3 Negate(Vector3 value) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector3 Normalize(Vector3 value) + public static Vector3 Normalize(float x, float y, float z) { - float factor = value.LengthSquared(); - if (factor > 1e-6f) + Vector3 tmp = new(x, y, z); + tmp.Normalize(); + return tmp; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector3 Normalize(ref readonly Vector3 value) + { + if(Sse41.IsSupported) + { + unsafe + { + Vector128 ma = Sse2.LoadScalarVector128((double *)Unsafe.AsPointer(ref Unsafe.AsRef(in value.X))).AsSingle(); + ma = Sse41.Insert(ma.AsUInt32(),Unsafe.As(ref Unsafe.AsRef(in value.Z)),0x02).AsSingle(); + + Vector128 mb = Sse41.DotProduct(ma, ma, 0x7f); + if(mb.ToScalar() > 1e-6f) + { + mb = Sse.Sqrt(mb); + ma = Sse.Divide(ma, mb); + return new(in ma); + } + return new(); + } + } + else { - factor = 1f / MathF.Sqrt(factor); - return value * factor; + float factor = value.LengthSquared(); + if (factor > 1e-6f) + { + factor = 1f / MathF.Sqrt(factor); + return value * factor; + } + return new(); } - return new Vector3(); } /// @@ -1240,7 +1315,7 @@ public Vector3 TransformPositionOffset(ref Quaternion ParentRot, ref Vector3 Par [MethodImpl(MethodImplOptions.AggressiveInlining)] public Vector3 TransformPositionOffset(ref Matrix3x3 ParentRot, ref Vector3 ParentPos) { - if (Sse.IsSupported) + if (Sse41.IsSupported) { unsafe { @@ -1295,7 +1370,7 @@ public vtmp(Vector128 v) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 TransformPositionOffset(ref Matrix3x3 ParentRot, ref Vector3 ParentPos, ref Vector3 Partoffset) { - if (Sse.IsSupported) + if (Sse41.IsSupported) { unsafe { @@ -1316,7 +1391,7 @@ public static Vector3 TransformPositionOffset(ref Matrix3x3 ParentRot, ref Vecto [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 TransformPositionOffset(Matrix3x3 ParentRot, Vector3 ParentPos, Vector3 Partoffset) { - if (Sse.IsSupported) + if (Sse41.IsSupported) { unsafe { diff --git a/OpenMetaverseTypes/Vector4.cs b/OpenMetaverseTypes/Vector4.cs index 68b415bf..ab68cf8e 100644 --- a/OpenMetaverseTypes/Vector4.cs +++ b/OpenMetaverseTypes/Vector4.cs @@ -29,6 +29,8 @@ using System.Runtime.InteropServices; using System.Globalization; using System.Text; +using System.Runtime.Intrinsics.X86; +using System.Runtime.Intrinsics; namespace OpenMetaverse { @@ -170,7 +172,14 @@ public float Length() [MethodImpl(MethodImplOptions.AggressiveInlining)] public float LengthSquared() { - return (X * X) + (Y * Y) + (Z * Z) + (W * W); + if(Sse41.IsSupported) + { + Vector128 ma = Vector128.LoadUnsafe(ref X); + ma = Sse41.DotProduct(ma, ma, 0xf1); + return ma.ToScalar(); + } + else + return (X * X) + (Y * Y) + (Z * Z) + (W * W); } public void Normalize() diff --git a/PrimMesher/ObjMesh.cs b/PrimMesher/ObjMesh.cs index 6843d39c..12f3174e 100644 --- a/PrimMesher/ObjMesh.cs +++ b/PrimMesher/ObjMesh.cs @@ -26,30 +26,29 @@ */ using System; -using System.Collections; using System.Collections.Generic; using System.Globalization; using System.IO; -using System.Text; using System.Text.RegularExpressions; +using OpenMetaverse; namespace PrimMesher { public class ObjMesh { - List coords = new List(); - List normals = new List(); - List uvs = new List(); + List coords = []; + List normals = []; + List uvs = []; public string meshName = string.Empty; - public List> viewerVertices = new List>(); - public List> viewerPolygons = new List>(); + public List> viewerVertices = []; + public List> viewerPolygons = []; - List faceVertices = new List(); - List facePolygons = new List(); + List faceVertices = []; + List facePolygons = []; public int numPrimFaces; - Dictionary viewerVertexLookup = new Dictionary(); + Dictionary viewerVertexLookup = new(); public ObjMesh(string path) { @@ -82,9 +81,9 @@ private void ProcessStream(StreamReader s) public VertexIndexer GetVertexIndexer() { VertexIndexer vi = new VertexIndexer(); - vi.numPrimFaces = this.numPrimFaces; - vi.viewerPolygons = this.viewerPolygons; - vi.viewerVertices = this.viewerVertices; + vi.numPrimFaces = numPrimFaces; + vi.viewerPolygons = viewerPolygons; + vi.viewerVertices = viewerVertices; return vi; } @@ -153,11 +152,11 @@ private void ProcessTokens(string[] tokens) int hash = hashInts(positionIndex, texCoordIndex, normalIndex); - if (viewerVertexLookup.ContainsKey(hash)) - vertIndices[vertexIndex - 1] = viewerVertexLookup[hash]; + if (viewerVertexLookup.TryGetValue(hash, out int hv)) + vertIndices[vertexIndex - 1] = hv; else { - ViewerVertex vv = new ViewerVertex(); + ViewerVertex vv = new(); vv.v = coords[positionIndex]; if (normalIndex > -1) vv.n = normals[normalIndex]; @@ -206,9 +205,9 @@ private UVCoord ParseUVCoord(string[] tokens) float.Parse(tokens[1], CultureInfo.InvariantCulture)); } - private Coord ParseCoord(string[] tokens) + private Vector3 ParseCoord(string[] tokens) { - return new Coord( + return new Vector3( float.Parse(tokens[1], CultureInfo.InvariantCulture), float.Parse(tokens[2], CultureInfo.InvariantCulture), float.Parse(tokens[3], CultureInfo.InvariantCulture)); @@ -216,7 +215,7 @@ private Coord ParseCoord(string[] tokens) private int hashInts(int i1, int i2, int i3) { - return (i1.ToString() + " " + i2.ToString() + " " + i3.ToString()).GetHashCode(); + return HashCode.Combine(i1, i2, i3); } } } diff --git a/PrimMesher/PrimMesher.cs b/PrimMesher/PrimMesher.cs index c6892ce0..136d1220 100644 --- a/PrimMesher/PrimMesher.cs +++ b/PrimMesher/PrimMesher.cs @@ -25,229 +25,30 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +using OpenMetaverse; using System; using System.Collections.Generic; using System.IO; +using System.Runtime.CompilerServices; namespace PrimMesher { - public struct Quat + public struct UVCoord(float u, float v) { - /// X value - public float X; - /// Y value - public float Y; - /// Z value - public float Z; - /// W value - public float W; - - public Quat(float x, float y, float z, float w) - { - X = x; - Y = y; - Z = z; - W = w; - } - - public Quat(Coord axis, float angle) - { - axis = axis.Normalize(); - - angle *= 0.5f; - float c = (float)Math.Cos(angle); - float s = (float)Math.Sin(angle); - - X = axis.X * s; - Y = axis.Y * s; - Z = axis.Z * s; - W = c; - - Normalize(); - } - - public float Length() - { - return (float)Math.Sqrt(X * X + Y * Y + Z * Z + W * W); - } - - public Quat Normalize() - { - const float MAG_THRESHOLD = 0.0000001f; - float mag = Length(); - - // Catch very small rounding errors when normalizing - if (mag > MAG_THRESHOLD) - { - float oomag = 1f / mag; - X *= oomag; - Y *= oomag; - Z *= oomag; - W *= oomag; - } - else - { - X = 0f; - Y = 0f; - Z = 0f; - W = 1f; - } - - return this; - } - - public static Quat operator *(Quat q1, Quat q2) - { - float x = q1.W * q2.X + q1.X * q2.W + q1.Y * q2.Z - q1.Z * q2.Y; - float y = q1.W * q2.Y - q1.X * q2.Z + q1.Y * q2.W + q1.Z * q2.X; - float z = q1.W * q2.Z + q1.X * q2.Y - q1.Y * q2.X + q1.Z * q2.W; - float w = q1.W * q2.W - q1.X * q2.X - q1.Y * q2.Y - q1.Z * q2.Z; - return new Quat(x, y, z, w); - } - - public override string ToString() - { - return "< X: " + this.X.ToString() + ", Y: " + this.Y.ToString() + ", Z: " + this.Z.ToString() + ", W: " + this.W.ToString() + ">"; - } - } - - public struct Coord - { - public float X; - public float Y; - public float Z; - - public Coord(float x, float y, float z) - { - this.X = x; - this.Y = y; - this.Z = z; - } - - public float Length() - { - return (float)Math.Sqrt(this.X * this.X + this.Y * this.Y + this.Z * this.Z); - } - - public Coord Invert() - { - this.X = -this.X; - this.Y = -this.Y; - this.Z = -this.Z; - - return this; - } - - public Coord Normalize() - { - const float MAG_THRESHOLD = 0.0000001f; - float mag = Length(); - - // Catch very small rounding errors when normalizing - if (mag > MAG_THRESHOLD) - { - float oomag = 1.0f / mag; - this.X *= oomag; - this.Y *= oomag; - this.Z *= oomag; - } - else - { - this.X = 0.0f; - this.Y = 0.0f; - this.Z = 0.0f; - } - - return this; - } - - public override string ToString() - { - return this.X.ToString() + " " + this.Y.ToString() + " " + this.Z.ToString(); - } - - public static Coord Cross(Coord c1, Coord c2) - { - return new Coord( - c1.Y * c2.Z - c2.Y * c1.Z, - c1.Z * c2.X - c2.Z * c1.X, - c1.X * c2.Y - c2.X * c1.Y - ); - } - - public static Coord operator +(Coord v, Coord a) - { - return new Coord(v.X + a.X, v.Y + a.Y, v.Z + a.Z); - } - - public static Coord operator *(Coord v, Coord m) - { - return new Coord(v.X * m.X, v.Y * m.Y, v.Z * m.Z); - } - - public static Coord operator *(Coord v, Quat q) - { - // From http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/transforms/ - - Coord c2 = new Coord(0.0f, 0.0f, 0.0f); - - c2.X = q.W * q.W * v.X + - 2f * q.Y * q.W * v.Z - - 2f * q.Z * q.W * v.Y + - q.X * q.X * v.X + - 2f * q.Y * q.X * v.Y + - 2f * q.Z * q.X * v.Z - - q.Z * q.Z * v.X - - q.Y * q.Y * v.X; - - c2.Y = - 2f * q.X * q.Y * v.X + - q.Y * q.Y * v.Y + - 2f * q.Z * q.Y * v.Z + - 2f * q.W * q.Z * v.X - - q.Z * q.Z * v.Y + - q.W * q.W * v.Y - - 2f * q.X * q.W * v.Z - - q.X * q.X * v.Y; - - c2.Z = - 2f * q.X * q.Z * v.X + - 2f * q.Y * q.Z * v.Y + - q.Z * q.Z * v.Z - - 2f * q.W * q.Y * v.X - - q.Y * q.Y * v.Z + - 2f * q.W * q.X * v.Y - - q.X * q.X * v.Z + - q.W * q.W * v.Z; - - return c2; - } - } - - public struct UVCoord - { - public float U; - public float V; - - - public UVCoord(float u, float v) - { - this.U = u; - this.V = v; - } + public float U = u; + public float V = v; + [MethodImpl(MethodImplOptions.AggressiveInlining)] public UVCoord Flip() { - this.U = 1.0f - this.U; - this.V = 1.0f - this.V; + U = 1.0f - U; + V = 1.0f - V; return this; } } public struct Face { - public int primFace; - // vertices public int v1; public int v2; @@ -265,26 +66,21 @@ public struct Face public Face(int v1, int v2, int v3) { - primFace = 0; - this.v1 = v1; this.v2 = v2; this.v3 = v3; - this.n1 = 0; - this.n2 = 0; - this.n3 = 0; - - this.uv1 = 0; - this.uv2 = 0; - this.uv3 = 0; + n1 = 0; + n2 = 0; + n3 = 0; + uv1 = 0; + uv2 = 0; + uv3 = 0; } public Face(int v1, int v2, int v3, int n1, int n2, int n3) { - primFace = 0; - this.v1 = v1; this.v2 = v2; this.v3 = v3; @@ -293,21 +89,38 @@ public Face(int v1, int v2, int v3, int n1, int n2, int n3) this.n2 = n2; this.n3 = n3; - this.uv1 = 0; - this.uv2 = 0; - this.uv3 = 0; + uv1 = 0; + uv2 = 0; + uv3 = 0; } - public Coord SurfaceNormal(List coordList) + public Vector3 SurfaceNormal(List coordList) { - Coord c1 = coordList[this.v1]; - Coord c2 = coordList[this.v2]; - Coord c3 = coordList[this.v3]; + Vector3 c1 = coordList[v1]; + Vector3 c2 = coordList[v2]; + Vector3 c3 = coordList[v3]; - Coord edge1 = new Coord(c2.X - c1.X, c2.Y - c1.Y, c2.Z - c1.Z); - Coord edge2 = new Coord(c3.X - c1.X, c3.Y - c1.Y, c3.Z - c1.Z); + Vector3 edge1 = c2 - c1; + Vector3 edge2 = c3 - c1; + c1 = Vector3.Cross(edge1, edge2); + c1.Normalize(); + return c1; + } - return Coord.Cross(edge1, edge2).Normalize(); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AddVerticesIndexesOffset(int o) + { + v1 += o; + v2 += o; + v3 += o; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AddNormalsIndexesOffset(int o) + { + n1 += o; + n2 += o; + n3 += o; } } @@ -315,17 +128,17 @@ public struct ViewerFace { public int primFaceNumber; - public Coord v1; - public Coord v2; - public Coord v3; + public Vector3 v1; + public Vector3 v2; + public Vector3 v3; public int coordIndex1; public int coordIndex2; public int coordIndex3; - public Coord n1; - public Coord n2; - public Coord n3; + public Vector3 n1; + public Vector3 n2; + public Vector3 n3; public UVCoord uv1; public UVCoord uv2; @@ -335,69 +148,99 @@ public ViewerFace(int primFaceNumber) { this.primFaceNumber = primFaceNumber; - this.v1 = new Coord(); - this.v2 = new Coord(); - this.v3 = new Coord(); - - this.coordIndex1 = this.coordIndex2 = this.coordIndex3 = -1; // -1 means not assigned yet + v1 = new(); + v2 = new(); + v3 = new(); - this.n1 = new Coord(); - this.n2 = new Coord(); - this.n3 = new Coord(); + coordIndex1 = coordIndex2 = coordIndex3 = -1; // -1 means not assigned yet - this.uv1 = new UVCoord(); - this.uv2 = new UVCoord(); - this.uv3 = new UVCoord(); + n1 = new(); + n2 = new(); + n3 = new(); + + uv1 = new(); + uv2 = new(); + uv3 = new(); } public void Scale(float x, float y, float z) { - this.v1.X *= x; - this.v1.Y *= y; - this.v1.Z *= z; + v1.X *= x; + v1.Y *= y; + v1.Z *= z; - this.v2.X *= x; - this.v2.Y *= y; - this.v2.Z *= z; + v2.X *= x; + v2.Y *= y; + v2.Z *= z; - this.v3.X *= x; - this.v3.Y *= y; - this.v3.Z *= z; + v3.X *= x; + v3.Y *= y; + v3.Z *= z; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Scale(Vector3 scale) + { + v1 *= scale; + v2 *= scale; + v3 *= scale; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AddPos(float x, float y, float z) { - this.v1.X += x; - this.v2.X += x; - this.v3.X += x; + v1.X += x; + v2.X += x; + v3.X += x; - this.v1.Y += y; - this.v2.Y += y; - this.v3.Y += y; + v1.Y += y; + v2.Y += y; + v3.Y += y; - this.v1.Z += z; - this.v2.Z += z; - this.v3.Z += z; + v1.Z += z; + v2.Z += z; + v3.Z += z; } - public void AddRot(Quat q) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AddPos(Vector3 v) { - this.v1 *= q; - this.v2 *= q; - this.v3 *= q; + v1 += v; + v2 += v; + v3 += v; + } - this.n1 *= q; - this.n2 *= q; - this.n3 *= q; + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AddRot(Quaternion q) + { + v1 *= q; + v2 *= q; + v3 *= q; + + n1 *= q; + n2 *= q; + n3 *= q; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void CalcSurfaceNormal() { + Vector3 edge1 = v2 - v1; + Vector3 edge2 = v3 - v1; + n1= Vector3.Cross(edge1, edge2); + n1.Normalize(); - Coord edge1 = new Coord(this.v2.X - this.v1.X, this.v2.Y - this.v1.Y, this.v2.Z - this.v1.Z); - Coord edge2 = new Coord(this.v3.X - this.v1.X, this.v3.Y - this.v1.Y, this.v3.Z - this.v1.Z); + n2 = n3 = n1; + } - this.n1 = this.n2 = this.n3 = Coord.Cross(edge1, edge2).Normalize(); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public readonly bool IsValid() + { + return + (MathF.Abs(n1.X) + MathF.Abs(n1.Y) + MathF.Abs(n1.Z) > 0.2f) && + (MathF.Abs(n2.X) + MathF.Abs(n2.Y) + MathF.Abs(n2.Z) > 0.2f) && + (MathF.Abs(n3.X) + MathF.Abs(n3.Y) + MathF.Abs(n3.Z) > 0.2f) + ; } } @@ -407,11 +250,19 @@ internal struct Angle internal float X; internal float Y; - internal Angle(float angle, float x, float y) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal Angle(float _angle, float x, float y) { - this.angle = angle; - this.X = x; - this.Y = y; + angle = _angle; + X = x; + Y = y; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal Angle(float _angle) + { + angle = _angle; + X = MathF.Cos(angle); // cos + Y = MathF.Sin(angle); // sin } } @@ -419,116 +270,162 @@ internal class AngleList { private float iX, iY; // intersection point - private static Angle[] angles3 = + private static readonly Angle[] angles3 = { - new Angle(0.0f, 1.0f, 0.0f), - new Angle(0.33333333333333333f, -0.5f, 0.86602540378443871f), - new Angle(0.66666666666666667f, -0.5f, -0.86602540378443837f), - new Angle(1.0f, 1.0f, 0.0f) + new(0.0f, 1.0f, 0.0f), + new(0.33333333333333333f, -0.5f, 0.86602540378443871f), + new(0.66666666666666667f, -0.5f, -0.86602540378443837f), + new(1.0f, 1.0f, 0.0f) }; - private static Coord[] normals3 = + private static Vector3[] normals3 = { - new Coord(0.25f, 0.4330127019f, 0.0f).Normalize(), - new Coord(-0.5f, 0.0f, 0.0f).Normalize(), - new Coord(0.25f, -0.4330127019f, 0.0f).Normalize(), - new Coord(0.25f, 0.4330127019f, 0.0f).Normalize() + Vector3.Normalize(0.25f, 0.4330127019f, 0.0f), + Vector3.Normalize(-0.5f, 0.0f, 0.0f), + Vector3.Normalize(0.25f, -0.4330127019f, 0.0f), + Vector3.Normalize(0.25f, 0.4330127019f, 0.0f) }; private static Angle[] angles4 = { - new Angle(0.0f, 1.0f, 0.0f), - new Angle(0.25f, 0.0f, 1.0f), - new Angle(0.5f, -1.0f, 0.0f), - new Angle(0.75f, 0.0f, -1.0f), - new Angle(1.0f, 1.0f, 0.0f) + new(0.0f, 1.0f, 0.0f), + new(0.25f, 0.0f, 1.0f), + new(0.5f, -1.0f, 0.0f), + new(0.75f, 0.0f, -1.0f), + new(1.0f, 1.0f, 0.0f) }; - private static Coord[] normals4 = + private static readonly Vector3[] normals4 = { - new Coord(0.5f, 0.5f, 0.0f).Normalize(), - new Coord(-0.5f, 0.5f, 0.0f).Normalize(), - new Coord(-0.5f, -0.5f, 0.0f).Normalize(), - new Coord(0.5f, -0.5f, 0.0f).Normalize(), - new Coord(0.5f, 0.5f, 0.0f).Normalize() + Vector3.Normalize(0.5f, 0.5f, 0.0f), + Vector3.Normalize(-0.5f, 0.5f, 0.0f), + Vector3.Normalize(-0.5f, -0.5f, 0.0f), + Vector3.Normalize(0.5f, -0.5f, 0.0f), + Vector3.Normalize(0.5f, 0.5f, 0.0f) }; - private static Angle[] angles24 = + private static readonly Angle[] angles6 = { - new Angle(0.0f, 1.0f, 0.0f), - new Angle(0.041666666666666664f, 0.96592582628906831f, 0.25881904510252074f), - new Angle(0.083333333333333329f, 0.86602540378443871f, 0.5f), - new Angle(0.125f, 0.70710678118654757f, 0.70710678118654746f), - new Angle(0.16666666666666667f, 0.5f, 0.8660254037844386f), - new Angle(0.20833333333333331f, 0.25881904510252096f, 0.9659258262890682f), - new Angle(0.25f, 0.0f, 1.0f), - new Angle(0.29166666666666663f, -0.25881904510252063f, 0.96592582628906831f), - new Angle(0.33333333333333333f, -0.5f, 0.86602540378443871f), - new Angle(0.375f, -0.70710678118654746f, 0.70710678118654757f), - new Angle(0.41666666666666663f, -0.86602540378443849f, 0.5f), - new Angle(0.45833333333333331f, -0.9659258262890682f, 0.25881904510252102f), - new Angle(0.5f, -1.0f, 0.0f), - new Angle(0.54166666666666663f, -0.96592582628906842f, -0.25881904510252035f), - new Angle(0.58333333333333326f, -0.86602540378443882f, -0.5f), - new Angle(0.62499999999999989f, -0.70710678118654791f, -0.70710678118654713f), - new Angle(0.66666666666666667f, -0.5f, -0.86602540378443837f), - new Angle(0.70833333333333326f, -0.25881904510252152f, -0.96592582628906809f), - new Angle(0.75f, 0.0f, -1.0f), - new Angle(0.79166666666666663f, 0.2588190451025203f, -0.96592582628906842f), - new Angle(0.83333333333333326f, 0.5f, -0.86602540378443904f), - new Angle(0.875f, 0.70710678118654735f, -0.70710678118654768f), - new Angle(0.91666666666666663f, 0.86602540378443837f, -0.5f), - new Angle(0.95833333333333326f, 0.96592582628906809f, -0.25881904510252157f), - new Angle(1.0f, 1.0f, 0.0f) + new(0.0f, 1.0f, 0.0f), + new(0.16666666666666667f, 0.5f, 0.8660254037844386f), + new(0.33333333333333333f, -0.5f, 0.86602540378443871f), + new(0.5f, -1.0f, 0.0f), + new(0.66666666666666667f, -0.5f, -0.86602540378443837f), + new(0.83333333333333326f, 0.5f, -0.86602540378443904f), + new(1.0f, 1.0f, 0.0f) + }; + + private static readonly Angle[] angles12 = + { + new(0.0f, 1.0f, 0.0f), + new(0.083333333333333329f, 0.86602540378443871f, 0.5f), + new(0.16666666666666667f, 0.5f, 0.8660254037844386f), + new(0.25f, 0.0f, 1.0f), + new(0.33333333333333333f, -0.5f, 0.86602540378443871f), + new(0.41666666666666663f, -0.86602540378443849f, 0.5f), + new(0.5f, -1.0f, 0.0f), + new(0.58333333333333326f, -0.86602540378443882f, -0.5f), + new(0.66666666666666667f, -0.5f, -0.86602540378443837f), + new(0.75f, 0.0f, -1.0f), + new(0.83333333333333326f, 0.5f, -0.86602540378443904f), + new(0.91666666666666663f, 0.86602540378443837f, -0.5f), + new(1.0f, 1.0f, 0.0f) }; + private static readonly Angle[] angles24 = + { + new(0.0f, 1.0f, 0.0f), + new(0.041666666666666664f, 0.96592582628906831f, 0.25881904510252074f), + new(0.083333333333333329f, 0.86602540378443871f, 0.5f), + new(0.125f, 0.70710678118654757f, 0.70710678118654746f), + new(0.16666666666666667f, 0.5f, 0.8660254037844386f), + new(0.20833333333333331f, 0.25881904510252096f, 0.9659258262890682f), + new(0.25f, 0.0f, 1.0f), + new(0.29166666666666663f, -0.25881904510252063f, 0.96592582628906831f), + new(0.33333333333333333f, -0.5f, 0.86602540378443871f), + new(0.375f, -0.70710678118654746f, 0.70710678118654757f), + new(0.41666666666666663f, -0.86602540378443849f, 0.5f), + new(0.45833333333333331f, -0.9659258262890682f, 0.25881904510252102f), + new(0.5f, -1.0f, 0.0f), + new(0.54166666666666663f, -0.96592582628906842f, -0.25881904510252035f), + new(0.58333333333333326f, -0.86602540378443882f, -0.5f), + new(0.62499999999999989f, -0.70710678118654791f, -0.70710678118654713f), + new(0.66666666666666667f, -0.5f, -0.86602540378443837f), + new(0.70833333333333326f, -0.25881904510252152f, -0.96592582628906809f), + new(0.75f, 0.0f, -1.0f), + new(0.79166666666666663f, 0.2588190451025203f, -0.96592582628906842f), + new(0.83333333333333326f, 0.5f, -0.86602540378443904f), + new(0.875f, 0.70710678118654735f, -0.70710678118654768f), + new(0.91666666666666663f, 0.86602540378443837f, -0.5f), + new(0.95833333333333326f, 0.96592582628906809f, -0.25881904510252157f), + new(1.0f, 1.0f, 0.0f) + }; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] private Angle interpolatePoints(float newPoint, Angle p1, Angle p2) { float m = (newPoint - p1.angle) / (p2.angle - p1.angle); - return new Angle(newPoint, p1.X + m * (p2.X - p1.X), p1.Y + m * (p2.Y - p1.Y)); + return new(newPoint, p1.X + m * (p2.X - p1.X), p1.Y + m * (p2.Y - p1.Y)); } - private void intersection(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4) - { // ref: http://local.wasp.uwa.edu.au/~pbourke/geometry/lineline2d/ - double denom = (y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1); - double uaNumerator = (x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private void intersection(float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4) + { // ref: https://paulbourke.net/geometry/pointlineplane/ + float denom = (y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1); + if (denom != 0.0f) + { + float uaNumerator = (x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3); + float ua = uaNumerator / denom; + iX = x1 + ua * (x2 - x1); + iY = y1 + ua * (y2 - y1); + } + } - if (denom != 0.0) + // if p3 is origin: + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private void intersection(float x1, float y1, float x2, float y2, float x4, float y4) + { // https://paulbourke.net/geometry/pointlineplane/ + float denom = y4 * (x2 - x1) - x4 * (y2 - y1); + if (denom != 0.0f) { - double ua = uaNumerator / denom; - iX = (float)(x1 + ua * (x2 - x1)); - iY = (float)(y1 + ua * (y2 - y1)); + float uaNumerator = x4 * y1 - y4 * x1; + float ua = uaNumerator / denom; + iX = x1 + ua * (x2 - x1); + iY = y1 + ua * (y2 - y1); } } internal List angles; - internal List normals; + internal List normals; internal void makeAngles(int sides, float startAngle, float stopAngle) { angles = new List(); - normals = new List(); + normals = new List(); - double twoPi = System.Math.PI * 2.0; - float twoPiInv = 1.0f / (float)twoPi; + const float twoPi = MathF.PI * 2.0f; + const float twoPiInv = 1.0f / (float)twoPi; if (sides < 1) throw new Exception("number of sides not greater than zero"); if (stopAngle <= startAngle) throw new Exception("stopAngle not greater than startAngle"); - if ((sides == 3 || sides == 4 || sides == 24)) + Angle[] sourceAngles = sides switch + { + 3 => angles3, + 4 => angles4, + 6 => angles6, + 12 => angles12, + 24 => angles24, + _ => null + }; + + if (sourceAngles != null) { startAngle *= twoPiInv; stopAngle *= twoPiInv; - Angle[] sourceAngles; - if (sides == 3) - sourceAngles = angles3; - else if (sides == 4) - sourceAngles = angles4; - else sourceAngles = angles24; - int startAngleIndex = (int)(startAngle * sides); int endAngleIndex = sourceAngles.Length - 1; if (stopAngle < 1.0f) @@ -536,7 +433,7 @@ internal void makeAngles(int sides, float startAngle, float stopAngle) if (endAngleIndex == startAngleIndex) endAngleIndex++; - for (int angleIndex = startAngleIndex; angleIndex < endAngleIndex + 1; angleIndex++) + for (int angleIndex = startAngleIndex; angleIndex <= endAngleIndex; angleIndex++) { angles.Add(sourceAngles[angleIndex]); if (sides == 3) @@ -559,7 +456,7 @@ internal void makeAngles(int sides, float startAngle, float stopAngle) double stepSize = twoPi / sides; int startStep = (int)(startAngle / stepSize); - double angle = stepSize * startStep; + double angle = (float)(stepSize * startStep); int step = startStep; double stopAngleTest = stopAngle; if (stopAngle < twoPi) @@ -573,10 +470,7 @@ internal void makeAngles(int sides, float startAngle, float stopAngle) while (angle <= stopAngleTest) { - Angle newAngle; - newAngle.angle = (float)angle; - newAngle.X = (float)System.Math.Cos(angle); - newAngle.Y = (float)System.Math.Sin(angle); + Angle newAngle = new((float)angle); angles.Add(newAngle); step += 1; angle = stepSize * step; @@ -584,23 +478,16 @@ internal void makeAngles(int sides, float startAngle, float stopAngle) if (startAngle > angles[0].angle) { - Angle newAngle; - intersection(angles[0].X, angles[0].Y, angles[1].X, angles[1].Y, 0.0f, 0.0f, (float)Math.Cos(startAngle), (float)Math.Sin(startAngle)); - newAngle.angle = startAngle; - newAngle.X = iX; - newAngle.Y = iY; - angles[0] = newAngle; + intersection(angles[0].X, angles[0].Y, angles[1].X, angles[1].Y, MathF.Cos(startAngle), MathF.Sin(startAngle)); + angles[0] = new(startAngle, iX, iY); } int index = angles.Count - 1; if (stopAngle < angles[index].angle) { - Angle newAngle; - intersection(angles[index - 1].X, angles[index - 1].Y, angles[index].X, angles[index].Y, 0.0f, 0.0f, (float)Math.Cos(stopAngle), (float)Math.Sin(stopAngle)); - newAngle.angle = stopAngle; - newAngle.X = iX; - newAngle.Y = iY; - angles[index] = newAngle; + int indxMinus1 = index - 1; + intersection(angles[indxMinus1].X, angles[indxMinus1].Y, angles[index].X, angles[index].Y, MathF.Cos(stopAngle), MathF.Sin(stopAngle)); + angles[index] = new(stopAngle, iX, iY);; } } } @@ -611,13 +498,13 @@ internal void makeAngles(int sides, float startAngle, float stopAngle) /// public class Profile { - private const float twoPi = 2.0f * (float)Math.PI; + private const float twoPi = 2.0f * MathF.PI; public string errorMessage = null; - public List coords; + public List coords; public List faces; - public List vertexNormals; + public List vertexNormals; public List us; public List faceUVs; public List faceNumbers; @@ -628,9 +515,9 @@ public class Profile public List cut1CoordIndices = null; public List cut2CoordIndices = null; - public Coord faceNormal = new Coord(0.0f, 0.0f, 1.0f); - public Coord cutNormal1 = new Coord(); - public Coord cutNormal2 = new Coord(); + public Vector3 faceNormal = Vector3.UnitZ; + public Vector3 cutNormal1 = new(); + public Vector3 cutNormal2 = new(); public int numOuterVerts = 0; public int numHollowVerts = 0; @@ -644,52 +531,55 @@ public class Profile public Profile() { - this.coords = new List(); - this.faces = new List(); - this.vertexNormals = new List(); - this.us = new List(); - this.faceUVs = new List(); - this.faceNumbers = new List(); + coords = []; + faces = []; + vertexNormals = []; + us = []; + faceUVs = []; + faceNumbers = []; } - public Profile(int sides, float profileStart, float profileEnd, float hollow, int hollowSides, bool createFaces, bool calcVertexNormals) + public Profile(int sides, float profileStart, float profileEnd, + float hollow, int hollowSides, bool createFaces, bool calcVertexNormals) { this.calcVertexNormals = calcVertexNormals; - this.coords = new List(); - this.faces = new List(); - this.vertexNormals = new List(); - this.us = new List(); - this.faceUVs = new List(); - this.faceNumbers = new List(); - - Coord center = new Coord(0.0f, 0.0f, 0.0f); - - List hollowCoords = new List(); - List hollowNormals = new List(); + coords = []; + faces = []; + vertexNormals = []; + us = []; + faceUVs = []; + faceNumbers = []; + + List hollowCoords = []; + List hollowNormals = []; List hollowUs = new List(); if (calcVertexNormals) { - this.outerCoordIndices = new List(); - this.hollowCoordIndices = new List(); - this.cut1CoordIndices = new List(); - this.cut2CoordIndices = new List(); + outerCoordIndices = []; + hollowCoordIndices = []; + cut1CoordIndices = []; + cut2CoordIndices = []; } - bool hasHollow = (hollow > 0.0f); + bool hasHollow = hollow > 0.0f; + bool hasProfileCut = profileStart > 0.0f || profileEnd < 1.0f; - bool hasProfileCut = (profileStart > 0.0f || profileEnd < 1.0f); + AngleList angles = new(); + AngleList hollowAngles = new(); - AngleList angles = new AngleList(); - AngleList hollowAngles = new AngleList(); - - float xScale = 0.5f; - float yScale = 0.5f; + float xScale; + float yScale; if (sides == 4) // corners of a square are sqrt(2) from center { xScale = 0.707107f; yScale = 0.707107f; } + else + { + xScale = 0.5f; + yScale = 0.5f; + } float startAngle = profileStart * twoPi; float stopAngle = profileEnd * twoPi; @@ -704,10 +594,10 @@ public Profile(int sides, float profileStart, float profileEnd, float hollow, in return; } - this.numOuterVerts = angles.angles.Count; + numOuterVerts = angles.angles.Count; // flag to create as few triangles as possible for 3 or 4 side profile - bool simpleFace = (sides < 5 && !hasHollow && !hasProfileCut); + bool simpleFace = sides < 5 && !hasHollow && !hasProfileCut; if (hasHollow) { @@ -724,37 +614,33 @@ public Profile(int sides, float profileStart, float profileEnd, float hollow, in return; } } - this.numHollowVerts = hollowAngles.angles.Count; + numHollowVerts = hollowAngles.angles.Count; } else if (!simpleFace) { - this.coords.Add(center); - if (this.calcVertexNormals) - this.vertexNormals.Add(new Coord(0.0f, 0.0f, 1.0f)); - this.us.Add(0.0f); + coords.Add(Vector3.Zero); + if (calcVertexNormals) + vertexNormals.Add(Vector3.UnitZ); + us.Add(0.0f); } - float z = 0.0f; - Angle angle; - Coord newVert = new Coord(); + Vector3 newVert = new(); + if (hasHollow && hollowSides != sides) { - int numHollowAngles = hollowAngles.angles.Count; - for (int i = 0; i < numHollowAngles; i++) + for (int i = 0; i < hollowAngles.angles.Count; i++) { angle = hollowAngles.angles[i]; newVert.X = hollow * xScale * angle.X; newVert.Y = hollow * yScale * angle.Y; - newVert.Z = z; - hollowCoords.Add(newVert); - if (this.calcVertexNormals) + if (calcVertexNormals) { if (hollowSides < 5) - hollowNormals.Add(hollowAngles.normals[i].Invert()); + hollowNormals.Add(-hollowAngles.normals[i]); else - hollowNormals.Add(new Coord(-angle.X, -angle.Y, 0.0f)); + hollowNormals.Add(new Vector3(-angle.X, -angle.Y, 0.0f)); if (hollowSides == 4) hollowUs.Add(angle.angle * hollow * 0.707107f); @@ -765,29 +651,26 @@ public Profile(int sides, float profileStart, float profileEnd, float hollow, in } int index = 0; - int numAngles = angles.angles.Count; - - for (int i = 0; i < numAngles; i++) + for (int i = 0; i < angles.angles.Count; i++) { angle = angles.angles[i]; newVert.X = angle.X * xScale; newVert.Y = angle.Y * yScale; - newVert.Z = z; - this.coords.Add(newVert); - if (this.calcVertexNormals) + coords.Add(newVert); + + if (calcVertexNormals) { - this.outerCoordIndices.Add(this.coords.Count - 1); + outerCoordIndices.Add(coords.Count - 1); if (sides < 5) { - this.vertexNormals.Add(angles.normals[i]); - float u = angle.angle; - this.us.Add(u); + vertexNormals.Add(angles.normals[i]); + us.Add(angle.angle); } else { - this.vertexNormals.Add(new Coord(angle.X, angle.Y, 0.0f)); - this.us.Add(angle.angle); + vertexNormals.Add(new(angle.X, angle.Y, 0.0f)); + us.Add(angle.angle); } } @@ -797,17 +680,16 @@ public Profile(int sides, float profileStart, float profileEnd, float hollow, in { newVert.X *= hollow; newVert.Y *= hollow; - newVert.Z = z; hollowCoords.Add(newVert); - if (this.calcVertexNormals) + if (calcVertexNormals) { if (sides < 5) { - hollowNormals.Add(angles.normals[i].Invert()); + hollowNormals.Add(-angles.normals[i]); } else - hollowNormals.Add(new Coord(-angle.X, -angle.Y, 0.0f)); + hollowNormals.Add(new Vector3(-angle.X, -angle.Y, 0.0f)); hollowUs.Add(angle.angle * hollow); } @@ -815,12 +697,7 @@ public Profile(int sides, float profileStart, float profileEnd, float hollow, in } else if (!simpleFace && createFaces && angle.angle > 0.0001f) { - Face newFace = new Face(); - newFace.v1 = 0; - newFace.v2 = index; - newFace.v3 = index + 1; - - this.faces.Add(newFace); + faces.Add(new( 0, index, index + 1)); } index += 1; } @@ -828,7 +705,7 @@ public Profile(int sides, float profileStart, float profileEnd, float hollow, in if (hasHollow) { hollowCoords.Reverse(); - if (this.calcVertexNormals) + if (calcVertexNormals) { hollowNormals.Reverse(); hollowUs.Reverse(); @@ -836,75 +713,56 @@ public Profile(int sides, float profileStart, float profileEnd, float hollow, in if (createFaces) { - int numTotalVerts = this.numOuterVerts + this.numHollowVerts; + int numTotalVerts = numOuterVerts + numHollowVerts; - if (this.numOuterVerts == this.numHollowVerts) + if (numOuterVerts == numHollowVerts) { - Face newFace = new Face(); - - for (int coordIndex = 0; coordIndex < this.numOuterVerts - 1; coordIndex++) + for (int coordIndex = 0; coordIndex < numOuterVerts - 1; coordIndex++) { - newFace.v1 = coordIndex; - newFace.v2 = coordIndex + 1; - newFace.v3 = numTotalVerts - coordIndex - 1; - this.faces.Add(newFace); - - newFace.v1 = coordIndex + 1; - newFace.v2 = numTotalVerts - coordIndex - 2; - newFace.v3 = numTotalVerts - coordIndex - 1; - this.faces.Add(newFace); + int fromTotal = numTotalVerts - coordIndex - 1; + faces.Add(new( coordIndex, coordIndex + 1, fromTotal )); + faces.Add(new( coordIndex + 1, fromTotal - 1, fromTotal )); } } else { - if (this.numOuterVerts < this.numHollowVerts) + if (numOuterVerts < numHollowVerts) { - Face newFace = new Face(); int j = 0; // j is the index for outer vertices - int maxJ = this.numOuterVerts - 1; - for (int i = 0; i < this.numHollowVerts; i++) // i is the index for inner vertices + int maxJ = numOuterVerts - 1; + for (int i = 0; i < numHollowVerts; i++) // i is the index for inner vertices { + int fromTotal = numTotalVerts - i - 1; if (j < maxJ) + { if (angles.angles[j + 1].angle - hollowAngles.angles[i].angle < hollowAngles.angles[i].angle - angles.angles[j].angle + 0.000001f) { - newFace.v1 = numTotalVerts - i - 1; - newFace.v2 = j; - newFace.v3 = j + 1; - - this.faces.Add(newFace); - j += 1; + faces.Add(new( fromTotal, j, j + 1)); + j++; } + } - newFace.v1 = j; - newFace.v2 = numTotalVerts - i - 2; - newFace.v3 = numTotalVerts - i - 1; - - this.faces.Add(newFace); + faces.Add(new( j, fromTotal - 1, fromTotal)); } } else // numHollowVerts < numOuterVerts { - Face newFace = new Face(); int j = 0; // j is the index for inner vertices - int maxJ = this.numHollowVerts - 1; - for (int i = 0; i < this.numOuterVerts; i++) + int maxJ = numHollowVerts - 1; + for (int i = 0; i < numOuterVerts; i++) { + int fromTotal = numTotalVerts - j - 1; if (j < maxJ) + { if (hollowAngles.angles[j + 1].angle - angles.angles[i].angle < angles.angles[i].angle - hollowAngles.angles[j].angle + 0.000001f) { - newFace.v1 = i; - newFace.v2 = numTotalVerts - j - 2; - newFace.v3 = numTotalVerts - j - 1; - - this.faces.Add(newFace); - j += 1; + faces.Add(new( i, fromTotal - 1, fromTotal )); + j++; + fromTotal--; } + } - newFace.v1 = numTotalVerts - j - 1; - newFace.v2 = i; - newFace.v3 = i + 1; - - this.faces.Add(newFace); + faces.Add(new( fromTotal, i, i + 1 )); } } } @@ -912,77 +770,68 @@ public Profile(int sides, float profileStart, float profileEnd, float hollow, in if (calcVertexNormals) { - foreach (Coord hc in hollowCoords) + foreach (Vector3 hc in hollowCoords) { - this.coords.Add(hc); - hollowCoordIndices.Add(this.coords.Count - 1); + hollowCoordIndices.Add(coords.Count); + coords.Add(hc); } + vertexNormals.AddRange(hollowNormals); + us.AddRange(hollowUs); } else - this.coords.AddRange(hollowCoords); - - if (this.calcVertexNormals) - { - this.vertexNormals.AddRange(hollowNormals); - this.us.AddRange(hollowUs); - - } + coords.AddRange(hollowCoords); } if (simpleFace && createFaces) { if (sides == 3) - this.faces.Add(new Face(0, 1, 2)); + faces.Add(new(0, 1, 2)); else if (sides == 4) { - this.faces.Add(new Face(0, 1, 2)); - this.faces.Add(new Face(0, 2, 3)); + faces.Add(new(0, 1, 2)); + faces.Add(new(0, 2, 3)); } } if (calcVertexNormals && hasProfileCut) { - int lastOuterVertIndex = this.numOuterVerts - 1; + int lastOuterVertIndex = numOuterVerts - 1; if (hasHollow) { - this.cut1CoordIndices.Add(0); - this.cut1CoordIndices.Add(this.coords.Count - 1); + cut1CoordIndices.Add(0); + cut1CoordIndices.Add(coords.Count - 1); - this.cut2CoordIndices.Add(lastOuterVertIndex + 1); - this.cut2CoordIndices.Add(lastOuterVertIndex); + int lastOuterVertIndexPlus1 = lastOuterVertIndex + 1; + cut2CoordIndices.Add(lastOuterVertIndexPlus1); + cut2CoordIndices.Add(lastOuterVertIndex); - this.cutNormal1.X = this.coords[0].Y - this.coords[this.coords.Count - 1].Y; - this.cutNormal1.Y = -(this.coords[0].X - this.coords[this.coords.Count - 1].X); + cutNormal1.X = coords[0].Y - coords[^1].Y; + cutNormal1.Y = -(coords[0].X - coords[^1].X); - this.cutNormal2.X = this.coords[lastOuterVertIndex + 1].Y - this.coords[lastOuterVertIndex].Y; - this.cutNormal2.Y = -(this.coords[lastOuterVertIndex + 1].X - this.coords[lastOuterVertIndex].X); + cutNormal2.X = coords[lastOuterVertIndexPlus1].Y - coords[lastOuterVertIndex].Y; + cutNormal2.Y = -(coords[lastOuterVertIndexPlus1].X - coords[lastOuterVertIndex].X); } else { - this.cut1CoordIndices.Add(0); - this.cut1CoordIndices.Add(1); + cut1CoordIndices.Add(0); + cut1CoordIndices.Add(1); - this.cut2CoordIndices.Add(lastOuterVertIndex); - this.cut2CoordIndices.Add(0); + cut2CoordIndices.Add(lastOuterVertIndex); + cut2CoordIndices.Add(0); - this.cutNormal1.X = this.vertexNormals[1].Y; - this.cutNormal1.Y = -this.vertexNormals[1].X; - - this.cutNormal2.X = -this.vertexNormals[this.vertexNormals.Count - 2].Y; - this.cutNormal2.Y = this.vertexNormals[this.vertexNormals.Count - 2].X; + cutNormal1.X = vertexNormals[1].Y; + cutNormal1.Y = -vertexNormals[1].X; + cutNormal2.X = -vertexNormals[^2].Y; + cutNormal2.Y = vertexNormals[^2].X; } - this.cutNormal1.Normalize(); - this.cutNormal2.Normalize(); + cutNormal1.Normalize(); + cutNormal2.Normalize(); } - this.MakeFaceUVs(); - - hollowCoords = null; - hollowNormals = null; - hollowUs = null; + MakeFaceUVs(); if (calcVertexNormals) { // calculate prim face numbers @@ -991,215 +840,204 @@ public Profile(int sides, float profileStart, float profileEnd, float hollow, in // I know it's ugly but so is the whole concept of prim face numbers int faceNum = 1; // start with outer faces - this.outerFaceNumber = faceNum; + outerFaceNumber = faceNum; - int startVert = hasProfileCut && !hasHollow ? 1 : 0; - if (startVert > 0) - this.faceNumbers.Add(-1); - for (int i = 0; i < this.numOuterVerts - 1; i++) - this.faceNumbers.Add(sides < 5 && i <= sides ? faceNum++ : faceNum); + if (hasProfileCut && !hasHollow) + faceNumbers.Add(-1); + + if(sides < 5) + { + for (int i = 0; i < numOuterVerts - 1; i++) + faceNumbers.Add(i <= sides ? faceNum++ : faceNum); + } + else + { + for (int i = 0; i < numOuterVerts - 1; i++) + faceNumbers.Add(faceNum); + } - this.faceNumbers.Add(hasProfileCut ? -1 : faceNum++); + faceNumbers.Add(hasProfileCut ? -1 : faceNum++); - if (sides > 4 && (hasHollow || hasProfileCut)) - faceNum++; + if(hasHollow || hasProfileCut) + { + if (sides > 4) + faceNum++; - if (sides < 5 && (hasHollow || hasProfileCut) && this.numOuterVerts < sides) - faceNum++; + if (sides < 5 && numOuterVerts < sides) + faceNum++; + } if (hasHollow) { - for (int i = 0; i < this.numHollowVerts; i++) - this.faceNumbers.Add(faceNum); + for (int i = 0; i < numHollowVerts; i++) + faceNumbers.Add(faceNum); - this.hollowFaceNumber = faceNum++; + hollowFaceNumber = faceNum++; } - this.bottomFaceNumber = faceNum++; + bottomFaceNumber = faceNum++; if (hasHollow && hasProfileCut) - this.faceNumbers.Add(faceNum++); + faceNumbers.Add(faceNum++); - for (int i = 0; i < this.faceNumbers.Count; i++) - if (this.faceNumbers[i] == -1) - this.faceNumbers[i] = faceNum++; + for (int i = 0; i < faceNumbers.Count; i++) + if (faceNumbers[i] == -1) + faceNumbers[i] = faceNum++; - this.numPrimFaces = faceNum; + numPrimFaces = faceNum; } } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void MakeFaceUVs() { - this.faceUVs = new List(); - foreach (Coord c in this.coords) - this.faceUVs.Add(new UVCoord(1.0f - (0.5f + c.X), 1.0f - (0.5f - c.Y))); + faceUVs = new(coords.Count); + foreach (Vector3 c in coords) + faceUVs.Add(new UVCoord(0.5f - c.X, 0.5f + c.Y)); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public Profile Copy() { - return this.Copy(true); + return Copy(true); } public Profile Copy(bool needFaces) { - Profile copy = new Profile(); + Profile copy = new(); - copy.coords.AddRange(this.coords); - copy.faceUVs.AddRange(this.faceUVs); + copy.coords.AddRange(coords); + copy.faceUVs.AddRange(faceUVs); + + copy.calcVertexNormals = calcVertexNormals; if (needFaces) - copy.faces.AddRange(this.faces); - if ((copy.calcVertexNormals = this.calcVertexNormals) == true) + copy.faces.AddRange(faces); + + if (calcVertexNormals) { - copy.vertexNormals.AddRange(this.vertexNormals); - copy.faceNormal = this.faceNormal; - copy.cutNormal1 = this.cutNormal1; - copy.cutNormal2 = this.cutNormal2; - copy.us.AddRange(this.us); - copy.faceNumbers.AddRange(this.faceNumbers); - - copy.cut1CoordIndices = new List(this.cut1CoordIndices); - copy.cut2CoordIndices = new List(this.cut2CoordIndices); - copy.hollowCoordIndices = new List(this.hollowCoordIndices); - copy.outerCoordIndices = new List(this.outerCoordIndices); + copy.vertexNormals.AddRange(vertexNormals); + copy.faceNormal = faceNormal; + copy.cutNormal1 = cutNormal1; + copy.cutNormal2 = cutNormal2; + copy.us.AddRange(us); + copy.faceNumbers.AddRange(faceNumbers); + + copy.cut1CoordIndices = new(cut1CoordIndices); + copy.cut2CoordIndices = new(cut2CoordIndices); + copy.hollowCoordIndices = new(hollowCoordIndices); + copy.outerCoordIndices = new(outerCoordIndices); } - copy.numOuterVerts = this.numOuterVerts; - copy.numHollowVerts = this.numHollowVerts; + copy.numOuterVerts = numOuterVerts; + copy.numHollowVerts = numHollowVerts; return copy; } - public void AddPos(Coord v) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AddPos(Vector3 v) { - this.AddPos(v.X, v.Y, v.Z); + for (int i = 0; i < coords.Count; i++) + coords[i] += v; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AddPos(float x, float y, float z) { - int i; - int numVerts = this.coords.Count; - Coord vert; - - for (i = 0; i < numVerts; i++) - { - vert = this.coords[i]; - vert.X += x; - vert.Y += y; - vert.Z += z; - this.coords[i] = vert; - } + Vector3 v = new(x, y, z); + AddPos(v); } - public void AddRot(Quat q) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AddRot(Quaternion q) { - int i; - int numVerts = this.coords.Count; + if(q.IsIdentity()) return; - for (i = 0; i < numVerts; i++) - this.coords[i] *= q; + for (int i = 0; i < coords.Count; i++) + coords[i] *= q; - if (this.calcVertexNormals) + if (calcVertexNormals) { - int numNormals = this.vertexNormals.Count; - for (i = 0; i < numNormals; i++) - this.vertexNormals[i] *= q; - - this.faceNormal *= q; - this.cutNormal1 *= q; - this.cutNormal2 *= q; + for (int i = 0; i < vertexNormals.Count; i++) + vertexNormals[i] *= q; + faceNormal *= q; + cutNormal1 *= q; + cutNormal2 *= q; } } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Scale(float x, float y) { - int i; - int numVerts = this.coords.Count; - Coord vert; - - for (i = 0; i < numVerts; i++) + Vector3 vert; + for (int i = 0; i < coords.Count; i++) { - vert = this.coords[i]; + vert = coords[i]; vert.X *= x; vert.Y *= y; - this.coords[i] = vert; + coords[i] = vert; } } /// /// Changes order of the vertex indices and negates the center vertex normal. Does not alter vertex normals of radial vertices /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void FlipNormals() { - int i; - int numFaces = this.faces.Count; Face tmpFace; int tmp; - for (i = 0; i < numFaces; i++) + for (int i = 0; i < faces.Count; i++) { - tmpFace = this.faces[i]; + tmpFace = faces[i]; tmp = tmpFace.v3; tmpFace.v3 = tmpFace.v1; tmpFace.v1 = tmp; - this.faces[i] = tmpFace; + faces[i] = tmpFace; } - if (this.calcVertexNormals) + if (calcVertexNormals) { - int normalCount = this.vertexNormals.Count; - if (normalCount > 0) + if (vertexNormals.Count > 0) { - Coord n = this.vertexNormals[normalCount - 1]; + Vector3 n = vertexNormals[^1]; n.Z = -n.Z; - this.vertexNormals[normalCount - 1] = n; + vertexNormals[^1] = n; } } - this.faceNormal.X = -this.faceNormal.X; - this.faceNormal.Y = -this.faceNormal.Y; - this.faceNormal.Z = -this.faceNormal.Z; + faceNormal = -faceNormal; - int numfaceUVs = this.faceUVs.Count; - for (i = 0; i < numfaceUVs; i++) + for (int i = 0; i < faceUVs.Count; i++) { - UVCoord uv = this.faceUVs[i]; + UVCoord uv = faceUVs[i]; uv.V = 1.0f - uv.V; - this.faceUVs[i] = uv; + faceUVs[i] = uv; } } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AddValue2FaceVertexIndices(int num) { - int numFaces = this.faces.Count; - Face tmpFace; - for (int i = 0; i < numFaces; i++) + for (int i = 0; i < faces.Count; i++) { - tmpFace = this.faces[i]; - tmpFace.v1 += num; - tmpFace.v2 += num; - tmpFace.v3 += num; - - this.faces[i] = tmpFace; + Face face = faces[i]; + face.AddVerticesIndexesOffset(num); + faces[i] = face; } } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AddValue2FaceNormalIndices(int num) { - if (this.calcVertexNormals) + for (int i = 0; i < faces.Count; i++) { - int numFaces = this.faces.Count; - Face tmpFace; - for (int i = 0; i < numFaces; i++) - { - tmpFace = this.faces[i]; - tmpFace.n1 += num; - tmpFace.n2 += num; - tmpFace.n3 += num; - - this.faces[i] = tmpFace; - } + Face face = faces[i]; + faces[i].AddNormalsIndexesOffset(num); + faces[i] = face; } } @@ -1209,16 +1047,10 @@ public void DumpRaw(String path, String name, String title) return; String fileName = name + "_" + title + ".raw"; String completePath = System.IO.Path.Combine(path, fileName); - StreamWriter sw = new StreamWriter(completePath); + StreamWriter sw = new(completePath); - for (int i = 0; i < this.faces.Count; i++) - { - string s = this.coords[this.faces[i].v1].ToString(); - s += " " + this.coords[this.faces[i].v2].ToString(); - s += " " + this.coords[this.faces[i].v3].ToString(); - - sw.WriteLine(s); - } + for (int i = 0; i < faces.Count; i++) + sw.WriteLine($"{coords[faces[i].v1]} {coords[faces[i].v2]} {coords[faces[i].v3]}"); sw.Close(); } @@ -1226,8 +1058,8 @@ public void DumpRaw(String path, String name, String title) public struct PathNode { - public Coord position; - public Quat rotation; + public Vector3 position; + public Quaternion rotation; public float xScale; public float yScale; public float percentOfPath; @@ -1237,7 +1069,7 @@ public enum PathType { Linear = 0, Circular = 1, Flexible = 2 } public class Path { - public List pathNodes = new List(); + public List pathNodes = []; public float twistBegin = 0.0f; public float twistEnd = 0.0f; @@ -1256,82 +1088,82 @@ public class Path public float revolutions = 1.0f; public int stepsPerRevolution = 24; - private const float twoPi = 2.0f * (float)Math.PI; + private const float twoPi = 2.0f * MathF.PI; public void Create(PathType pathType, int steps) { - if (this.taperX > 0.999f) - this.taperX = 0.999f; - if (this.taperX < -0.999f) - this.taperX = -0.999f; - if (this.taperY > 0.999f) - this.taperY = 0.999f; - if (this.taperY < -0.999f) - this.taperY = -0.999f; + if(taperX < -0.999f) + taperX = -0.999f; + else if(taperX > 0.999f) + taperX = 0.999f; + + if(taperY < -0.999f) + taperY = -0.999f; + else if(taperY > 0.999f) + taperY = 0.999f; if (pathType == PathType.Linear || pathType == PathType.Flexible) { int step = 0; - float length = this.pathCutEnd - this.pathCutBegin; + float length = pathCutEnd - pathCutBegin; float twistTotal = twistEnd - twistBegin; - float twistTotalAbs = Math.Abs(twistTotal); + float twistTotalAbs = MathF.Abs(twistTotal); if (twistTotalAbs > 0.01f) - steps += (int)(twistTotalAbs * 3.66); // dahlia's magic number + steps += (int)(twistTotalAbs * 3.66f); // dahlia's magic number float start = -0.5f; float stepSize = length / (float)steps; float percentOfPathMultiplier = stepSize * 0.999999f; - float xOffset = this.topShearX * this.pathCutBegin; - float yOffset = this.topShearY * this.pathCutBegin; + float xOffset = topShearX * pathCutBegin; + float yOffset = topShearY * pathCutBegin; float zOffset = start; - float xOffsetStepIncrement = this.topShearX * length / steps; - float yOffsetStepIncrement = this.topShearY * length / steps; + float xOffsetStepIncrement = topShearX * length / steps; + float yOffsetStepIncrement = topShearY * length / steps; - float percentOfPath = this.pathCutBegin; + float percentOfPath = pathCutBegin; zOffset += percentOfPath; // sanity checks - bool done = false; - - while (!done) + while (true) { - PathNode newNode = new PathNode(); + PathNode newNode = new(); - newNode.xScale = 1.0f; - if (this.taperX == 0.0f) + if (taperX == 0.0f) newNode.xScale = 1.0f; - else if (this.taperX > 0.0f) - newNode.xScale = 1.0f - percentOfPath * this.taperX; - else newNode.xScale = 1.0f + (1.0f - percentOfPath) * this.taperX; + else if (taperX > 0.0f) + newNode.xScale = 1.0f - percentOfPath * taperX; + else + newNode.xScale = 1.0f + (1.0f - percentOfPath) * taperX; - newNode.yScale = 1.0f; - if (this.taperY == 0.0f) + if (taperY == 0.0f) newNode.yScale = 1.0f; - else if (this.taperY > 0.0f) - newNode.yScale = 1.0f - percentOfPath * this.taperY; - else newNode.yScale = 1.0f + (1.0f - percentOfPath) * this.taperY; + else if (taperY > 0.0f) + newNode.yScale = 1.0f - percentOfPath * taperY; + else + newNode.yScale = 1.0f + (1.0f - percentOfPath) * taperY; float twist = twistBegin + twistTotal * percentOfPath; - newNode.rotation = new Quat(new Coord(0.0f, 0.0f, 1.0f), twist); - newNode.position = new Coord(xOffset, yOffset, zOffset); + newNode.rotation = twist == 0f ? Quaternion.Identity : + new Quaternion(Quaternion.MainAxis.Z, twist); + newNode.position = new Vector3(xOffset, yOffset, zOffset); newNode.percentOfPath = percentOfPath; pathNodes.Add(newNode); - if (step < steps) - { - step += 1; - percentOfPath += percentOfPathMultiplier; - xOffset += xOffsetStepIncrement; - yOffset += yOffsetStepIncrement; - zOffset += stepSize; - if (percentOfPath > this.pathCutEnd) - done = true; - } - else done = true; + if (step >= steps) + break; + + percentOfPath += percentOfPathMultiplier; + if (percentOfPath > pathCutEnd) + break; + + step++; + xOffset += xOffsetStepIncrement; + yOffset += yOffsetStepIncrement; + zOffset += stepSize; } } // end of linear path code @@ -1342,21 +1174,23 @@ public void Create(PathType pathType, int steps) // if the profile has a lot of twist, add more layers otherwise the layers may overlap // and the resulting mesh may be quite inaccurate. This method is arbitrary and doesn't // accurately match the viewer - float twistTotalAbs = Math.Abs(twistTotal); + /* + float twistTotalAbs = MathF.Abs(twistTotal); if (twistTotalAbs > 0.01f) { - if (twistTotalAbs > Math.PI * 1.5f) + if (twistTotalAbs > MathF.PI * 1.5f) steps *= 2; - if (twistTotalAbs > Math.PI * 3.0f) + if (twistTotalAbs > MathF.PI * 3.0f) steps *= 2; } + */ - float yPathScale = this.holeSizeY * 0.5f; - float pathLength = this.pathCutEnd - this.pathCutBegin; - float totalSkew = this.skew * 2.0f * pathLength; - float skewStart = this.pathCutBegin * 2.0f * this.skew - this.skew; - float xOffsetTopShearXFactor = this.topShearX * (0.25f + 0.5f * (0.5f - this.holeSizeY)); - float yShearCompensation = 1.0f + Math.Abs(this.topShearY) * 0.25f; + float yPathScale = holeSizeY * 0.5f; + float pathLength = pathCutEnd - pathCutBegin; + float totalSkew = skew * 2.0f * pathLength; + float skewStart = pathCutBegin * 2.0f * skew - skew; + float xOffsetTopShearXFactor = topShearX * (0.25f + 0.5f * (0.5f - holeSizeY)); + float yShearCompensation = 1.0f + MathF.Abs(topShearY) * 0.25f; // It's not quite clear what pushY (Y top shear) does, but subtracting it from the start and end // angles appears to approximate it's effects on path cut. Likewise, adding it to the angle used @@ -1366,62 +1200,63 @@ public void Create(PathType pathType, int steps) // the meshes generated with this technique appear nearly identical in shape to the same prims when // displayed by the viewer. - float startAngle = (twoPi * this.pathCutBegin * this.revolutions) - this.topShearY * 0.9f; - float endAngle = (twoPi * this.pathCutEnd * this.revolutions) - this.topShearY * 0.9f; - float stepSize = twoPi / this.stepsPerRevolution; + float startAngle = (twoPi * pathCutBegin * revolutions) - topShearY * 0.9f; + float endAngle = (twoPi * pathCutEnd * revolutions) - topShearY * 0.9f; + float stepSize = twoPi / stepsPerRevolution; - int step = (int)(startAngle / stepSize); float angle = startAngle; - bool done = false; - while (!done) // loop through the length of the path and add the layers + while (true) // loop through the length of the path and add the layers { - PathNode newNode = new PathNode(); + PathNode newNode = new(); - float xProfileScale = (1.0f - Math.Abs(this.skew)) * this.holeSizeX; - float yProfileScale = this.holeSizeY; + float xProfileScale = (1.0f - MathF.Abs(skew)) * holeSizeX; + float yProfileScale = holeSizeY; - float percentOfPath = angle / (twoPi * this.revolutions); + float percentOfPath = angle / (twoPi * revolutions); float percentOfAngles = (angle - startAngle) / (endAngle - startAngle); - if (this.taperX > 0.01f) - xProfileScale *= 1.0f - percentOfPath * this.taperX; - else if (this.taperX < -0.01f) - xProfileScale *= 1.0f + (1.0f - percentOfPath) * this.taperX; + if (taperX > 0.01f) + xProfileScale *= 1.0f - percentOfPath * taperX; + else if (taperX < -0.01f) + xProfileScale *= 1.0f + (1.0f - percentOfPath) * taperX; - if (this.taperY > 0.01f) - yProfileScale *= 1.0f - percentOfPath * this.taperY; - else if (this.taperY < -0.01f) - yProfileScale *= 1.0f + (1.0f - percentOfPath) * this.taperY; + if (taperY > 0.01f) + yProfileScale *= 1.0f - percentOfPath * taperY; + else if (taperY < -0.01f) + yProfileScale *= 1.0f + (1.0f - percentOfPath) * taperY; newNode.xScale = xProfileScale; newNode.yScale = yProfileScale; - float radiusScale = 1.0f; - if (this.radius > 0.001f) - radiusScale = 1.0f - this.radius * percentOfPath; - else if (this.radius < 0.001f) - radiusScale = 1.0f + this.radius * (1.0f - percentOfPath); + float radiusScale; + if (radius > 0.001f) + radiusScale = 1.0f - radius * percentOfPath; + else if (radius < 0.001f) + radiusScale = 1.0f + radius * (1.0f - percentOfPath); + else + radiusScale = 1.0f; float twist = twistBegin + twistTotal * percentOfPath; float xOffset = 0.5f * (skewStart + totalSkew * percentOfAngles); - xOffset += (float)Math.Sin(angle) * xOffsetTopShearXFactor; + xOffset += MathF.Sin(angle) * xOffsetTopShearXFactor; - float yOffset = yShearCompensation * (float)Math.Cos(angle) * (0.5f - yPathScale) * radiusScale; + float yOffset = yShearCompensation * MathF.Cos(angle) * (0.5f - yPathScale) * radiusScale; - float zOffset = (float)Math.Sin(angle + this.topShearY) * (0.5f - yPathScale) * radiusScale; + float zOffset = MathF.Sin(angle + topShearY) * (0.5f - yPathScale) * radiusScale; - newNode.position = new Coord(xOffset, yOffset, zOffset); + newNode.position = new(xOffset, yOffset, zOffset); // now orient the rotation of the profile layer relative to it's position on the path // adding taperY to the angle used to generate the quat appears to approximate the viewer - newNode.rotation = new Quat(new Coord(1.0f, 0.0f, 0.0f), angle + this.topShearY); + newNode.rotation = angle + topShearY == 0f ? Quaternion.Identity : + new Quaternion(Quaternion.MainAxis.X, angle + topShearY); // next apply twist rotation to the profile layer if (twistTotal != 0.0f || twistBegin != 0.0f) - newNode.rotation *= new Quat(new Coord(0.0f, 0.0f, 1.0f), twist); + newNode.rotation *= new Quaternion(Quaternion.MainAxis.Z, twist); newNode.percentOfPath = percentOfPath; @@ -1431,14 +1266,11 @@ public void Create(PathType pathType, int steps) // calculate the angle for the next iteration of the loop if (angle >= endAngle - 0.01) - done = true; - else - { - step += 1; - angle = stepSize * step; - if (angle > endAngle) - angle = endAngle; - } + break; + + angle += stepSize; + if (angle > endAngle) + angle = endAngle; } } } @@ -1447,19 +1279,20 @@ public void Create(PathType pathType, int steps) public class PrimMesh { public string errorMessage = ""; - private const float twoPi = 2.0f * (float)Math.PI; + private const float twoPi = 2.0f * MathF.PI; + private const float DegToRad = twoPi / 360f; - public List coords; - public List normals; + public List coords; + public List normals; public List faces; public List viewerFaces; - private int sides = 4; - private int hollowSides = 4; - private float profileStart = 0.0f; - private float profileEnd = 1.0f; - private float hollow = 0.0f; + private readonly int sides = 4; + private readonly int hollowSides = 4; + private readonly float profileStart = 0.0f; + private readonly float profileEnd = 1.0f; + private readonly float hollow = 0.0f; public int twistBegin = 0; public int twistEnd = 0; public float topShearX = 0.0f; @@ -1496,52 +1329,56 @@ public class PrimMesh public string ParamsToDisplayString() { string s = ""; - s += "sides..................: " + this.sides.ToString(); - s += "\nhollowSides..........: " + this.hollowSides.ToString(); - s += "\nprofileStart.........: " + this.profileStart.ToString(); - s += "\nprofileEnd...........: " + this.profileEnd.ToString(); - s += "\nhollow...............: " + this.hollow.ToString(); - s += "\ntwistBegin...........: " + this.twistBegin.ToString(); - s += "\ntwistEnd.............: " + this.twistEnd.ToString(); - s += "\ntopShearX............: " + this.topShearX.ToString(); - s += "\ntopShearY............: " + this.topShearY.ToString(); - s += "\npathCutBegin.........: " + this.pathCutBegin.ToString(); - s += "\npathCutEnd...........: " + this.pathCutEnd.ToString(); - s += "\ndimpleBegin..........: " + this.dimpleBegin.ToString(); - s += "\ndimpleEnd............: " + this.dimpleEnd.ToString(); - s += "\nskew.................: " + this.skew.ToString(); - s += "\nholeSizeX............: " + this.holeSizeX.ToString(); - s += "\nholeSizeY............: " + this.holeSizeY.ToString(); - s += "\ntaperX...............: " + this.taperX.ToString(); - s += "\ntaperY...............: " + this.taperY.ToString(); - s += "\nradius...............: " + this.radius.ToString(); - s += "\nrevolutions..........: " + this.revolutions.ToString(); - s += "\nstepsPerRevolution...: " + this.stepsPerRevolution.ToString(); - s += "\nsphereMode...........: " + this.sphereMode.ToString(); - s += "\nhasProfileCut........: " + this.hasProfileCut.ToString(); - s += "\nhasHollow............: " + this.hasHollow.ToString(); - s += "\nviewerMode...........: " + this.viewerMode.ToString(); + s += "sides..................: " + sides.ToString(); + s += "\nhollowSides..........: " + hollowSides.ToString(); + s += "\nprofileStart.........: " + profileStart.ToString(); + s += "\nprofileEnd...........: " + profileEnd.ToString(); + s += "\nhollow...............: " + hollow.ToString(); + s += "\ntwistBegin...........: " + twistBegin.ToString(); + s += "\ntwistEnd.............: " + twistEnd.ToString(); + s += "\ntopShearX............: " + topShearX.ToString(); + s += "\ntopShearY............: " + topShearY.ToString(); + s += "\npathCutBegin.........: " + pathCutBegin.ToString(); + s += "\npathCutEnd...........: " + pathCutEnd.ToString(); + s += "\ndimpleBegin..........: " + dimpleBegin.ToString(); + s += "\ndimpleEnd............: " + dimpleEnd.ToString(); + s += "\nskew.................: " + skew.ToString(); + s += "\nholeSizeX............: " + holeSizeX.ToString(); + s += "\nholeSizeY............: " + holeSizeY.ToString(); + s += "\ntaperX...............: " + taperX.ToString(); + s += "\ntaperY...............: " + taperY.ToString(); + s += "\nradius...............: " + radius.ToString(); + s += "\nrevolutions..........: " + revolutions.ToString(); + s += "\nstepsPerRevolution...: " + stepsPerRevolution.ToString(); + s += "\nsphereMode...........: " + sphereMode.ToString(); + s += "\nhasProfileCut........: " + hasProfileCut.ToString(); + s += "\nhasHollow............: " + hasHollow.ToString(); + s += "\nviewerMode...........: " + viewerMode.ToString(); return s; } public int ProfileOuterFaceNumber { + [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return profileOuterFaceNumber; } } public int ProfileHollowFaceNumber { + [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return profileHollowFaceNumber; } } public bool HasProfileCut { + [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return hasProfileCut; } } public bool HasHollow { + [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return hasHollow; } } @@ -1554,33 +1391,31 @@ public bool HasHollow /// /// /// - public PrimMesh(int sides, float profileStart, float profileEnd, float hollow, int hollowSides) + public PrimMesh(int _sides, float _profileStart, float _profileEnd, float _hollow, int _hollowSides) { - this.coords = new List(); - this.faces = new List(); - - this.sides = sides; - this.profileStart = profileStart; - this.profileEnd = profileEnd; - this.hollow = hollow; - this.hollowSides = hollowSides; - - if (sides < 3) - this.sides = 3; - if (hollowSides < 3) - this.hollowSides = 3; + coords = []; + faces = []; + + sides = _sides < 3 ? 3 : _sides; + hollowSides = _hollowSides < 3 ? 3 : _hollowSides; + profileStart = _profileStart; + profileEnd = _profileEnd; + hollow = _hollow; + + if(hollow < 0f) + hollow = 0f; + else if(hollow > 0.99f) + hollow = 0.99f; + + if(profileEnd < 0.02f) + profileEnd = 0.02f; + else if( profileEnd > 1f) + profileEnd = 1f; + if (profileStart < 0.0f) - this.profileStart = 0.0f; - if (profileEnd > 1.0f) - this.profileEnd = 1.0f; - if (profileEnd < 0.02f) - this.profileEnd = 0.02f; - if (profileStart >= profileEnd) - this.profileStart = profileEnd - 0.02f; - if (hollow > 0.99f) - this.hollow = 0.99f; - if (hollow < 0.0f) - this.hollow = 0.0f; + profileStart = 0.0f; + else if (profileStart >= profileEnd) + profileStart = profileEnd - 0.02f; } /// @@ -1588,72 +1423,63 @@ public PrimMesh(int sides, float profileStart, float profileEnd, float hollow, i /// public void Extrude(PathType pathType) { - bool needEndFaces = false; - this.coords = new List(); - this.faces = new List(); + coords = []; + faces = []; - if (this.viewerMode) + if (viewerMode) { - this.viewerFaces = new List(); - this.calcVertexNormals = true; + viewerFaces = []; + calcVertexNormals = true; } - if (this.calcVertexNormals) - this.normals = new List(); - - int steps = 1; + if (calcVertexNormals) + normals = []; - float length = this.pathCutEnd - this.pathCutBegin; normalsProcessed = false; - if (this.viewerMode && this.sides == 3) + int steps = 1; + float length = pathCutEnd - pathCutBegin; + + if (viewerMode && sides == 3) { // prisms don't taper well so add some vertical resolution // other prims may benefit from this but just do prisms for now - if (Math.Abs(this.taperX) > 0.01 || Math.Abs(this.taperY) > 0.01) - steps = (int)(steps * 4.5 * length); + if (MathF.Abs(taperX) > 0.01f || MathF.Abs(taperY) > 0.01f) + steps = (int)(steps * 4.5f * length); } - if (this.sphereMode) - this.hasProfileCut = this.profileEnd - this.profileStart < 0.4999f; + if (sphereMode) + hasProfileCut = profileEnd - profileStart < 0.4999f; else - this.hasProfileCut = this.profileEnd - this.profileStart < 0.9999f; - this.hasHollow = (this.hollow > 0.001f); + hasProfileCut = profileEnd - profileStart < 0.9999f; + + float hollow = this.hollow; + hasHollow = hollow > 0.001f; - float twistBegin = this.twistBegin / 360.0f * twoPi; - float twistEnd = this.twistEnd / 360.0f * twoPi; + float twistBegin = this.twistBegin * DegToRad; + float twistEnd = this.twistEnd * DegToRad; float twistTotal = twistEnd - twistBegin; - float twistTotalAbs = Math.Abs(twistTotal); + float twistTotalAbs = MathF.Abs(twistTotal); if (twistTotalAbs > 0.01f) - steps += (int)(twistTotalAbs * 3.66); // dahlia's magic number - - float hollow = this.hollow; + steps += (int)(twistTotalAbs * 3.66f); // dahlia's magic number - if (pathType == PathType.Circular) - { - needEndFaces = false; - if (this.pathCutBegin > float.Epsilon || this.pathCutEnd < 1.0f - float.Epsilon) - needEndFaces = true; - else if (this.taperX > 0.01f || this.taperY > 0.01f) - needEndFaces = true; - else if (Math.Abs(this.skew) > 0.01f) - needEndFaces = true; - else if (Math.Abs(twistTotal) > 0.001f) - needEndFaces = true; - else if (Math.Abs(this.radius) > 0.0005f) - needEndFaces = true; - } - else needEndFaces = true; + bool needEndFaces = + pathType != PathType.Circular || + pathCutBegin > float.Epsilon || pathCutEnd < 1.0f - float.Epsilon || + taperX > 0.01f || taperY > 0.01f || + MathF.Abs(skew) > 0.01f || + MathF.Abs(twistTotal) > 0.001f || + MathF.Abs(radius) > 0.0005f; // sanity checks float initialProfileRot = 0.0f; if (pathType == PathType.Circular) { - if (this.sides == 3) + if (sides == 3) { - initialProfileRot = (float)Math.PI; - if (this.hollowSides == 4) + initialProfileRot = MathF.PI; + if (hollowSides == 4) { if (hollow > 0.7f) hollow = 0.7f; @@ -1661,16 +1487,16 @@ public void Extrude(PathType pathType) } else hollow *= 0.5f; } - else if (this.sides == 4) + else if (sides == 4) { - initialProfileRot = 0.25f * (float)Math.PI; - if (this.hollowSides != 4) + initialProfileRot = 0.25f * MathF.PI; + if (hollowSides != 4) hollow *= 0.707f; } - else if (this.sides > 4) + else if (sides > 4) { - initialProfileRot = (float)Math.PI; - if (this.hollowSides == 4) + initialProfileRot = MathF.PI; + if (hollowSides == 4) { if (hollow > 0.7f) hollow = 0.7f; @@ -1680,9 +1506,9 @@ public void Extrude(PathType pathType) } else { - if (this.sides == 3) + if (sides == 3) { - if (this.hollowSides == 4) + if (hollowSides == 4) { if (hollow > 0.7f) hollow = 0.7f; @@ -1690,77 +1516,83 @@ public void Extrude(PathType pathType) } else hollow *= 0.5f; } - else if (this.sides == 4) + else if (sides == 4) { - initialProfileRot = 1.25f * (float)Math.PI; - if (this.hollowSides != 4) + initialProfileRot = 1.25f * MathF.PI; + if (hollowSides != 4) hollow *= 0.707f; } - else if (this.sides == 24 && this.hollowSides == 4) + else if (sides > 4 && hollowSides == 4) hollow *= 1.414f; } - Profile profile = new Profile(this.sides, this.profileStart, this.profileEnd, hollow, this.hollowSides, true, calcVertexNormals); - this.errorMessage = profile.errorMessage; + Profile profile = new(sides, profileStart, profileEnd, hollow, hollowSides, true, calcVertexNormals); + errorMessage = profile.errorMessage; - this.numPrimFaces = profile.numPrimFaces; + numPrimFaces = profile.numPrimFaces; - int cut1FaceNumber = profile.bottomFaceNumber + 1; - int cut2FaceNumber = cut1FaceNumber + 1; - if (!needEndFaces) + int cut1FaceNumber; + if(needEndFaces) { - cut1FaceNumber -= 2; - cut2FaceNumber -= 2; + cut1FaceNumber = profile.bottomFaceNumber + 1; + profileOuterFaceNumber = profile.outerFaceNumber; } - - profileOuterFaceNumber = profile.outerFaceNumber; - if (!needEndFaces) - profileOuterFaceNumber--; + else + { + cut1FaceNumber = profile.bottomFaceNumber - 1; + profileOuterFaceNumber = profile.outerFaceNumber - 1; + } + int cut2FaceNumber = cut1FaceNumber + 1; if (hasHollow) { - profileHollowFaceNumber = profile.hollowFaceNumber; - if (!needEndFaces) - profileHollowFaceNumber--; + profileHollowFaceNumber = needEndFaces ? profile.hollowFaceNumber : profile.hollowFaceNumber - 1; } - int cut1Vert = -1; - int cut2Vert = -1; + int cut1Vert; + int cut2Vert; if (hasProfileCut) { cut1Vert = hasHollow ? profile.coords.Count - 1 : 0; cut2Vert = hasHollow ? profile.numOuterVerts - 1 : profile.numOuterVerts; } + else + { + cut1Vert = -1; + cut2Vert = -1; + } if (initialProfileRot != 0.0f) { - profile.AddRot(new Quat(new Coord(0.0f, 0.0f, 1.0f), initialProfileRot)); + profile.AddRot(new Quaternion(Quaternion.MainAxis.Z, initialProfileRot)); if (viewerMode) profile.MakeFaceUVs(); } - Coord lastCutNormal1 = new Coord(); - Coord lastCutNormal2 = new Coord(); - float thisV = 0.0f; + Vector3 lastCutNormal1 = new(); + Vector3 lastCutNormal2 = new(); float lastV = 0.0f; + float thisV; - Path path = new Path(); - path.twistBegin = twistBegin; - path.twistEnd = twistEnd; - path.topShearX = topShearX; - path.topShearY = topShearY; - path.pathCutBegin = pathCutBegin; - path.pathCutEnd = pathCutEnd; - path.dimpleBegin = dimpleBegin; - path.dimpleEnd = dimpleEnd; - path.skew = skew; - path.holeSizeX = holeSizeX; - path.holeSizeY = holeSizeY; - path.taperX = taperX; - path.taperY = taperY; - path.radius = radius; - path.revolutions = revolutions; - path.stepsPerRevolution = stepsPerRevolution; + Path path = new() + { + twistBegin = twistBegin, + twistEnd = twistEnd, + topShearX = topShearX, + topShearY = topShearY, + pathCutBegin = pathCutBegin, + pathCutEnd = pathCutEnd, + dimpleBegin = dimpleBegin, + dimpleEnd = dimpleEnd, + skew = skew, + holeSizeX = holeSizeX, + holeSizeY = holeSizeY, + taperX = taperX, + taperY = taperY, + radius = radius, + revolutions = revolutions, + stepsPerRevolution = stepsPerRevolution + }; path.Create(pathType, steps); @@ -1778,14 +1610,13 @@ public void Extrude(PathType pathType) newLayer.FlipNormals(); // add the bottom faces to the viewerFaces list - if (this.viewerMode) + if (viewerMode) { - Coord faceNormal = newLayer.faceNormal; - ViewerFace newViewerFace = new ViewerFace(profile.bottomFaceNumber); - int numFaces = newLayer.faces.Count; + Vector3 faceNormal = newLayer.faceNormal; + ViewerFace newViewerFace = new(profile.bottomFaceNumber); List faces = newLayer.faces; - for (int i = 0; i < numFaces; i++) + for (int i = 0; i < faces.Count; i++) { Face face = faces[i]; newViewerFace.v1 = newLayer.coords[face.v1]; @@ -1811,208 +1642,209 @@ public void Extrude(PathType pathType) newViewerFace.uv3.Flip(); } - this.viewerFaces.Add(newViewerFace); + viewerFaces.Add(newViewerFace); } } } // if (nodeIndex == 0) // append this layer + int coordsLen = coords.Count; + if(coordsLen > 0) + newLayer.AddValue2FaceVertexIndices(coordsLen); + coords.AddRange(newLayer.coords); - int coordsLen = this.coords.Count; - newLayer.AddValue2FaceVertexIndices(coordsLen); - - this.coords.AddRange(newLayer.coords); - - if (this.calcVertexNormals) + if (calcVertexNormals) { - newLayer.AddValue2FaceNormalIndices(this.normals.Count); - this.normals.AddRange(newLayer.vertexNormals); + if(normals.Count > 0) + newLayer.AddValue2FaceNormalIndices(normals.Count); + normals.AddRange(newLayer.vertexNormals); } if (needEndFaces) { if (nodeIndex == 0 || nodeIndex == path.pathNodes.Count - 1) - this.faces.AddRange(newLayer.faces); + faces.AddRange(newLayer.faces); } + if(nodeIndex == 0) + { + lastCutNormal1 = newLayer.cutNormal1; + lastCutNormal2 = newLayer.cutNormal2; + lastV = 1.0f - node.percentOfPath; + continue; + } // fill faces between layers int numVerts = newLayer.coords.Count; - Face newFace1 = new Face(); - Face newFace2 = new Face(); + Face newFace1 = new(); + Face newFace2 = new(); thisV = 1.0f - node.percentOfPath; - if (nodeIndex > 0) + int startVert = coordsLen + 1; + int endVert = coords.Count; + + if (sides < 5 || hasProfileCut || hasHollow) + startVert--; + + for (int i = startVert; i < endVert; i++) { - int startVert = coordsLen + 1; - int endVert = this.coords.Count; + int iNext = i == endVert - 1 ? startVert : i + 1; - if (sides < 5 || this.hasProfileCut || this.hasHollow) - startVert--; + newFace1.v1 = i; + newFace1.v2 = i - numVerts; + newFace1.v3 = iNext; - for (int i = startVert; i < endVert; i++) - { - int iNext = i + 1; - if (i == endVert - 1) - iNext = startVert; + newFace1.n1 = newFace1.v1; + newFace1.n2 = newFace1.v2; + newFace1.n3 = newFace1.v3; + faces.Add(newFace1); - int whichVert = i - startVert; + newFace2.v1 = iNext; + newFace2.v2 = i - numVerts; + newFace2.v3 = iNext - numVerts; - newFace1.v1 = i; - newFace1.v2 = i - numVerts; - newFace1.v3 = iNext; + newFace2.n1 = newFace2.v1; + newFace2.n2 = newFace2.v2; + newFace2.n3 = newFace2.v3; + faces.Add(newFace2); - newFace1.n1 = newFace1.v1; - newFace1.n2 = newFace1.v2; - newFace1.n3 = newFace1.v3; - this.faces.Add(newFace1); + if (viewerMode) + { + // add the side faces to the list of viewerFaces here + int whichVert = i - startVert; - newFace2.v1 = iNext; - newFace2.v2 = i - numVerts; - newFace2.v3 = iNext - numVerts; + int primFaceNum = profile.faceNumbers[whichVert]; + if (!needEndFaces) + primFaceNum -= 1; - newFace2.n1 = newFace2.v1; - newFace2.n2 = newFace2.v2; - newFace2.n3 = newFace2.v3; - this.faces.Add(newFace2); + ViewerFace newViewerFace1 = new(primFaceNum); + ViewerFace newViewerFace2 = new(primFaceNum); - if (this.viewerMode) + int uIndex = whichVert; + if (!hasHollow && sides > 4 && uIndex < newLayer.us.Count - 1) { - // add the side faces to the list of viewerFaces here - - int primFaceNum = profile.faceNumbers[whichVert]; - if (!needEndFaces) - primFaceNum -= 1; + uIndex++; + } - ViewerFace newViewerFace1 = new ViewerFace(primFaceNum); - ViewerFace newViewerFace2 = new ViewerFace(primFaceNum); + float u1 = newLayer.us[uIndex]; + float u2 = 1.0f; + if (uIndex < newLayer.us.Count - 1) + u2 = newLayer.us[uIndex + 1]; - int uIndex = whichVert; - if (!hasHollow && sides > 4 && uIndex < newLayer.us.Count - 1) - { - uIndex++; + if (whichVert == cut1Vert || whichVert == cut2Vert) + { + u1 = 0.0f; + u2 = 1.0f; + } + else if (sides < 5) + { + if (whichVert < profile.numOuterVerts) + { // boxes and prisms have one texture face per side of the prim, so the U values have to be scaled + // to reflect the entire texture width + u1 *= sides; + u2 *= sides; + u2 -= (int)u1; + u1 -= (int)u1; + if (u2 < 0.1f) + u2 = 1.0f; } + } - float u1 = newLayer.us[uIndex]; - float u2 = 1.0f; - if (uIndex < (int)newLayer.us.Count - 1) - u2 = newLayer.us[uIndex + 1]; - - if (whichVert == cut1Vert || whichVert == cut2Vert) - { - u1 = 0.0f; - u2 = 1.0f; - } - else if (sides < 5) + if (sphereMode) + { + if (whichVert != cut1Vert && whichVert != cut2Vert) { - if (whichVert < profile.numOuterVerts) - { // boxes and prisms have one texture face per side of the prim, so the U values have to be scaled - // to reflect the entire texture width - u1 *= sides; - u2 *= sides; - u2 -= (int)u1; - u1 -= (int)u1; - if (u2 < 0.1f) - u2 = 1.0f; - } - } + u1 = u1 * 2.0f - 1.0f; + u2 = u2 * 2.0f - 1.0f; - if (this.sphereMode) - { - if (whichVert != cut1Vert && whichVert != cut2Vert) + if (whichVert >= newLayer.numOuterVerts) { - u1 = u1 * 2.0f - 1.0f; - u2 = u2 * 2.0f - 1.0f; - - if (whichVert >= newLayer.numOuterVerts) - { - u1 -= hollow; - u2 -= hollow; - } - + u1 -= hollow; + u2 -= hollow; } } + } - newViewerFace1.uv1.U = u1; - newViewerFace1.uv2.U = u1; - newViewerFace1.uv3.U = u2; - - newViewerFace1.uv1.V = thisV; - newViewerFace1.uv2.V = lastV; - newViewerFace1.uv3.V = thisV; + newViewerFace1.uv1.U = u1; + newViewerFace1.uv2.U = u1; + newViewerFace1.uv3.U = u2; - newViewerFace2.uv1.U = u2; - newViewerFace2.uv2.U = u1; - newViewerFace2.uv3.U = u2; + newViewerFace1.uv1.V = thisV; + newViewerFace1.uv2.V = lastV; + newViewerFace1.uv3.V = thisV; - newViewerFace2.uv1.V = thisV; - newViewerFace2.uv2.V = lastV; - newViewerFace2.uv3.V = lastV; + newViewerFace2.uv1.U = u2; + newViewerFace2.uv2.U = u1; + newViewerFace2.uv3.U = u2; - newViewerFace1.v1 = this.coords[newFace1.v1]; - newViewerFace1.v2 = this.coords[newFace1.v2]; - newViewerFace1.v3 = this.coords[newFace1.v3]; + newViewerFace2.uv1.V = thisV; + newViewerFace2.uv2.V = lastV; + newViewerFace2.uv3.V = lastV; - newViewerFace2.v1 = this.coords[newFace2.v1]; - newViewerFace2.v2 = this.coords[newFace2.v2]; - newViewerFace2.v3 = this.coords[newFace2.v3]; + newViewerFace1.v1 = coords[newFace1.v1]; + newViewerFace1.v2 = coords[newFace1.v2]; + newViewerFace1.v3 = coords[newFace1.v3]; + + newViewerFace2.v1 = coords[newFace2.v1]; + newViewerFace2.v2 = coords[newFace2.v2]; + newViewerFace2.v3 = coords[newFace2.v3]; - newViewerFace1.coordIndex1 = newFace1.v1; - newViewerFace1.coordIndex2 = newFace1.v2; - newViewerFace1.coordIndex3 = newFace1.v3; + newViewerFace1.coordIndex1 = newFace1.v1; + newViewerFace1.coordIndex2 = newFace1.v2; + newViewerFace1.coordIndex3 = newFace1.v3; - newViewerFace2.coordIndex1 = newFace2.v1; - newViewerFace2.coordIndex2 = newFace2.v2; - newViewerFace2.coordIndex3 = newFace2.v3; + newViewerFace2.coordIndex1 = newFace2.v1; + newViewerFace2.coordIndex2 = newFace2.v2; + newViewerFace2.coordIndex3 = newFace2.v3; - // profile cut faces - if (whichVert == cut1Vert) - { - newViewerFace1.primFaceNumber = cut1FaceNumber; - newViewerFace2.primFaceNumber = cut1FaceNumber; - newViewerFace1.n1 = newLayer.cutNormal1; - newViewerFace1.n2 = newViewerFace1.n3 = lastCutNormal1; + // profile cut faces + if (whichVert == cut1Vert) + { + newViewerFace1.primFaceNumber = cut1FaceNumber; + newViewerFace2.primFaceNumber = cut1FaceNumber; + newViewerFace1.n1 = newLayer.cutNormal1; + newViewerFace1.n2 = lastCutNormal1; + newViewerFace1.n3 = lastCutNormal1; + + newViewerFace2.n1 = newLayer.cutNormal1; + newViewerFace2.n3 = newLayer.cutNormal1; + newViewerFace2.n2 = lastCutNormal1; + } + else if (whichVert == cut2Vert) + { + newViewerFace1.primFaceNumber = cut2FaceNumber; + newViewerFace2.primFaceNumber = cut2FaceNumber; + newViewerFace1.n1 = newLayer.cutNormal2; + newViewerFace1.n2 = lastCutNormal2; + newViewerFace1.n3 = lastCutNormal2; + + newViewerFace2.n1 = newLayer.cutNormal2; + newViewerFace2.n3 = newLayer.cutNormal2; + newViewerFace2.n2 = lastCutNormal2; + } - newViewerFace2.n1 = newViewerFace2.n3 = newLayer.cutNormal1; - newViewerFace2.n2 = lastCutNormal1; - } - else if (whichVert == cut2Vert) - { - newViewerFace1.primFaceNumber = cut2FaceNumber; - newViewerFace2.primFaceNumber = cut2FaceNumber; - newViewerFace1.n1 = newLayer.cutNormal2; - newViewerFace1.n2 = lastCutNormal2; - newViewerFace1.n3 = lastCutNormal2; - - newViewerFace2.n1 = newLayer.cutNormal2; - newViewerFace2.n3 = newLayer.cutNormal2; - newViewerFace2.n2 = lastCutNormal2; + else // outer and hollow faces + { + if ((sides < 5 && whichVert < newLayer.numOuterVerts) || (hollowSides < 5 && whichVert >= newLayer.numOuterVerts)) + { // looks terrible when path is twisted... need vertex normals here + newViewerFace1.CalcSurfaceNormal(); + newViewerFace2.CalcSurfaceNormal(); } - - else // outer and hollow faces + else { - if ((sides < 5 && whichVert < newLayer.numOuterVerts) || (hollowSides < 5 && whichVert >= newLayer.numOuterVerts)) - { // looks terrible when path is twisted... need vertex normals here - newViewerFace1.CalcSurfaceNormal(); - newViewerFace2.CalcSurfaceNormal(); - } - else - { - newViewerFace1.n1 = this.normals[newFace1.n1]; - newViewerFace1.n2 = this.normals[newFace1.n2]; - newViewerFace1.n3 = this.normals[newFace1.n3]; - - newViewerFace2.n1 = this.normals[newFace2.n1]; - newViewerFace2.n2 = this.normals[newFace2.n2]; - newViewerFace2.n3 = this.normals[newFace2.n3]; - } + newViewerFace1.n1 = normals[newFace1.n1]; + newViewerFace1.n2 = normals[newFace1.n2]; + newViewerFace1.n3 = normals[newFace1.n3]; + + newViewerFace2.n1 = normals[newFace2.n1]; + newViewerFace2.n2 = normals[newFace2.n2]; + newViewerFace2.n3 = normals[newFace2.n3]; } - - this.viewerFaces.Add(newViewerFace1); - this.viewerFaces.Add(newViewerFace2); - } + + viewerFaces.Add(newViewerFace1); + viewerFaces.Add(newViewerFace2); } } @@ -2023,12 +1855,11 @@ public void Extrude(PathType pathType) if (needEndFaces && nodeIndex == path.pathNodes.Count - 1 && viewerMode) { // add the top faces to the viewerFaces list here - Coord faceNormal = newLayer.faceNormal; - ViewerFace newViewerFace = new ViewerFace(0); - int numFaces = newLayer.faces.Count; + Vector3 faceNormal = newLayer.faceNormal; + ViewerFace newViewerFace = new(0); List faces = newLayer.faces; - for (int i = 0; i < numFaces; i++) + for (int i = 0; i < faces.Count; i++) { Face face = faces[i]; newViewerFace.v1 = newLayer.coords[face.v1 - coordsLen]; @@ -2054,7 +1885,7 @@ public void Extrude(PathType pathType) newViewerFace.uv3.Flip(); } - this.viewerFaces.Add(newViewerFace); + viewerFaces.Add(newViewerFace); } } @@ -2063,44 +1894,34 @@ public void Extrude(PathType pathType) } - - /// - /// DEPRICATED - use Extrude(PathType.Linear) instead - /// Extrudes a profile along a straight line path. Used for prim types box, cylinder, and prism. - /// - /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ExtrudeLinear() { - this.Extrude(PathType.Linear); + Extrude(PathType.Linear); } - - /// - /// DEPRICATED - use Extrude(PathType.Circular) instead - /// Extrude a profile into a circular path prim mesh. Used for prim types torus, tube, and ring. - /// - /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ExtrudeCircular() { - this.Extrude(PathType.Circular); + Extrude(PathType.Circular); } - - private Coord SurfaceNormal(Coord c1, Coord c2, Coord c3) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static Vector3 SurfaceNormal(Vector3 c1, Vector3 c2, Vector3 c3) { - Coord edge1 = new Coord(c2.X - c1.X, c2.Y - c1.Y, c2.Z - c1.Z); - Coord edge2 = new Coord(c3.X - c1.X, c3.Y - c1.Y, c3.Z - c1.Z); - - Coord normal = Coord.Cross(edge1, edge2); + Vector3 edge1 = c2 - c1; + Vector3 edge2 = c3 - c1; + Vector3 normal = Vector3.Cross(edge1, edge2); normal.Normalize(); return normal; } - private Coord SurfaceNormal(Face face) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private Vector3 SurfaceNormal(Face face) { - return SurfaceNormal(this.coords[face.v1], this.coords[face.v2], this.coords[face.v3]); + return SurfaceNormal(coords[face.v1], coords[face.v2], coords[face.v3]); } /// @@ -2108,13 +1929,13 @@ private Coord SurfaceNormal(Face face) /// /// /// - public Coord SurfaceNormal(int faceIndex) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vector3 SurfaceNormal(int faceIndex) { - int numFaces = this.faces.Count; - if (faceIndex < 0 || faceIndex >= numFaces) + if (faceIndex < 0 || faceIndex >= faces.Count) throw new Exception("faceIndex out of range"); - return SurfaceNormal(this.faces[faceIndex]); + return SurfaceNormal(faces[faceIndex]); } /// @@ -2123,33 +1944,35 @@ public Coord SurfaceNormal(int faceIndex) /// public PrimMesh Copy() { - PrimMesh copy = new PrimMesh(this.sides, this.profileStart, this.profileEnd, this.hollow, this.hollowSides); - copy.twistBegin = this.twistBegin; - copy.twistEnd = this.twistEnd; - copy.topShearX = this.topShearX; - copy.topShearY = this.topShearY; - copy.pathCutBegin = this.pathCutBegin; - copy.pathCutEnd = this.pathCutEnd; - copy.dimpleBegin = this.dimpleBegin; - copy.dimpleEnd = this.dimpleEnd; - copy.skew = this.skew; - copy.holeSizeX = this.holeSizeX; - copy.holeSizeY = this.holeSizeY; - copy.taperX = this.taperX; - copy.taperY = this.taperY; - copy.radius = this.radius; - copy.revolutions = this.revolutions; - copy.stepsPerRevolution = this.stepsPerRevolution; - copy.calcVertexNormals = this.calcVertexNormals; - copy.normalsProcessed = this.normalsProcessed; - copy.viewerMode = this.viewerMode; - copy.numPrimFaces = this.numPrimFaces; - copy.errorMessage = this.errorMessage; - - copy.coords = new List(this.coords); - copy.faces = new List(this.faces); - copy.viewerFaces = new List(this.viewerFaces); - copy.normals = new List(this.normals); + PrimMesh copy = new(sides, profileStart, profileEnd, hollow, hollowSides) + { + twistBegin = twistBegin, + twistEnd = twistEnd, + topShearX = topShearX, + topShearY = topShearY, + pathCutBegin = pathCutBegin, + pathCutEnd = pathCutEnd, + dimpleBegin = dimpleBegin, + dimpleEnd = dimpleEnd, + skew = skew, + holeSizeX = holeSizeX, + holeSizeY = holeSizeY, + taperX = taperX, + taperY = taperY, + radius = radius, + revolutions = revolutions, + stepsPerRevolution = stepsPerRevolution, + calcVertexNormals = calcVertexNormals, + normalsProcessed = normalsProcessed, + viewerMode = viewerMode, + numPrimFaces = numPrimFaces, + errorMessage = errorMessage, + + coords = new List(coords), + faces = new List(faces), + viewerFaces = new List(viewerFaces), + normals = new List(normals) + }; return copy; } @@ -2164,23 +1987,23 @@ public void CalcNormals() normalsProcessed = true; - int numFaces = faces.Count; + if (!calcVertexNormals) + normals = []; - if (!this.calcVertexNormals) - this.normals = new List(); - - for (int i = 0; i < numFaces; i++) + for (int i = 0; i < faces.Count; i++) { - Face face = faces[i]; + int normIndex = normals.Count; - this.normals.Add(SurfaceNormal(i).Normalize()); + Face face = faces[i]; + Vector3 n = SurfaceNormal(face); + n.Normalize(); + normals.Add(n); - int normIndex = normals.Count - 1; face.n1 = normIndex; face.n2 = normIndex; face.n3 = normIndex; - this.faces[i] = face; + faces[i] = face; } } @@ -2190,30 +2013,21 @@ public void CalcNormals() /// /// /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AddPos(float x, float y, float z) { - int i; - int numVerts = this.coords.Count; - Coord vert; + Vector3 vert = new(x, y, z); - for (i = 0; i < numVerts; i++) - { - vert = this.coords[i]; - vert.X += x; - vert.Y += y; - vert.Z += z; - this.coords[i] = vert; - } + for (int i = 0; i < coords.Count; i++) + coords[i] += vert; - if (this.viewerFaces != null) + if (viewerFaces != null) { - int numViewerFaces = this.viewerFaces.Count; - - for (i = 0; i < numViewerFaces; i++) + for (int i = 0; i < viewerFaces.Count; i++) { - ViewerFace v = this.viewerFaces[i]; - v.AddPos(x, y, z); - this.viewerFaces[i] = v; + ViewerFace face = viewerFaces[i]; + face.AddPos(vert); + viewerFaces[i] = face; } } } @@ -2222,45 +2036,35 @@ public void AddPos(float x, float y, float z) /// Rotates the mesh /// /// - public void AddRot(Quat q) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AddRot(Quaternion q) { - int i; - int numVerts = this.coords.Count; + if(q.IsIdentity()) + return; - for (i = 0; i < numVerts; i++) - this.coords[i] *= q; + for (int i = 0; i < coords.Count; i++) + coords[i] *= q; - if (this.normals != null) + if (normals != null) { - int numNormals = this.normals.Count; - for (i = 0; i < numNormals; i++) - this.normals[i] *= q; + for (int i = 0; i < normals.Count; i++) + normals[i] *= q; } - if (this.viewerFaces != null) + if (viewerFaces != null) { - int numViewerFaces = this.viewerFaces.Count; - - for (i = 0; i < numViewerFaces; i++) + for (int i = 0; i < viewerFaces.Count; i++) { - ViewerFace v = this.viewerFaces[i]; - v.v1 *= q; - v.v2 *= q; - v.v3 *= q; - - v.n1 *= q; - v.n2 *= q; - v.n3 *= q; - this.viewerFaces[i] = v; + ViewerFace face = viewerFaces[i]; + face.AddRot(q); + viewerFaces[i] = face; } } } public VertexIndexer GetVertexIndexer() { - if (this.viewerMode && this.viewerFaces.Count > 0) - return new VertexIndexer(this); - return null; + return (viewerMode && viewerFaces.Count > 0) ? new VertexIndexer(this) : null; } /// @@ -2271,24 +2075,17 @@ public VertexIndexer GetVertexIndexer() /// public void Scale(float x, float y, float z) { - int i; - int numVerts = this.coords.Count; - //Coord vert; + Vector3 scale = new(x, y, z); + for (int i = 0; i < coords.Count; i++) + coords[i] *= scale; - Coord m = new Coord(x, y, z); - for (i = 0; i < numVerts; i++) - this.coords[i] *= m; - - if (this.viewerFaces != null) + if (viewerFaces != null) { - int numViewerFaces = this.viewerFaces.Count; - for (i = 0; i < numViewerFaces; i++) + for (int i = 0; i < viewerFaces.Count; i++) { - ViewerFace v = this.viewerFaces[i]; - v.v1 *= m; - v.v2 *= m; - v.v3 *= m; - this.viewerFaces[i] = v; + ViewerFace face = viewerFaces[i]; + face.Scale(scale); + viewerFaces[i] = face; } } @@ -2307,18 +2104,15 @@ public void DumpRaw(String path, String name, String title) return; String fileName = name + "_" + title + ".raw"; String completePath = System.IO.Path.Combine(path, fileName); - StreamWriter sw = new StreamWriter(completePath); - for (int i = 0; i < this.faces.Count; i++) - { - string s = this.coords[this.faces[i].v1].ToString(); - s += " " + this.coords[this.faces[i].v2].ToString(); - s += " " + this.coords[this.faces[i].v3].ToString(); + using StreamWriter sw = new(completePath); + for (int i = 0; i < faces.Count; i++) + { + Face face = faces[i]; + string s = $"{coords[face.v1]} {coords[face.v2]} {coords[face.v3]}"; sw.WriteLine(s); } - - sw.Close(); } } } diff --git a/PrimMesher/SculptMap.cs b/PrimMesher/SculptMap.cs index 502f6f44..a1d3daa8 100644 --- a/PrimMesher/SculptMap.cs +++ b/PrimMesher/SculptMap.cs @@ -25,16 +25,11 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -// to build without references to System.Drawing, comment this out -#define SYSTEM_DRAWING - using System; using System.Collections.Generic; -using System.Text; +using OpenMetaverse; -#if SYSTEM_DRAWING using System.Drawing; -using System.Drawing.Imaging; namespace PrimMesher { @@ -142,12 +137,12 @@ public SculptMap(Bitmap bm, int lod) } } - public List> ToRows(bool mirror) + public List> ToRows(bool mirror) { int numRows = height; int numCols = width; - List> rows = new List>(numRows); + List> rows = new List>(numRows); float pixScale = 1.0f / 255; @@ -156,13 +151,13 @@ public List> ToRows(bool mirror) for (rowNdx = 0; rowNdx < numRows; rowNdx++) { - List row = new List(numCols); + List row = new List(numCols); for (colNdx = 0; colNdx < numCols; colNdx++) { if (mirror) - row.Add(new Coord(-(redBytes[smNdx] * pixScale - 0.5f), (greenBytes[smNdx] * pixScale - 0.5f), blueBytes[smNdx] * pixScale - 0.5f)); + row.Add(new Vector3(-(redBytes[smNdx] * pixScale - 0.5f), (greenBytes[smNdx] * pixScale - 0.5f), blueBytes[smNdx] * pixScale - 0.5f)); else - row.Add(new Coord(redBytes[smNdx] * pixScale - 0.5f, greenBytes[smNdx] * pixScale - 0.5f, blueBytes[smNdx] * pixScale - 0.5f)); + row.Add(new Vector3(redBytes[smNdx] * pixScale - 0.5f, greenBytes[smNdx] * pixScale - 0.5f, blueBytes[smNdx] * pixScale - 0.5f)); ++smNdx; } @@ -190,4 +185,4 @@ private Bitmap ScaleImage(Bitmap srcImage, int destWidth, int destHeight, } } } -#endif + diff --git a/PrimMesher/SculptMesh.cs b/PrimMesher/SculptMesh.cs index c396eef4..e1681315 100644 --- a/PrimMesher/SculptMesh.cs +++ b/PrimMesher/SculptMesh.cs @@ -30,24 +30,21 @@ using System; using System.Collections.Generic; -using System.Text; using System.IO; -#if SYSTEM_DRAWING +using OpenMetaverse; using System.Drawing; -using System.Drawing.Imaging; -#endif namespace PrimMesher { public class SculptMesh { - public List coords; + public List coords; public List faces; public List viewerFaces; - public List normals; + public List normals; public List uvs; public enum SculptType { sphere = 1, torus = 2, plane = 3, cylinder = 4 }; @@ -102,12 +99,12 @@ public SculptMesh(float[,] zMap, float xBegin, float xEnd, float yBegin, float y return; } - coords = new List(); - faces = new List(); - normals = new List(); - uvs = new List(); + coords = []; + faces = []; + normals = []; + uvs = []; - viewerFaces = new List(); + viewerFaces = []; int p1, p2, p3, p4; @@ -134,12 +131,12 @@ public SculptMesh(float[,] zMap, float xBegin, float xEnd, float yBegin, float y p2 = p4 - numXElements; p1 = p3 - numXElements; - Coord c = new Coord(xBegin + x * xStep, yBegin + y * yStep, zMap[y, x]); + Vector3 c = new(xBegin + x * xStep, yBegin + y * yStep, zMap[y, x]); this.coords.Add(c); if (viewerMode) { - this.normals.Add(new Coord()); - this.uvs.Add(new UVCoord(uStep * x, 1.0f - vStep * y)); + normals.Add(Vector3.Zero); + uvs.Add(new UVCoord(uStep * x, 1.0f - vStep * y)); } if (y > 0 && x > 0) @@ -164,8 +161,8 @@ public SculptMesh(float[,] zMap, float xBegin, float xEnd, float yBegin, float y f2 = new Face(p1, p2, p4); } - this.faces.Add(f1); - this.faces.Add(f2); + faces.Add(f1); + faces.Add(f2); } } } @@ -174,7 +171,6 @@ public SculptMesh(float[,] zMap, float xBegin, float xEnd, float yBegin, float y calcVertexNormals(SculptType.plane, numXElements, numYElements); } -#if SYSTEM_DRAWING public SculptMesh(Bitmap sculptBitmap, SculptType sculptType, int lod, bool viewerMode) { _SculptMesh(sculptBitmap, sculptType, lod, viewerMode, false, false); @@ -184,14 +180,12 @@ public SculptMesh(Bitmap sculptBitmap, SculptType sculptType, int lod, bool view { _SculptMesh(sculptBitmap, sculptType, lod, viewerMode, mirror, invert); } -#endif - public SculptMesh(List> rows, SculptType sculptType, bool viewerMode, bool mirror, bool invert) + public SculptMesh(List> rows, SculptType sculptType, bool viewerMode, bool mirror, bool invert) { _SculptMesh(rows, sculptType, viewerMode, mirror, invert); } -#if SYSTEM_DRAWING /// /// converts a bitmap to a list of lists of coords, while scaling the image. /// the scaling is done in floating point so as to allow for reduced vertex position @@ -202,11 +196,11 @@ public SculptMesh(List> rows, SculptType sculptType, bool viewerMode /// /// /// - private List> bitmap2Coords(Bitmap bitmap, int scale, bool mirror) + private List> bitmap2Coords(Bitmap bitmap, int scale, bool mirror) { int numRows = bitmap.Height / scale; int numCols = bitmap.Width / scale; - List> rows = new List>(numRows); + List> rows = new List>(numRows); float pixScale = 1.0f / (scale * scale); pixScale /= 255; @@ -217,7 +211,7 @@ private List> bitmap2Coords(Bitmap bitmap, int scale, bool mirror) for (rowNdx = 0; rowNdx < numRows; rowNdx++) { - List row = new List(numCols); + List row = new List(numCols); for (colNdx = 0; colNdx < numCols; colNdx++) { imageX = colNdx * scale; @@ -243,9 +237,9 @@ private List> bitmap2Coords(Bitmap bitmap, int scale, bool mirror) } } if (mirror) - row.Add(new Coord(-(rSum * pixScale - 0.5f), gSum * pixScale - 0.5f, bSum * pixScale - 0.5f)); + row.Add(new(-(rSum * pixScale - 0.5f), gSum * pixScale - 0.5f, bSum * pixScale - 0.5f)); else - row.Add(new Coord(rSum * pixScale - 0.5f, gSum * pixScale - 0.5f, bSum * pixScale - 0.5f)); + row.Add(new(rSum * pixScale - 0.5f, gSum * pixScale - 0.5f, bSum * pixScale - 0.5f)); } rows.Add(row); @@ -253,11 +247,11 @@ private List> bitmap2Coords(Bitmap bitmap, int scale, bool mirror) return rows; } - private List> bitmap2CoordsSampled(Bitmap bitmap, int scale, bool mirror) + private List> bitmap2CoordsSampled(Bitmap bitmap, int scale, bool mirror) { int numRows = bitmap.Height / scale; int numCols = bitmap.Width / scale; - List> rows = new List>(numRows); + List> rows = new List>(numRows); float pixScale = 1.0f / 256.0f; @@ -267,7 +261,7 @@ private List> bitmap2CoordsSampled(Bitmap bitmap, int scale, bool mi for (rowNdx = 0; rowNdx <= numRows; rowNdx++) { - List row = new List(numCols); + List row = new List(numCols); imageY = rowNdx * scale; if (rowNdx == numRows) imageY--; for (colNdx = 0; colNdx <= numCols; colNdx++) @@ -283,9 +277,9 @@ private List> bitmap2CoordsSampled(Bitmap bitmap, int scale, bool mi } if (mirror) - row.Add(new Coord(-(c.R * pixScale - 0.5f), c.G * pixScale - 0.5f, c.B * pixScale - 0.5f)); + row.Add(new(-(c.R * pixScale - 0.5f), c.G * pixScale - 0.5f, c.B * pixScale - 0.5f)); else - row.Add(new Coord(c.R * pixScale - 0.5f, c.G * pixScale - 0.5f, c.B * pixScale - 0.5f)); + row.Add(new(c.R * pixScale - 0.5f, c.G * pixScale - 0.5f, c.B * pixScale - 0.5f)); } rows.Add(row); @@ -298,14 +292,13 @@ void _SculptMesh(Bitmap sculptBitmap, SculptType sculptType, int lod, bool viewe { _SculptMesh(new SculptMap(sculptBitmap, lod).ToRows(mirror), sculptType, viewerMode, mirror, invert); } -#endif - void _SculptMesh(List> rows, SculptType sculptType, bool viewerMode, bool mirror, bool invert) + void _SculptMesh(List> rows, SculptType sculptType, bool viewerMode, bool mirror, bool invert) { - coords = new List(); - faces = new List(); - normals = new List(); - uvs = new List(); + coords = []; + faces = []; + normals = []; + uvs = []; sculptType = (SculptType)(((int)sculptType) & 0x07); @@ -336,16 +329,16 @@ void _SculptMesh(List> rows, SculptType sculptType, bool viewerMode, } } - Coord topPole = rows[0][width / 2]; - Coord bottomPole = rows[rows.Count - 1][width / 2]; + Vector3 topPole = rows[0][width / 2]; + Vector3 bottomPole = rows[rows.Count - 1][width / 2]; if (sculptType == SculptType.sphere) { if (rows.Count % 2 == 0) { int count = rows[0].Count; - List topPoleRow = new List(count); - List bottomPoleRow = new List(count); + List topPoleRow = []; + List bottomPoleRow = []; for (int i = 0; i < count; i++) { @@ -359,8 +352,8 @@ void _SculptMesh(List> rows, SculptType sculptType, bool viewerMode, { int count = rows[0].Count; - List topPoleRow = rows[0]; - List bottomPoleRow = rows[rows.Count - 1]; + List topPoleRow = rows[0]; + List bottomPoleRow = rows[rows.Count - 1]; for (int i = 0; i < count; i++) { @@ -400,11 +393,11 @@ void _SculptMesh(List> rows, SculptType sculptType, bool viewerMode, p2 = p4 - coordsAcross; p1 = p3 - coordsAcross; - this.coords.Add(rows[imageY][imageX]); + coords.Add(rows[imageY][imageX]); if (viewerMode) { - this.normals.Add(new Coord()); - this.uvs.Add(new UVCoord(widthUnit * imageX, heightUnit * imageY)); + normals.Add(Vector3.Zero); + uvs.Add(new(widthUnit * imageX, heightUnit * imageY)); } if (imageY > 0 && imageX > 0) @@ -473,60 +466,65 @@ public SculptMesh Copy() public SculptMesh(SculptMesh sm) { - coords = new List(sm.coords); + coords = new List(sm.coords); faces = new List(sm.faces); viewerFaces = new List(sm.viewerFaces); - normals = new List(sm.normals); + normals = new List(sm.normals); uvs = new List(sm.uvs); } private void calcVertexNormals(SculptType sculptType, int xSize, int ySize) { // compute vertex normals by summing all the surface normals of all the triangles sharing // each vertex and then normalizing - int numFaces = this.faces.Count; - for (int i = 0; i < numFaces; i++) + for (int i = 0; i < faces.Count; i++) { - Face face = this.faces[i]; - Coord surfaceNormal = face.SurfaceNormal(this.coords); - this.normals[face.n1] += surfaceNormal; - this.normals[face.n2] += surfaceNormal; - this.normals[face.n3] += surfaceNormal; + Face face = faces[i]; + Vector3 surfaceNormal = face.SurfaceNormal(coords); + normals[face.n1] += surfaceNormal; + normals[face.n2] += surfaceNormal; + normals[face.n3] += surfaceNormal; } - int numNormals = this.normals.Count; - for (int i = 0; i < numNormals; i++) - this.normals[i] = this.normals[i].Normalize(); + for (int i = 0; i < normals.Count; i++) + { + Vector3 n = normals[i]; + n.Normalize(); + normals[i] = n; + } if (sculptType != SculptType.plane) { // blend the vertex normals at the cylinder seam - for (int y = 0; y < ySize; y++) + for (int rowOffsetA = 0; rowOffsetA < xSize * ySize; rowOffsetA += xSize) { - int rowOffset = y * xSize; - - this.normals[rowOffset] = this.normals[rowOffset + xSize - 1] = (this.normals[rowOffset] + this.normals[rowOffset + xSize - 1]).Normalize(); + int rowOffsetB = rowOffsetA + xSize - 1; + Vector3 v = normals[rowOffsetA] + normals[rowOffsetB]; + v.Normalize(); + normals[rowOffsetA] = normals[rowOffsetB] = v; } } - foreach (Face face in this.faces) + foreach (Face face in faces) { - ViewerFace vf = new ViewerFace(0); - vf.v1 = this.coords[face.v1]; - vf.v2 = this.coords[face.v2]; - vf.v3 = this.coords[face.v3]; + ViewerFace vf = new(0) + { + v1 = coords[face.v1], + v2 = coords[face.v2], + v3 = coords[face.v3], - vf.coordIndex1 = face.v1; - vf.coordIndex2 = face.v2; - vf.coordIndex3 = face.v3; + coordIndex1 = face.v1, + coordIndex2 = face.v2, + coordIndex3 = face.v3, - vf.n1 = this.normals[face.n1]; - vf.n2 = this.normals[face.n2]; - vf.n3 = this.normals[face.n3]; + n1 = normals[face.n1], + n2 = normals[face.n2], + n3 = normals[face.n3], - vf.uv1 = this.uvs[face.uv1]; - vf.uv2 = this.uvs[face.uv2]; - vf.uv3 = this.uvs[face.uv3]; + uv1 = uvs[face.uv1], + uv2 = uvs[face.uv2], + uv3 = uvs[face.uv3] + }; - this.viewerFaces.Add(vf); + viewerFaces.Add(vf); } } @@ -538,28 +536,17 @@ private void calcVertexNormals(SculptType sculptType, int xSize, int ySize) /// public void AddPos(float x, float y, float z) { - int i; - int numVerts = this.coords.Count; - Coord vert; - - for (i = 0; i < numVerts; i++) - { - vert = this.coords[i]; - vert.X += x; - vert.Y += y; - vert.Z += z; - this.coords[i] = vert; - } + Vector3 v = new(x, y, z); + for (int i = 0; i < coords.Count; i++) + coords[i] += v; - if (this.viewerFaces != null) + if (viewerFaces != null) { - int numViewerFaces = this.viewerFaces.Count; - - for (i = 0; i < numViewerFaces; i++) + for (int i = 0; i < viewerFaces.Count; i++) { - ViewerFace v = this.viewerFaces[i]; - v.AddPos(x, y, z); - this.viewerFaces[i] = v; + ViewerFace vf = viewerFaces[i]; + vf.AddPos(v); + viewerFaces[i] = vf; } } } @@ -568,57 +555,40 @@ public void AddPos(float x, float y, float z) /// Rotates the mesh /// /// - public void AddRot(Quat q) + public void AddRot(Quaternion q) { - int i; - int numVerts = this.coords.Count; - - for (i = 0; i < numVerts; i++) - this.coords[i] *= q; + if(q.IsIdentity()) + return; + for (int i = 0; i < coords.Count; i++) + coords[i] *= q; - int numNormals = this.normals.Count; - for (i = 0; i < numNormals; i++) - this.normals[i] *= q; + for (int i = 0; i < normals.Count; i++) + normals[i] *= q; - if (this.viewerFaces != null) + if (viewerFaces != null) { - int numViewerFaces = this.viewerFaces.Count; - - for (i = 0; i < numViewerFaces; i++) + for (int i = 0; i < viewerFaces.Count; i++) { - ViewerFace v = this.viewerFaces[i]; - v.v1 *= q; - v.v2 *= q; - v.v3 *= q; - - v.n1 *= q; - v.n2 *= q; - v.n3 *= q; - - this.viewerFaces[i] = v; + ViewerFace vf = viewerFaces[i]; + vf.AddRot(q); + viewerFaces[i] = vf; } } } public void Scale(float x, float y, float z) { - int i; - int numVerts = this.coords.Count; - - Coord m = new Coord(x, y, z); - for (i = 0; i < numVerts; i++) - this.coords[i] *= m; + Vector3 m = new(x, y, z); + for (int i = 0; i < coords.Count; i++) + coords[i] *= m; - if (this.viewerFaces != null) + if (viewerFaces != null) { - int numViewerFaces = this.viewerFaces.Count; - for (i = 0; i < numViewerFaces; i++) + for (int i = 0; i < viewerFaces.Count; i++) { - ViewerFace v = this.viewerFaces[i]; - v.v1 *= m; - v.v2 *= m; - v.v3 *= m; - this.viewerFaces[i] = v; + ViewerFace vf = viewerFaces[i]; + vf.Scale(m); + viewerFaces[i] = vf; } } } @@ -631,12 +601,10 @@ public void DumpRaw(String path, String name, String title) String completePath = System.IO.Path.Combine(path, fileName); StreamWriter sw = new StreamWriter(completePath); - for (int i = 0; i < this.faces.Count; i++) + for (int i = 0; i < faces.Count; i++) { - string s = this.coords[this.faces[i].v1].ToString(); - s += " " + this.coords[this.faces[i].v2].ToString(); - s += " " + this.coords[this.faces[i].v3].ToString(); - + Face face = faces[i]; + string s = $"{coords[face.v1]} {coords[face.v2]} {coords[face.v3]}"; sw.WriteLine(s); } diff --git a/PrimMesher/VertexIndexer.cs b/PrimMesher/VertexIndexer.cs index f8ba3e6e..01bc2050 100644 --- a/PrimMesher/VertexIndexer.cs +++ b/PrimMesher/VertexIndexer.cs @@ -28,16 +28,17 @@ using System; using System.Collections.Generic; +using OpenMetaverse; namespace PrimMesher { public struct ViewerVertex { - public Coord v; - public Coord n; + public Vector3 v; + public Vector3 n; public UVCoord uv; - public ViewerVertex(Coord coord, Coord normal, UVCoord uv) + public ViewerVertex(Vector3 coord, Vector3 normal, UVCoord uv) { this.v = coord; this.n = normal; From 859b8df17d71a24076de1418f6726d29a3f1c1ea Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Thu, 14 Aug 2025 20:20:13 +0100 Subject: [PATCH 137/149] sync with local work (not all csj2k) --- .../MeshmerizerR.cs | 162 +++++++++++++++--- OpenMetaverse/Assets/AssetTypes/AssetMesh.cs | 1 + OpenMetaverse/_Packets_.cs | 121 ++++++++++++- OpenMetaverseTypes/EnumsPrimitive.cs | 2 + OpenMetaverseTypes/Matrix3x3.cs | 1 - OpenMetaverseTypes/OSUTF8.cs | 1 - OpenMetaverseTypes/UtilsConversions.cs | 8 +- OpenMetaverseTypes/Vector3.cs | 1 - OpenMetaverseTypes/Vector4.cs | 1 + PrimMesher/ObjMesh.cs | 4 - PrimMesher/PrimMesher.cs | 19 +- PrimMesher/SculptMap.cs | 2 +- PrimMesher/SculptMesh.cs | 13 +- data/message_template.msg | 7 + 14 files changed, 278 insertions(+), 65 deletions(-) diff --git a/OpenMetaverse.Rendering.Meshmerizer/MeshmerizerR.cs b/OpenMetaverse.Rendering.Meshmerizer/MeshmerizerR.cs index b6e1981d..fd900ee9 100644 --- a/OpenMetaverse.Rendering.Meshmerizer/MeshmerizerR.cs +++ b/OpenMetaverse.Rendering.Meshmerizer/MeshmerizerR.cs @@ -31,6 +31,7 @@ * using PrimMesher (http://forge.opensimulator.org/projects/primmesher). */ +using PrimMesher; using System; using System.Collections.Generic; using OMV = OpenMetaverse; @@ -107,6 +108,95 @@ public OMVR.SimpleMesh GenerateSimpleSculptMesh(OMV.Primitive prim, System.Drawi return null; } + public static FacetedMesh m_BasicBoxMesh = null; + private static readonly object m_BasicBoxMeshLock = new(); + public static List m_indexs_012213 = [0, 1, 2, 2, 1, 3]; + public static FacetedMesh GetBasicBoxMesh() + { + if(m_BasicBoxMesh == null) + { + lock (m_BasicBoxMeshLock) + { + m_BasicBoxMesh ??= new() + { + Faces = + [ + new Face() + { + Vertices = + [ + new() { Position = new(-0.5f, -0.5f, 0.5f), Normal = Vector3.UnitZ, TexCoord = new(0f, 0f)}, + new() { Position = new( 0.5f, -0.5f, 0.5f), Normal = Vector3.UnitZ, TexCoord = new(1f, 0f)}, + new() { Position = new( 0.5f, 0.5f, 0.5f), Normal = Vector3.UnitZ, TexCoord = new(1f, 1f)}, + new() { Position = new(-0.5f, 0.5f, 0.5f), Normal = Vector3.UnitZ, TexCoord = new(0f, 1f)}, + ], + Indices = [0, 1, 2, 0, 2, 3], + }, + new Face() + { + Vertices = + [ + new() { Position = new(-0.5f, -0.5f, 0.5f), Normal = -Vector3.UnitY, TexCoord = new(0f, 1f)}, + new() { Position = new(-0.5f, -0.5f, -0.5f), Normal = -Vector3.UnitY, TexCoord = new(0f, 0f)}, + new() { Position = new( 0.5f, -0.5f, 0.5f), Normal = -Vector3.UnitY, TexCoord = new(1f, 1f)}, + new() { Position = new( 0.5f, -0.5f, -0.5f), Normal = -Vector3.UnitY, TexCoord = new(1f, 0f)}, + ], + Indices = m_indexs_012213, + }, + new Face() + { + Vertices = + [ + new() { Position = new( 0.5f, -0.5f, 0.5f), Normal = Vector3.UnitX, TexCoord = new(0f, 1f)}, + new() { Position = new( 0.5f, -0.5f, -0.5f), Normal = Vector3.UnitX, TexCoord = new(0f, 0f)}, + new() { Position = new( 0.5f, 0.5f, 0.5f), Normal = Vector3.UnitX, TexCoord = new(1f, 1f)}, + new() { Position = new( 0.5f, 0.5f, -0.5f), Normal = Vector3.UnitX, TexCoord = new(1f, 0f)}, + ], + Indices = m_indexs_012213, + }, + new Face() + { + Vertices = + [ + new() { Position = new( 0.5f, 0.5f, 0.5f), Normal = Vector3.UnitY, TexCoord = new(0f, 1f)}, + new() { Position = new( 0.5f, 0.5f, -0.5f), Normal = Vector3.UnitY, TexCoord = new(0f, 0f)}, + new() { Position = new( -0.5f, 0.5f, 0.5f), Normal = Vector3.UnitY, TexCoord = new(1f, 1f)}, + new() { Position = new( -0.5f, 0.5f, -0.5f), Normal = Vector3.UnitY, TexCoord = new(1f, 0f)}, + ], + Indices = m_indexs_012213, + }, + new Face() + { + Vertices = + [ + new() { Position = new( -0.5f, 0.5f, 0.5f), Normal = -Vector3.UnitX, TexCoord = new(0f, 1f)}, + new() { Position = new( -0.5f, 0.5f, -0.5f), Normal = -Vector3.UnitX, TexCoord = new(0f, 0f)}, + new() { Position = new( -0.5f, -0.5f, 0.5f), Normal = -Vector3.UnitX, TexCoord = new(1f, 1f)}, + new() { Position = new( -0.5f, -0.5f, -0.5f), Normal = -Vector3.UnitX, TexCoord = new(1f, 0f)}, + ], + Indices = m_indexs_012213, + }, + new Face() + { + Vertices = + [ + new() { Position = new( 0.5f, 0.5f, -0.5f), Normal = -Vector3.UnitZ, TexCoord = new(1f, 0f)}, + new() { Position = new( 0.5f, -0.5f, -0.5f), Normal = -Vector3.UnitZ, TexCoord = new(1f, 1f)}, + new() { Position = new( -0.5f, -0.5f, -0.5f), Normal = -Vector3.UnitZ, TexCoord = new(0f, 1f)}, + new() { Position = new( -0.5f, 0.5f, -0.5f), Normal = -Vector3.UnitZ, TexCoord = new(0f, 0f)}, + ], + Indices = [0, 1, 2, 3, 0, 2], + }, + ] + }; + } + } + + return m_BasicBoxMesh; + } + + + /// /// Generates a a series of faces, each face containing a mesh and /// metadata @@ -116,6 +206,22 @@ public OMVR.SimpleMesh GenerateSimpleSculptMesh(OMV.Primitive prim, System.Drawi /// The generated mesh public OMVR.FacetedMesh GenerateFacetedMesh(OMV.Primitive prim, OMVR.DetailLevel lod) { + OMV.ProfileCurve profileCurve = (OMV.ProfileCurve)(prim.PrimData.profileCurve & 0x07); + + if ( profileCurve == OMV.ProfileCurve.Square && prim.PrimData.PathCurve == OMV.PathCurve.Line) + { + if( prim.PrimData.ProfileHole == 0 && + prim.PrimData.ProfileBegin == 0f && prim.PrimData.ProfileEnd == 1f && + prim.PrimData.PathBegin == 0f && prim.PrimData.PathEnd == 1f && + prim.PrimData.PathScaleX == 1f && prim.PrimData.PathScaleY == 1f && + prim.PrimData.PathShearX == 0 && prim.PrimData.PathShearY == 0 && + prim.PrimData.PathRevolutions == 1f + ) + { + return GetBasicBoxMesh(); + } + } + PrimMesher.PrimMesh newPrim = GeneratePrimMesh(prim, lod, true); if (newPrim == null) return null; @@ -322,16 +428,16 @@ public void TransformTexCoords(List vertices, OMV.Vector3 center, O private PrimMesher.PrimMesh GeneratePrimMesh(Primitive prim, DetailLevel lod, bool viewerMode) { - OMV.Primitive.ConstructionData primData = prim.PrimData; int sides = 4; int hollowsides = 4; - float profileBegin = primData.ProfileBegin; - float profileEnd = primData.ProfileEnd; + float profileBegin = prim.PrimData.ProfileBegin; + float profileEnd = prim.PrimData.ProfileEnd; bool isSphere = false; - if ((OMV.ProfileCurve)(primData.profileCurve & 0x07) == OMV.ProfileCurve.Circle) + OMV.ProfileCurve profileCurve = (OMV.ProfileCurve)(prim.PrimData.profileCurve & 0x07); + if (profileCurve == OMV.ProfileCurve.Circle) { switch (lod) { @@ -346,9 +452,9 @@ private PrimMesher.PrimMesh GeneratePrimMesh(Primitive prim, DetailLevel lod, bo break; } } - else if ((OMV.ProfileCurve)(primData.profileCurve & 0x07) == OMV.ProfileCurve.EqualTriangle) + else if (profileCurve == OMV.ProfileCurve.EqualTriangle) sides = 3; - else if ((OMV.ProfileCurve)(primData.profileCurve & 0x07) == OMV.ProfileCurve.HalfCircle) + else if (profileCurve == OMV.ProfileCurve.HalfCircle) { // half circle, prim is a sphere isSphere = true; @@ -368,9 +474,9 @@ private PrimMesher.PrimMesh GeneratePrimMesh(Primitive prim, DetailLevel lod, bo profileEnd = 0.5f * profileEnd + 0.5f; } - if ((OMV.HoleType)primData.ProfileHole == OMV.HoleType.Same) + if ((OMV.HoleType)prim.PrimData.ProfileHole == OMV.HoleType.Same) hollowsides = sides; - else if ((OMV.HoleType)primData.ProfileHole == OMV.HoleType.Circle) + else if (prim.PrimData.ProfileHole == OMV.HoleType.Circle) { switch (lod) { @@ -385,21 +491,21 @@ private PrimMesher.PrimMesh GeneratePrimMesh(Primitive prim, DetailLevel lod, bo break; } } - else if ((OMV.HoleType)primData.ProfileHole == OMV.HoleType.Triangle) + else if (prim.PrimData.ProfileHole == OMV.HoleType.Triangle) hollowsides = 3; - PrimMesher.PrimMesh newPrim = new PrimMesher.PrimMesh(sides, profileBegin, profileEnd, (float)primData.ProfileHollow, hollowsides); + PrimMesher.PrimMesh newPrim = new(sides, profileBegin, profileEnd, prim.PrimData.ProfileHollow, hollowsides); newPrim.viewerMode = viewerMode; newPrim.sphereMode = isSphere; - newPrim.holeSizeX = primData.PathScaleX; - newPrim.holeSizeY = primData.PathScaleY; - newPrim.pathCutBegin = primData.PathBegin; - newPrim.pathCutEnd = primData.PathEnd; - newPrim.topShearX = primData.PathShearX; - newPrim.topShearY = primData.PathShearY; - newPrim.radius = primData.PathRadiusOffset; - newPrim.revolutions = primData.PathRevolutions; - newPrim.skew = primData.PathSkew; + newPrim.holeSizeX = prim.PrimData.PathScaleX; + newPrim.holeSizeY = prim.PrimData.PathScaleY; + newPrim.pathCutBegin = prim.PrimData.PathBegin; + newPrim.pathCutEnd = prim.PrimData.PathEnd; + newPrim.topShearX = prim.PrimData.PathShearX; + newPrim.topShearY = prim.PrimData.PathShearY; + newPrim.radius = prim.PrimData.PathRadiusOffset; + newPrim.revolutions = prim.PrimData.PathRevolutions; + newPrim.skew = prim.PrimData.PathSkew; switch (lod) { case OMVR.DetailLevel.Low: @@ -413,20 +519,20 @@ private PrimMesher.PrimMesh GeneratePrimMesh(Primitive prim, DetailLevel lod, bo break; } - if ((primData.PathCurve == OMV.PathCurve.Line) || (primData.PathCurve == OMV.PathCurve.Flexible)) + if ((prim.PrimData.PathCurve == OMV.PathCurve.Line) || (prim.PrimData.PathCurve == OMV.PathCurve.Flexible)) { - newPrim.taperX = 1.0f - primData.PathScaleX; - newPrim.taperY = 1.0f - primData.PathScaleY; - newPrim.twistBegin = (int)(180 * primData.PathTwistBegin); - newPrim.twistEnd = (int)(180 * primData.PathTwist); + newPrim.taperX = 1.0f - prim.PrimData.PathScaleX; + newPrim.taperY = 1.0f - prim.PrimData.PathScaleY; + newPrim.twistBegin = (int)(180 * prim.PrimData.PathTwistBegin); + newPrim.twistEnd = (int)(180 * prim.PrimData.PathTwist); newPrim.ExtrudeLinear(); } else { - newPrim.taperX = primData.PathTaperX; - newPrim.taperY = primData.PathTaperY; - newPrim.twistBegin = (int)(360 * primData.PathTwistBegin); - newPrim.twistEnd = (int)(360 * primData.PathTwist); + newPrim.taperX = prim.PrimData.PathTaperX; + newPrim.taperY = prim.PrimData.PathTaperY; + newPrim.twistBegin = (int)(360 * prim.PrimData.PathTwistBegin); + newPrim.twistEnd = (int)(360 * prim.PrimData.PathTwist); newPrim.ExtrudeCircular(); } diff --git a/OpenMetaverse/Assets/AssetTypes/AssetMesh.cs b/OpenMetaverse/Assets/AssetTypes/AssetMesh.cs index 2453314b..7dab3d3a 100644 --- a/OpenMetaverse/Assets/AssetTypes/AssetMesh.cs +++ b/OpenMetaverse/Assets/AssetTypes/AssetMesh.cs @@ -75,6 +75,7 @@ public override bool Decode() { OSDMap header = (OSDMap)OSDParser.DeserializeLLSDBinary(data); MeshData["asset_header"] = header; + long start = data.Position; foreach(string partName in header.Keys) diff --git a/OpenMetaverse/_Packets_.cs b/OpenMetaverse/_Packets_.cs index d0d2265f..7d20b50c 100644 --- a/OpenMetaverse/_Packets_.cs +++ b/OpenMetaverse/_Packets_.cs @@ -33858,20 +33858,61 @@ public override void ToBytes(byte[] bytes, ref int i) } + /// + public sealed class OptionsBlock : PacketBlock + { + public uint Flags; + + public override int Length + { + get + { + return 4; + } + } + + public OptionsBlock() { } + public OptionsBlock(byte[] bytes, ref int i) + { + FromBytes(bytes, ref i); + } + + public override void FromBytes(byte[] bytes, ref int i) + { + try + { + Flags = Utils.BytesToUIntSafepos(bytes, i); i += 4; + } + catch (Exception) + { + throw new MalformedDataException(); + } + } + + public override void ToBytes(byte[] bytes, ref int i) + { + Utils.UIntToBytesSafepos(Flags, bytes, i); i += 4; + } + + } + public override int Length { get { - int length = 10; + int length = 11; length += Data.Length; + for (int j = 0; j < Options.Length; j++) + length += Options[j].Length; return length; } } public DataBlock Data; + public OptionsBlock[] Options; public ScriptTeleportRequestPacket() { - HasVariableBlocks = false; + HasVariableBlocks = true; Type = PacketType.ScriptTeleportRequest; Header = new Header(); Header.Frequency = PacketFrequency.Low; @@ -33879,6 +33920,7 @@ public ScriptTeleportRequestPacket() Header.Reliable = true; NeedValidateIDs = false; Data = new DataBlock(); + Options = null; } public ScriptTeleportRequestPacket(byte[] bytes, ref int i) : this() @@ -33896,6 +33938,14 @@ override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[ bytes = zeroBuffer; } Data.FromBytes(bytes, ref i); + int count = (int)bytes[i++]; + if(Options == null || Options.Length != -1) { + Options = new OptionsBlock[count]; + for(int j = 0; j < count; j++) + { Options[j] = new OptionsBlock(); } + } + for (int j = 0; j < count; j++) + { Options[j].FromBytes(bytes, ref i); } } public ScriptTeleportRequestPacket(Header head, byte[] bytes, ref int i): this() @@ -33907,24 +33957,89 @@ override public void FromBytes(Header header, byte[] bytes, ref int i) { Header = header; Data.FromBytes(bytes, ref i); + int count = (int)bytes[i++]; + if(Options == null || Options.Length != count) { + Options = new OptionsBlock[count]; + for(int j = 0; j < count; j++) + { Options[j] = new OptionsBlock(); } + } + for (int j = 0; j < count; j++) + { Options[j].FromBytes(bytes, ref i); } } public override byte[] ToBytes() { int length = 10; length += Data.Length; + length++; + for (int j = 0; j < Options.Length; j++) { length += Options[j].Length; } if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; } byte[] bytes = new byte[length]; int i = 0; Header.ToBytes(bytes, ref i); Data.ToBytes(bytes, ref i); + Utils.ByteToBytes((byte)Options.Length, bytes, ref i); + for (int j = 0; j < Options.Length; j++) { Options[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; } public override byte[][] ToBytesMultiple() { - return new byte[][] { ToBytes() }; + System.Collections.Generic.List packets = new System.Collections.Generic.List(); + int i = 0; + int fixedLength = 10; + + byte[] ackBytes = null; + int acksLength = 0; + if (Header.AckList != null && Header.AckList.Length > 0) { + Header.AppendedAcks = true; + ackBytes = new byte[Header.AckList.Length * 4 + 1]; + Header.AcksToBytes(ackBytes, ref acksLength); + } + + fixedLength += Data.Length; + byte[] fixedBytes = new byte[fixedLength]; + Header.ToBytes(fixedBytes, ref i); + Data.ToBytes(fixedBytes, ref i); + fixedLength += 1; + + int OptionsStart = 0; + do + { + int variableLength = 0; + int OptionsCount = 0; + + i = OptionsStart; + while (fixedLength + variableLength + acksLength < Packet.MTU && i < Options.Length) { + int blockLength = Options[i].Length; + if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == OptionsStart) { + variableLength += blockLength; + ++OptionsCount; + } + else { break; } + ++i; + } + + byte[] packet = new byte[fixedLength + variableLength + acksLength]; + int length = fixedBytes.Length; + Buffer.BlockCopy(fixedBytes, 0, packet, 0, length); + if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); } + + packet[length++] = (byte)OptionsCount; + for (i = OptionsStart; i < OptionsStart + OptionsCount; i++) { Options[i].ToBytes(packet, ref length); } + OptionsStart += OptionsCount; + + if (acksLength > 0) { + Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength); + acksLength = 0; + } + + packets.Add(packet); + } while ( + OptionsStart < Options.Length); + + return packets.ToArray(); } } diff --git a/OpenMetaverseTypes/EnumsPrimitive.cs b/OpenMetaverseTypes/EnumsPrimitive.cs index 47d2568f..e72a4938 100644 --- a/OpenMetaverseTypes/EnumsPrimitive.cs +++ b/OpenMetaverseTypes/EnumsPrimitive.cs @@ -275,6 +275,8 @@ public enum SculptType : byte /// Mesh = 5, /// + llGLTF = 6, + /// Invert = 64, /// Mirror = 128 diff --git a/OpenMetaverseTypes/Matrix3x3.cs b/OpenMetaverseTypes/Matrix3x3.cs index 38178de6..6e115a7e 100644 --- a/OpenMetaverseTypes/Matrix3x3.cs +++ b/OpenMetaverseTypes/Matrix3x3.cs @@ -309,7 +309,6 @@ public static Matrix3x3 Add(Matrix3x3 matrix1, in Matrix3x3 matrix2) public static Matrix3x3 CreateFromAxisAngle(Vector3 axis, float angle) { - float x = axis.X; float y = axis.Y; float z = axis.Z; diff --git a/OpenMetaverseTypes/OSUTF8.cs b/OpenMetaverseTypes/OSUTF8.cs index 7eb931cc..b4ccb0f6 100644 --- a/OpenMetaverseTypes/OSUTF8.cs +++ b/OpenMetaverseTypes/OSUTF8.cs @@ -346,7 +346,6 @@ public unsafe bool ACSIILowerEquals(osUTF8 o) return true; } - public unsafe bool ACSIILowerEquals(osUTF8Slice o) { if (o is null || m_len != o.m_len) diff --git a/OpenMetaverseTypes/UtilsConversions.cs b/OpenMetaverseTypes/UtilsConversions.cs index b990fd31..259fd471 100644 --- a/OpenMetaverseTypes/UtilsConversions.cs +++ b/OpenMetaverseTypes/UtilsConversions.cs @@ -1219,7 +1219,6 @@ public static unsafe void Int16ToBytes(short value, byte* dest) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static unsafe void Int16ToBytes(short value, byte* dest, int pos) { - *(short*)dest[pos] = value; } @@ -1328,6 +1327,7 @@ public unsafe static void IntToBytes(int value, ref byte dest) { Unsafe.WriteUnaligned(ref dest, value); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void IntToBytes(int value, byte* dest, int pos) { @@ -1947,7 +1947,7 @@ public static string BytesToHexString(byte[] bytes, int length, string fieldName if (i != 0) output.Append('\n'); - if (!String.IsNullOrEmpty(fieldName)) + if (!string.IsNullOrEmpty(fieldName)) { output.Append(fieldName); output.Append(": "); @@ -1961,7 +1961,7 @@ public static string BytesToHexString(byte[] bytes, int length, string fieldName if (j != 0) output.Append(' '); - output.Append(String.Format("{0:X2}", bytes[k])); + output.Append(string.Format("{0:X2}", bytes[k])); } } @@ -2684,7 +2684,7 @@ public unsafe static byte HexToByte(char* hex, int pos) /// The converted byte array public unsafe static byte[] HexStringToBytes(string hexString, bool handleDirty) { - if (String.IsNullOrEmpty(hexString)) + if (string.IsNullOrEmpty(hexString)) return EmptyBytes; if (handleDirty) { diff --git a/OpenMetaverseTypes/Vector3.cs b/OpenMetaverseTypes/Vector3.cs index a49bfb21..ebf65927 100644 --- a/OpenMetaverseTypes/Vector3.cs +++ b/OpenMetaverseTypes/Vector3.cs @@ -292,7 +292,6 @@ public readonly bool ApproxEquals(Vector3 vec, float tolerance) Utils.ApproxEqual(Z, vec.Z, tolerance); } - [MethodImpl(MethodImplOptions.AggressiveInlining)] public readonly bool ApproxZero() { diff --git a/OpenMetaverseTypes/Vector4.cs b/OpenMetaverseTypes/Vector4.cs index ab68cf8e..6ac85d88 100644 --- a/OpenMetaverseTypes/Vector4.cs +++ b/OpenMetaverseTypes/Vector4.cs @@ -607,6 +607,7 @@ public static bool TryParse(ReadOnlySpan sp, out Vector4 result) result = Zero; return false; } + int start = 0; int comma = 0; char c; diff --git a/PrimMesher/ObjMesh.cs b/PrimMesher/ObjMesh.cs index 12f3174e..799bd238 100644 --- a/PrimMesher/ObjMesh.cs +++ b/PrimMesher/ObjMesh.cs @@ -55,13 +55,11 @@ public ObjMesh(string path) ProcessStream(new StreamReader(path)); } - public ObjMesh(StreamReader sr) { ProcessStream(sr); } - private void ProcessStream(StreamReader s) { numPrimFaces = 0; @@ -88,7 +86,6 @@ public VertexIndexer GetVertexIndexer() return vi; } - private void ProcessTokens(string[] tokens) { switch (tokens[0].ToLower()) @@ -181,7 +178,6 @@ private void ProcessTokens(string[] tokens) } } - private void MakePrimFace() { if (faceVertices.Count > 0 && facePolygons.Count > 0) diff --git a/PrimMesher/PrimMesher.cs b/PrimMesher/PrimMesher.cs index 136d1220..dd242a8f 100644 --- a/PrimMesher/PrimMesher.cs +++ b/PrimMesher/PrimMesher.cs @@ -587,7 +587,6 @@ public Profile(int sides, float profileStart, float profileEnd, try { angles.makeAngles(sides, startAngle, stopAngle); } catch (Exception ex) { - errorMessage = "makeAngles failed: Exception: " + ex.ToString() + "\nsides: " + sides.ToString() + " startAngle: " + startAngle.ToString() + " stopAngle: " + stopAngle.ToString(); @@ -886,7 +885,6 @@ public Profile(int sides, float profileStart, float profileEnd, numPrimFaces = faceNum; } - } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -1041,12 +1039,12 @@ public void AddValue2FaceNormalIndices(int num) } } - public void DumpRaw(String path, String name, String title) + public void DumpRaw(string path, string name, string title) { if (path == null) return; - String fileName = name + "_" + title + ".raw"; - String completePath = System.IO.Path.Combine(path, fileName); + string fileName = name + "_" + title + ".raw"; + string completePath = System.IO.Path.Combine(path, fileName); StreamWriter sw = new(completePath); for (int i = 0; i < faces.Count; i++) @@ -1474,6 +1472,7 @@ public void Extrude(PathType pathType) // sanity checks float initialProfileRot = 0.0f; + if (pathType == PathType.Circular) { if (sides == 3) @@ -1888,8 +1887,6 @@ public void Extrude(PathType pathType) viewerFaces.Add(newViewerFace); } } - - } // for (int nodeIndex = 0; nodeIndex < path.pathNodes.Count; nodeIndex++) } @@ -2087,9 +2084,7 @@ public void Scale(float x, float y, float z) face.Scale(scale); viewerFaces[i] = face; } - } - } /// @@ -2098,12 +2093,12 @@ public void Scale(float x, float y, float z) /// /// /// - public void DumpRaw(String path, String name, String title) + public void DumpRaw(string path, string name, string title) { if (path == null) return; - String fileName = name + "_" + title + ".raw"; - String completePath = System.IO.Path.Combine(path, fileName); + string fileName = name + "_" + title + ".raw"; + string completePath = System.IO.Path.Combine(path, fileName); using StreamWriter sw = new(completePath); diff --git a/PrimMesher/SculptMap.cs b/PrimMesher/SculptMap.cs index a1d3daa8..cb9009f4 100644 --- a/PrimMesher/SculptMap.cs +++ b/PrimMesher/SculptMap.cs @@ -144,7 +144,7 @@ public List> ToRows(bool mirror) List> rows = new List>(numRows); - float pixScale = 1.0f / 255; + const float pixScale = 1.0f / 255.0f; int rowNdx, colNdx; int smNdx = 0; diff --git a/PrimMesher/SculptMesh.cs b/PrimMesher/SculptMesh.cs index e1681315..2102b028 100644 --- a/PrimMesher/SculptMesh.cs +++ b/PrimMesher/SculptMesh.cs @@ -26,7 +26,6 @@ */ // to build without references to System.Drawing, comment this out -#define SYSTEM_DRAWING using System; using System.Collections.Generic; @@ -37,7 +36,6 @@ namespace PrimMesher { - public class SculptMesh { public List coords; @@ -49,8 +47,6 @@ public class SculptMesh public enum SculptType { sphere = 1, torus = 2, plane = 3, cylinder = 4 }; -#if SYSTEM_DRAWING - public SculptMesh SculptMeshFromFile(string fileName, SculptType sculptType, int lod, bool viewerMode) { Bitmap bitmap = (Bitmap)Bitmap.FromFile(fileName); @@ -66,7 +62,6 @@ public SculptMesh(string fileName, int sculptType, int lod, int viewerMode, int _SculptMesh(bitmap, (SculptType)sculptType, lod, viewerMode != 0, mirror != 0, invert != 0); bitmap.Dispose(); } -#endif /// /// ** Experimental ** May disappear from future versions ** not recommeneded for use in applications @@ -287,7 +282,6 @@ private List> bitmap2CoordsSampled(Bitmap bitmap, int scale, bool return rows; } - void _SculptMesh(Bitmap sculptBitmap, SculptType sculptType, int lod, bool viewerMode, bool mirror, bool invert) { _SculptMesh(new SculptMap(sculptBitmap, lod).ToRows(mirror), sculptType, viewerMode, mirror, invert); @@ -592,13 +586,12 @@ public void Scale(float x, float y, float z) } } } - - public void DumpRaw(String path, String name, String title) + public void DumpRaw(string path, string name, string title) { if (path == null) return; - String fileName = name + "_" + title + ".raw"; - String completePath = System.IO.Path.Combine(path, fileName); + string fileName = name + "_" + title + ".raw"; + string completePath = System.IO.Path.Combine(path, fileName); StreamWriter sw = new StreamWriter(completePath); for (int i = 0; i < faces.Count; i++) diff --git a/data/message_template.msg b/data/message_template.msg index 23d595fc..8235623e 100755 --- a/data/message_template.msg +++ b/data/message_template.msg @@ -4353,6 +4353,9 @@ version 2.0 } // ScriptTeleportRequest +// Interestingly, this message does not actually "Request a Teleport" +// on the viewer. Instead it opens the world map and places a beacon +// at the indicated location. // reliable { ScriptTeleportRequest Low 195 Trusted Unencoded @@ -4363,6 +4366,10 @@ version 2.0 { SimPosition LLVector3 } { LookAt LLVector3 } } + { + Options Variable + { Flags U32 } + } } From 1c1f4892679135bc9de9a2142e61a3b43145b829 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Thu, 14 Aug 2025 20:25:52 +0100 Subject: [PATCH 138/149] minor change on github action --- .github/workflows/dotnet.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index b1bc9015..ee57c08c 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -41,7 +41,7 @@ jobs: message: | ${{ github.actor }} pushed to ${{ github.repository }} ${{ join(github.event.commits.*.message, '\n') }} - mono compile: ${{ steps.build.conclusion }} + dotnet compile: ${{ steps.build.conclusion }} - name: report manual irc if: github.event_name == 'workflow_dispatch' uses: rectalogic/notify-irc@v1 From 590cdafbcee70c56e32b3f6913a2056aca19f24c Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Thu, 14 Aug 2025 21:29:41 +0100 Subject: [PATCH 139/149] a code line is back from holidays --- PrimMesher/PrimMesher.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/PrimMesher/PrimMesher.cs b/PrimMesher/PrimMesher.cs index dd242a8f..098eaf01 100644 --- a/PrimMesher/PrimMesher.cs +++ b/PrimMesher/PrimMesher.cs @@ -633,6 +633,7 @@ public Profile(int sides, float profileStart, float profileEnd, angle = hollowAngles.angles[i]; newVert.X = hollow * xScale * angle.X; newVert.Y = hollow * yScale * angle.Y; + hollowCoords.Add(newVert); if (calcVertexNormals) { From 072fa6bf952bad8d48e904c0d33601611d61c099 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Tue, 10 Mar 2026 15:57:46 +0000 Subject: [PATCH 140/149] some cosmetics on DoubleDictionary --- .../MeshmerizerR.cs | 8 +- OpenMetaverseTypes/DoubleDictionary.cs | 41 ++--------- OpenMetaverseTypes/Quaternion.cs | 73 ++++++++++++++----- 3 files changed, 68 insertions(+), 54 deletions(-) diff --git a/OpenMetaverse.Rendering.Meshmerizer/MeshmerizerR.cs b/OpenMetaverse.Rendering.Meshmerizer/MeshmerizerR.cs index fd900ee9..4fe280fe 100644 --- a/OpenMetaverse.Rendering.Meshmerizer/MeshmerizerR.cs +++ b/OpenMetaverse.Rendering.Meshmerizer/MeshmerizerR.cs @@ -110,7 +110,9 @@ public OMVR.SimpleMesh GenerateSimpleSculptMesh(OMV.Primitive prim, System.Drawi public static FacetedMesh m_BasicBoxMesh = null; private static readonly object m_BasicBoxMeshLock = new(); - public static List m_indexs_012213 = [0, 1, 2, 2, 1, 3]; + public static List m_indexs_012023 = [0, 1, 2, 0, 2, 3]; + public static List m_indexs_012213 = [0, 1, 2, 2, 1, 3]; + public static List m_indexs_012302 = [0, 1, 2, 3, 0, 2]; public static FacetedMesh GetBasicBoxMesh() { if(m_BasicBoxMesh == null) @@ -130,7 +132,7 @@ public static FacetedMesh GetBasicBoxMesh() new() { Position = new( 0.5f, 0.5f, 0.5f), Normal = Vector3.UnitZ, TexCoord = new(1f, 1f)}, new() { Position = new(-0.5f, 0.5f, 0.5f), Normal = Vector3.UnitZ, TexCoord = new(0f, 1f)}, ], - Indices = [0, 1, 2, 0, 2, 3], + Indices = m_indexs_012023, }, new Face() { @@ -185,7 +187,7 @@ public static FacetedMesh GetBasicBoxMesh() new() { Position = new( -0.5f, -0.5f, -0.5f), Normal = -Vector3.UnitZ, TexCoord = new(0f, 1f)}, new() { Position = new( -0.5f, 0.5f, -0.5f), Normal = -Vector3.UnitZ, TexCoord = new(0f, 0f)}, ], - Indices = [0, 1, 2, 3, 0, 2], + Indices = m_indexs_012302, }, ] }; diff --git a/OpenMetaverseTypes/DoubleDictionary.cs b/OpenMetaverseTypes/DoubleDictionary.cs index 040edf66..bd31493c 100644 --- a/OpenMetaverseTypes/DoubleDictionary.cs +++ b/OpenMetaverseTypes/DoubleDictionary.cs @@ -73,24 +73,18 @@ public void Add(TKey1 key1, TKey2 key2, TValue value) public bool Remove(TKey1 key1, TKey2 key2) { - bool success; rwLock.EnterWriteLock(); - try { Dictionary1.Remove(key1); - success = Dictionary2.Remove(key2); + return Dictionary2.Remove(key2); } finally { rwLock.ExitWriteLock(); } - - return success; } public bool Remove(TKey1 key1) { - bool found = false; rwLock.EnterWriteLock(); - try { // This is an O(n) operation! @@ -103,27 +97,22 @@ public bool Remove(TKey1 key1) { Dictionary1.Remove(key1); Dictionary2.Remove(kvp.Key); - found = true; - break; + return true; } } } + return false; } finally { rwLock.ExitWriteLock(); } - - return found; } public bool Remove(TKey2 key2) { - bool found = false; rwLock.EnterWriteLock(); - try { // This is an O(n) operation! - TValue value; - if (Dictionary2.TryGetValue(key2, out value)) + if (Dictionary2.TryGetValue(key2, out TValue value)) { foreach (KeyValuePair kvp in Dictionary1) { @@ -131,15 +120,13 @@ public bool Remove(TKey2 key2) { Dictionary2.Remove(key2); Dictionary1.Remove(kvp.Key); - found = true; - break; + return true; } } } + return false; } finally { rwLock.ExitWriteLock(); } - - return found; } public void Clear() @@ -171,30 +158,21 @@ public bool ContainsKey(TKey2 key) public bool TryGetValue(TKey1 key, out TValue value) { - bool success; rwLock.EnterReadLock(); - - try { success = Dictionary1.TryGetValue(key, out value); } + try { return Dictionary1.TryGetValue(key, out value); } finally { rwLock.ExitReadLock(); } - - return success; } public bool TryGetValue(TKey2 key, out TValue value) { - bool success; rwLock.EnterReadLock(); - - try { success = Dictionary2.TryGetValue(key, out value); } + try { return Dictionary2.TryGetValue(key, out value); } finally { rwLock.ExitReadLock(); } - - return success; } public void ForEach(Action action) { rwLock.EnterReadLock(); - try { foreach (TValue value in Dictionary1.Values) @@ -206,7 +184,6 @@ public void ForEach(Action action) public void ForEach(Action> action) { rwLock.EnterReadLock(); - try { foreach (KeyValuePair entry in Dictionary1) @@ -218,7 +195,6 @@ public void ForEach(Action> action) public void ForEach(Action> action) { rwLock.EnterReadLock(); - try { foreach (KeyValuePair entry in Dictionary2) @@ -247,7 +223,6 @@ public IList FindAll(Predicate predicate) { IList list = new List(); rwLock.EnterReadLock(); - try { foreach (TValue value in Dictionary1.Values) diff --git a/OpenMetaverseTypes/Quaternion.cs b/OpenMetaverseTypes/Quaternion.cs index 4b4c2304..f75bbec7 100644 --- a/OpenMetaverseTypes/Quaternion.cs +++ b/OpenMetaverseTypes/Quaternion.cs @@ -377,6 +377,41 @@ public void Sub(ref readonly Quaternion quaternion2) } } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public readonly Quaternion Multiply(ref readonly Quaternion b) + { + //if (MathF.Abs(W) > (1.0f - 1e-6f)) + // return b; + + return new Quaternion( + W * b.X + X * b.W + Y * b.Z - Z * b.Y, + W * b.Y + Y * b.W + Z * b.X - X * b.Z, + W * b.Z + Z * b.W + X * b.Y - Y * b.X, + W * b.W - X * b.X - Y * b.Y - Z * b.Z + ); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void MultiplySelf(ref readonly Quaternion b) + { + if (MathF.Abs(W) > (1.0f - 1e-6f)) + + { + X = b.X; + Y = b.Y; + Z = b.Z; + W = b.W; + return; + } + float x = W * b.X + X * b.W + Y * b.Z - Z * b.Y; + float y = W * b.Y + Y * b.W + Z * b.X - X * b.Z; + float z = W * b.Z + Z * b.W + X * b.Y - Y * b.X; + W = W * b.W - X * b.X - Y * b.Y - Z * b.Z; + X = x; + Y = y; + Z = z; + } + /// /// Builds a quaternion object from a byte array /// @@ -701,11 +736,11 @@ public static Quaternion Add(ref readonly Quaternion quaternion1, ref readonly Q /// Returns the conjugate (spatial inverse) of a quaternion /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Quaternion Conjugate(in Quaternion quaternion) + public static Quaternion Conjugate(ref readonly Quaternion quaternion) { if (Sse.IsSupported) { - Vector128 d = Unsafe.As>(ref Unsafe.AsRef(quaternion)); + Vector128 d = Unsafe.As>(ref Unsafe.AsRef(in quaternion)); Vector128 Mask = Vector128.Create(0x80000000, 0x80000000, 0x80000000, 0).AsSingle(); d = Sse.Xor(d, Mask); return new Quaternion(ref d); @@ -733,13 +768,14 @@ public static Quaternion CreateFromAxisAngle(float axisX, float axisY, float axi [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Quaternion CreateFromAxisAngle(Vector3 axis, float angle) { - axis.Normalize(); - angle *= 0.5f; - float c = MathF.Cos(angle); float s = MathF.Sin(angle); - return new Quaternion(axis.X * s, axis.Y * s, axis.Z * s, c); + axis.Normalize(); + axis *= s; + + float c = MathF.Cos(angle); + return new Quaternion(axis.X, axis.Y, axis.Z, c); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -834,7 +870,7 @@ public static Quaternion CreateFromRotationMatrix(Matrix3x3 matrix) } if ((matrix.M11 >= matrix.M22) && (matrix.M11 >= matrix.M33)) { - num = MathF.Sqrt((((1f + matrix.M11) - matrix.M22) - matrix.M33)); + num = MathF.Sqrt(1f + matrix.M11 - matrix.M22 - matrix.M33); n2 = 0.5f / num; return new Quaternion( 0.5f * num, @@ -844,7 +880,7 @@ public static Quaternion CreateFromRotationMatrix(Matrix3x3 matrix) } if (matrix.M22 > matrix.M33) { - num = MathF.Sqrt((((1f + matrix.M22) - matrix.M11) - matrix.M33)); + num = MathF.Sqrt(1f - matrix.M11 + matrix.M22 - matrix.M33); n2 = 0.5f / num; return new Quaternion( (matrix.M21 + matrix.M12) * n2, @@ -853,7 +889,7 @@ public static Quaternion CreateFromRotationMatrix(Matrix3x3 matrix) (matrix.M31 - matrix.M13) * n2); } - num = MathF.Sqrt((((1f + matrix.M33) - matrix.M11) - matrix.M22)); + num = MathF.Sqrt(1f - matrix.M11 - matrix.M22 + matrix.M33 ); n2 = 0.5f / num; return new Quaternion( (matrix.M31 + matrix.M13) * n2, @@ -868,7 +904,7 @@ public static Quaternion CreateFromRotationMatrix(Matrix4 matrix) float n2; if (num >= 0f) { - num = MathF.Sqrt((num + 1f)); + num = MathF.Sqrt(1f + num); n2 = 0.5f / num; return new Quaternion( (matrix.M23 - matrix.M32) * n2, @@ -878,7 +914,7 @@ public static Quaternion CreateFromRotationMatrix(Matrix4 matrix) } if ((matrix.M11 >= matrix.M22) && (matrix.M11 >= matrix.M33)) { - num = MathF.Sqrt((((1f + matrix.M11) - matrix.M22) - matrix.M33)); + num = MathF.Sqrt(1f + matrix.M11 - matrix.M22 - matrix.M33); n2 = 0.5f / num; return new Quaternion( 0.5f * num, @@ -888,7 +924,7 @@ public static Quaternion CreateFromRotationMatrix(Matrix4 matrix) } if (matrix.M22 > matrix.M33) { - num = MathF.Sqrt((((1f + matrix.M22) - matrix.M11) - matrix.M33)); + num = MathF.Sqrt(1f - matrix.M11 + matrix.M22 - matrix.M33); n2 = 0.5f / num; return new Quaternion( (matrix.M21 + matrix.M12) * n2, @@ -897,7 +933,7 @@ public static Quaternion CreateFromRotationMatrix(Matrix4 matrix) (matrix.M31 - matrix.M13) * n2); } - num = MathF.Sqrt((((1f + matrix.M33) - matrix.M11) - matrix.M22)); + num = MathF.Sqrt(1f - matrix.M11 - matrix.M22 + matrix.M33); n2 = 0.5f / num; return new Quaternion( (matrix.M31 + matrix.M13) * n2, @@ -909,7 +945,7 @@ public static Quaternion CreateFromRotationMatrix(Matrix4 matrix) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Quaternion Divide(Quaternion q1, Quaternion q2) { - return Quaternion.Inverse(q1) * q2; + return Inverse(q1) * q2; } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -932,9 +968,8 @@ public static float Dot(Quaternion q1, Quaternion q2) public static Quaternion Inverse(Quaternion quaternion) { float normsq = quaternion.LengthSquared(); - if (normsq < 1e-6f) - return Quaternion.Identity; + return Identity; float oonorm = -1f / normsq; return new Quaternion( @@ -1008,7 +1043,7 @@ public static Quaternion Subtract(Quaternion quaternion1, Quaternion quaternion2 } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Quaternion Multiply(Quaternion a, Quaternion b) + public static Quaternion Multiply(ref readonly Quaternion a, ref readonly Quaternion b) { return new Quaternion( a.W * b.X + a.X * b.W + a.Y * b.Z - a.Z * b.Y, @@ -1019,7 +1054,7 @@ public static Quaternion Multiply(Quaternion a, Quaternion b) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Quaternion Multiply(Quaternion quaternion, float scaleFactor) + public static Quaternion Multiply(ref readonly Quaternion quaternion, float scaleFactor) { return new Quaternion( quaternion.X * scaleFactor, @@ -1401,6 +1436,8 @@ public readonly string ToRawString() [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Quaternion operator *(Quaternion a, Quaternion b) { + if (MathF.Abs(a.W) > (1.0f - 1e-6f)) return b; + if (MathF.Abs(b.W) > (1.0f - 1e-6f)) return a; return new Quaternion( a.W * b.X + a.X * b.W + a.Y * b.Z - a.Z * b.Y, a.W * b.Y + a.Y * b.W + a.Z * b.X - a.X * b.Z, From 82aecce0ac1253b35cbb1bd7856f61946e2f2525 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Sat, 14 Mar 2026 23:50:34 +0000 Subject: [PATCH 141/149] let OSD AsLong() and AsUlong() to also convert binary or array types of size 4 --- .../StructuredData.cs | 32 +++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/OpenMetaverse.StructuredData/StructuredData.cs b/OpenMetaverse.StructuredData/StructuredData.cs index 12a64fa9..78a0a2d3 100644 --- a/OpenMetaverse.StructuredData/StructuredData.cs +++ b/OpenMetaverse.StructuredData/StructuredData.cs @@ -259,9 +259,17 @@ public virtual long AsLong() case OSDType.Binary: { byte[] b = ((OSDBinary)this).value; + if(b.Length == 4) + { + return + ((long)b[0] << 24) | + ((long)b[1] << 16) | + ((long)b[2] << 8) | + b[3]; + } if(b.Length < 8) return 0; - return ( + return ((long)b[0] << 56) | ((long)b[1] << 48) | ((long)b[2] << 40) | @@ -269,11 +277,17 @@ public virtual long AsLong() ((long)b[4] << 24) | ((long)b[5] << 16) | ((long)b[6] << 8) | - b[7]); + b[7]; } case OSDType.Array: { List l = ((OSDArray)this).value; + if (l.Count == 4) + return + ((long)(byte)l[0].AsInteger() << 24) | + ((long)(byte)l[1].AsInteger() << 16) | + ((long)(byte)l[2].AsInteger() << 8) | + (byte)l[3].AsInteger(); if (l.Count < 8) return 0; return @@ -323,6 +337,14 @@ public virtual ulong AsULong() case OSDType.Binary: { byte[] b = ((OSDBinary)this).value; + if(b.Length == 4) + { + return + ((ulong)b[0] << 24) | + ((ulong)b[1] << 16) | + ((ulong)b[2] << 8) | + b[3]; + } if (b.Length < 8) return 0; return ( @@ -338,6 +360,12 @@ public virtual ulong AsULong() case OSDType.Array: { List l = ((OSDArray)this).value; + if (l.Count == 4) + return + ((ulong)(byte)l[0].AsInteger() << 24) | + ((ulong)(byte)l[1].AsInteger() << 16) | + ((ulong)(byte)l[2].AsInteger() << 8) | + (byte)l[3].AsInteger(); if (l.Count < 8) return 0; return ( From 0cc1041f1ed31d2020bf7179fd11200945947335 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Tue, 17 Mar 2026 02:33:24 +0000 Subject: [PATCH 142/149] add OSD type NLong to store a c# long. May change it do just Long ( and ulong) so osd is a better rep of c# and not just a wrapper for llsd --- .../JSON/JsonWriter.cs | 1 - OpenMetaverse.StructuredData/JSON/OSDJson.cs | 21 ++++++ .../StructuredData.cs | 72 ++++++++++++++++++- OpenMetaverseTypes/UtilsConversions.cs | 4 +- 4 files changed, 92 insertions(+), 6 deletions(-) diff --git a/OpenMetaverse.StructuredData/JSON/JsonWriter.cs b/OpenMetaverse.StructuredData/JSON/JsonWriter.cs index 66a54200..32f50d3d 100644 --- a/OpenMetaverse.StructuredData/JSON/JsonWriter.cs +++ b/OpenMetaverse.StructuredData/JSON/JsonWriter.cs @@ -267,7 +267,6 @@ private void Unindent() } #endregion - public override string ToString() { if (inst_string_builder == null) diff --git a/OpenMetaverse.StructuredData/JSON/OSDJson.cs b/OpenMetaverse.StructuredData/JSON/OSDJson.cs index a7846150..b5e30773 100644 --- a/OpenMetaverse.StructuredData/JSON/OSDJson.cs +++ b/OpenMetaverse.StructuredData/JSON/OSDJson.cs @@ -97,6 +97,8 @@ public static JsonData SerializeJson(OSD osd, bool preserveDefaults) return new JsonData(osd.AsBoolean()); case OSDType.Integer: return new JsonData(osd.AsInteger()); + case OSDType.NLong: + return new JsonData(osd.AsLong()); case OSDType.Real: return new JsonData(osd.AsReal()); case OSDType.String: @@ -153,6 +155,10 @@ private static JsonData SerializeJsonNoDefaults(OSD osd) return null; return new JsonData(v); + + case OSDType.NLong: + return new JsonData(osd.AsLong()); + case OSDType.Real: double d = osd.AsReal(); if (d == 0.0d) @@ -241,6 +247,9 @@ public static void SerializeJson(OSD osd, osUTF8 sb, bool preserveDefaults) case OSDType.Integer: sb.AppendInt(osd.AsInteger()); break; + case OSDType.NLong: + sb.AppendInt(osd.AsLong()); + break; case OSDType.Real: string str = Convert.ToString(osd.AsReal(), NumberFormatInfo.InvariantInfo); sb.AppendASCII(str); @@ -344,6 +353,18 @@ public static void SerializeJsonMapNoDefaults(string name, OSD osd, ref int mapc sb.AppendInt(oi); } break; + case OSDType.NLong: + long ol = osd.AsLong(); + if(ol != 0) + { + if (mapcont++ > 0) + sb.AppendASCII(','); + appendJsonString(name, sb); + sb.AppendASCII(':'); + sb.AppendInt(ol); + } + break; + case OSDType.Real: double od = osd.AsReal(); if(od != 0) diff --git a/OpenMetaverse.StructuredData/StructuredData.cs b/OpenMetaverse.StructuredData/StructuredData.cs index 78a0a2d3..a1cb7f8b 100644 --- a/OpenMetaverse.StructuredData/StructuredData.cs +++ b/OpenMetaverse.StructuredData/StructuredData.cs @@ -62,7 +62,8 @@ public enum OSDType:byte /// Array, LLSDxml, - OSDUTF8 + OSDUTF8, + NLong } public enum OSDFormat @@ -121,7 +122,8 @@ public virtual bool AsBoolean() if (u.Equals('0') || u.ACSIILowerEquals("false")) return false; return true; - + case OSDType.NLong: + return ((OSDNLong)this).value != 0; default: return false; } @@ -135,6 +137,13 @@ public virtual int AsInteger() return ((OSDBoolean)this).value ? 1 : 0; case OSDType.Integer: return ((OSDInteger)this).value; + case OSDType.NLong: + long nlv = ((OSDNLong)this).value; + if (nlv >= Int32.MaxValue) + return Int32.MaxValue; + if (nlv <= Int32.MinValue) + return Int32.MinValue; + return (int)nlv; case OSDType.Real: double v = ((OSDReal)this).value; if (Double.IsNaN(v)) @@ -185,6 +194,13 @@ public virtual uint AsUInteger() return ((OSDBoolean)this).value ? 1U : 0; case OSDType.Integer: return (uint)((OSDInteger)this).value; + case OSDType.NLong: + long nlv = ((OSDNLong)this).value; + if (nlv >= UInt32.MaxValue) + return Int32.MaxValue; + if (nlv <= UInt32.MinValue) + return UInt32.MinValue; + return (uint)nlv; case OSDType.Real: double v = ((OSDReal)this).value; if (Double.IsNaN(v)) @@ -234,6 +250,8 @@ public virtual long AsLong() return ((OSDBoolean)this).value ? 1 : 0; case OSDType.Integer: return ((OSDInteger)this).value; + case OSDType.NLong: + return ((OSDNLong)this).value; case OSDType.Real: double v = ((OSDReal)this).value; if (Double.IsNaN(v)) @@ -313,6 +331,8 @@ public virtual ulong AsULong() return ((OSDBoolean)this).value ? 1UL : 0; case OSDType.Integer: return (ulong)((OSDInteger)this).value; + case OSDType.NLong: + return (ulong)((OSDNLong)this).value; case OSDType.Real: double v = ((OSDReal)this).value; if (Double.IsNaN(v)) @@ -391,6 +411,8 @@ public virtual double AsReal() return ((OSDBoolean)this).value ? 1.0 : 0; case OSDType.Integer: return ((OSDInteger)this).value; + case OSDType.NLong: + return ((OSDNLong)this).value; case OSDType.Real: return ((OSDReal)this).value; case OSDType.String: @@ -416,6 +438,8 @@ public virtual string AsString() return ((OSDBoolean)this).value ? "1" : "0"; case OSDType.Integer: return ((OSDInteger)this).value.ToString(); + case OSDType.NLong: + return ((OSDNLong)this).value.ToString(); case OSDType.Real: return ((OSDReal)this).value.ToString("g", Utils.EnUsCulture); case OSDType.String: @@ -527,6 +551,8 @@ public virtual byte[] AsBinary() return ((OSDBoolean)this).value ? trueBinary : falseBinary; case OSDType.Integer: return Utils.IntToBytesBig(((OSDInteger)this).value); + case OSDType.NLong: + return Utils.Int64ToBytes(((OSDNLong)this).value); case OSDType.Real: return Utils.DoubleToBytesBig(((OSDReal)this).value); case OSDType.String: @@ -700,6 +726,7 @@ public virtual OSD Copy() { OSDType.Boolean => new OSDBoolean(((OSDBoolean)this).value), OSDType.Integer => new OSDInteger(((OSDInteger)this).value), + OSDType.NLong => new OSDNLong(((OSDNLong)this).value), OSDType.Real => new OSDReal(((OSDReal)this).value), OSDType.String => new OSDString(((OSDString)this).value), OSDType.OSDUTF8 => new OSDUTF8(((OSDUTF8)this).value), @@ -722,6 +749,8 @@ public override string ToString() return ((OSDBoolean)this).value ? "1" : "0"; case OSDType.Integer: return ((OSDInteger)this).value.ToString(); + case OSDType.NLong: + return (((OSDNLong)this).value).ToString(); case OSDType.Real: return ((OSDReal)this).value.ToString("g", Utils.EnUsCulture); case OSDType.String: @@ -779,9 +808,15 @@ public override string ToString() [MethodImpl(MethodImplOptions.AggressiveInlining)] public static OSD FromInteger(byte value) { return new OSDInteger((int)value); } - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static OSD FromUInteger(uint value) { return new OSDBinary(value); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static OSD FromUInteger(uint value) { return new OSDBinary(value); } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static OSD FromLong(long value) { return new OSDBinary(value); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static OSD FromNLong(long value) { return new OSDNLong((long)value); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static OSD FromULong(ulong value) { return new OSDBinary(value); } public static OSD FromReal(double value) { return new OSDReal(value); } @@ -1170,6 +1205,37 @@ public OSDInteger(int value) [MethodImpl(MethodImplOptions.AggressiveInlining)] public override string ToString() { return AsString(); } } + public sealed class OSDNLong : OSD + { + public readonly long value; + + public OSDNLong(long value) + { + Type = OSDType.NLong; + this.value = value; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public override bool AsBoolean() { return value != 0; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public override int AsInteger() { return (int)value; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public override uint AsUInteger() { return (uint)value; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public override long AsLong() { return value; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public override ulong AsULong() { return (ulong)value; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public override double AsReal() { return (double)value; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public override string AsString() { return value.ToString(); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public override byte[] AsBinary() { return Utils.Int64ToBytes(value); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public override OSD Copy() { return new OSDNLong(value); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public override string ToString() { return AsString(); } + } /// /// diff --git a/OpenMetaverseTypes/UtilsConversions.cs b/OpenMetaverseTypes/UtilsConversions.cs index 259fd471..f16d9ead 100644 --- a/OpenMetaverseTypes/UtilsConversions.cs +++ b/OpenMetaverseTypes/UtilsConversions.cs @@ -3434,7 +3434,7 @@ public static unsafe int LongToByteString(long value, byte* dst) if (value > 0) { n = CountDigits((ulong)value); - UintToStrBytesFromEnd((uint)value, dst + n - 1); + ULongToStrBytesFromEnd((ulong)value, dst + n - 1); return n; } @@ -3447,7 +3447,7 @@ public static unsafe int LongToByteString(long value, byte* dst) *dst = ASCIIminus; value = -value; n = CountDigits((ulong)value); - UintToStrBytesFromEnd((uint)value, dst + n); + ULongToStrBytesFromEnd((ulong)value, dst + n); return n + 1; } From 4dd1e1c3957422efac5030501373a891d5129f8d Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Mon, 23 Mar 2026 01:11:30 +0000 Subject: [PATCH 143/149] add osd Long type ( rename of NLong); fix llsd serializers to still do it as binary (big endian byte array) --- .../JSON/JsonReader.cs | 39 ++++------ .../JSON/JsonWriter.cs | 2 +- OpenMetaverse.StructuredData/JSON/OSDJson.cs | 8 +- .../LLSD/BinaryLLSD.cs | 1 + .../LLSD/NotationLLSD.cs | 2 + OpenMetaverse.StructuredData/LLSD/XmlLLSD.cs | 2 + .../StructuredData.cs | 75 ++++++++++--------- 7 files changed, 63 insertions(+), 66 deletions(-) diff --git a/OpenMetaverse.StructuredData/JSON/JsonReader.cs b/OpenMetaverse.StructuredData/JSON/JsonReader.cs index 1e8d2dae..fd60e870 100644 --- a/OpenMetaverse.StructuredData/JSON/JsonReader.cs +++ b/OpenMetaverse.StructuredData/JSON/JsonReader.cs @@ -12,8 +12,6 @@ using System; using System.Collections.Generic; using System.IO; -using System.Text; - namespace LitJson { @@ -60,7 +58,6 @@ public class JsonReader private JsonToken token; #endregion - #region Public Properties public bool AllowComments { @@ -264,17 +261,12 @@ private static void TableAddRow(ParserToken rule) } #endregion - #region Private Methods private void ProcessNumber(string number) { - if (number.IndexOf('.') != -1 || - number.IndexOf('e') != -1 || - number.IndexOf('E') != -1) + if (number.IndexOfAny(['.','e','E']) >= 0) { - - double n_double; - if (Double.TryParse(number, out n_double)) + if (double.TryParse(number, out double n_double)) { token = JsonToken.Double; token_value = n_double; @@ -283,26 +275,23 @@ private void ProcessNumber(string number) } } - int n_int32; - if (Int32.TryParse(number, out n_int32)) + if (long.TryParse(number, out long n_int64)) { - token = JsonToken.Int; - token_value = n_int32; - - return; - } - - long n_int64; - if (Int64.TryParse(number, out n_int64)) - { - token = JsonToken.Long; - token_value = n_int64; + if(n_int64 >= int.MinValue && n_int64 <= int.MaxValue) + { + token = JsonToken.Int; + token_value = (int)n_int64; + } + else + { + token = JsonToken.Long; + token_value = n_int64; + } return; } - ulong n_uint64; - if (UInt64.TryParse(number, out n_uint64)) + if (ulong.TryParse(number, out ulong n_uint64)) { token = JsonToken.Long; token_value = n_uint64; diff --git a/OpenMetaverse.StructuredData/JSON/JsonWriter.cs b/OpenMetaverse.StructuredData/JSON/JsonWriter.cs index 32f50d3d..1bbbe00a 100644 --- a/OpenMetaverse.StructuredData/JSON/JsonWriter.cs +++ b/OpenMetaverse.StructuredData/JSON/JsonWriter.cs @@ -315,7 +315,7 @@ public void Write(double number) string str = Convert.ToString(number, number_format); Put(str); - if (str.IndexOfAny(new char[] { '.', 'E' }) == -1) + if (str.IndexOfAny(['.', 'e' ,'E']) < 0) writer.Write(".0"); context.ExpectingValue = false; diff --git a/OpenMetaverse.StructuredData/JSON/OSDJson.cs b/OpenMetaverse.StructuredData/JSON/OSDJson.cs index b5e30773..778044e0 100644 --- a/OpenMetaverse.StructuredData/JSON/OSDJson.cs +++ b/OpenMetaverse.StructuredData/JSON/OSDJson.cs @@ -97,7 +97,7 @@ public static JsonData SerializeJson(OSD osd, bool preserveDefaults) return new JsonData(osd.AsBoolean()); case OSDType.Integer: return new JsonData(osd.AsInteger()); - case OSDType.NLong: + case OSDType.Long: return new JsonData(osd.AsLong()); case OSDType.Real: return new JsonData(osd.AsReal()); @@ -156,7 +156,7 @@ private static JsonData SerializeJsonNoDefaults(OSD osd) return new JsonData(v); - case OSDType.NLong: + case OSDType.Long: return new JsonData(osd.AsLong()); case OSDType.Real: @@ -247,7 +247,7 @@ public static void SerializeJson(OSD osd, osUTF8 sb, bool preserveDefaults) case OSDType.Integer: sb.AppendInt(osd.AsInteger()); break; - case OSDType.NLong: + case OSDType.Long: sb.AppendInt(osd.AsLong()); break; case OSDType.Real: @@ -353,7 +353,7 @@ public static void SerializeJsonMapNoDefaults(string name, OSD osd, ref int mapc sb.AppendInt(oi); } break; - case OSDType.NLong: + case OSDType.Long: long ol = osd.AsLong(); if(ol != 0) { diff --git a/OpenMetaverse.StructuredData/LLSD/BinaryLLSD.cs b/OpenMetaverse.StructuredData/LLSD/BinaryLLSD.cs index 4e0fd401..3bbceb7f 100644 --- a/OpenMetaverse.StructuredData/LLSD/BinaryLLSD.cs +++ b/OpenMetaverse.StructuredData/LLSD/BinaryLLSD.cs @@ -185,6 +185,7 @@ private static void SerializeLLSDBinaryElement(MemoryStream stream, OSD osd) stream.Write(stringLengthNetEnd, 0, int32Length); stream.Write(rawString, 0, rawString.Length); break; + case OSDType.Long: case OSDType.Binary: stream.WriteByte(binaryBinaryMarker); byte[] rawBinary = osd.AsBinary(); diff --git a/OpenMetaverse.StructuredData/LLSD/NotationLLSD.cs b/OpenMetaverse.StructuredData/LLSD/NotationLLSD.cs index 78ca3951..4d2d4040 100644 --- a/OpenMetaverse.StructuredData/LLSD/NotationLLSD.cs +++ b/OpenMetaverse.StructuredData/LLSD/NotationLLSD.cs @@ -473,6 +473,7 @@ private static void SerializeLLSDNotationElement(TextWriter writer, OSD osd) case OSDType.LLSDxml: writer.Write(osd.AsString()); break; + case OSDType.Long: case OSDType.Binary: writer.Write(binaryNotationMarker); writer.Write("64"); @@ -613,6 +614,7 @@ private static void SerializeLLSDNotationElementFormatted(TextWriter writer, str case OSDType.LLSDxml: writer.Write(osd.AsString()); break; + case OSDType.Long: case OSDType.Binary: writer.Write(binaryNotationMarker); writer.Write("64"); diff --git a/OpenMetaverse.StructuredData/LLSD/XmlLLSD.cs b/OpenMetaverse.StructuredData/LLSD/XmlLLSD.cs index 6cdeb4bb..e39afffe 100644 --- a/OpenMetaverse.StructuredData/LLSD/XmlLLSD.cs +++ b/OpenMetaverse.StructuredData/LLSD/XmlLLSD.cs @@ -207,6 +207,7 @@ public static void SerializeLLSDXmlElement(StringBuilder sb, OSD data, bool form sb.Append(data.AsString()); sb.Append(""); break; + case OSDType.Long: case OSDType.Binary: if(formal) sb.Append(""); @@ -408,6 +409,7 @@ public static void SerializeLLSDXmlElement(osUTF8 mb, OSD data, bool formal) EscapeToXML(mb, data.ToString()); mb.Append(osUTF8Const.XMLuriEnd); break; + case OSDType.Long: case OSDType.Binary: if (formal) mb.Append(osUTF8Const.XMLformalBinaryStart); diff --git a/OpenMetaverse.StructuredData/StructuredData.cs b/OpenMetaverse.StructuredData/StructuredData.cs index a1cb7f8b..69d166bf 100644 --- a/OpenMetaverse.StructuredData/StructuredData.cs +++ b/OpenMetaverse.StructuredData/StructuredData.cs @@ -63,7 +63,7 @@ public enum OSDType:byte Array, LLSDxml, OSDUTF8, - NLong + Long } public enum OSDFormat @@ -122,8 +122,8 @@ public virtual bool AsBoolean() if (u.Equals('0') || u.ACSIILowerEquals("false")) return false; return true; - case OSDType.NLong: - return ((OSDNLong)this).value != 0; + case OSDType.Long: + return ((OSDLong)this).value != 0; default: return false; } @@ -137,8 +137,8 @@ public virtual int AsInteger() return ((OSDBoolean)this).value ? 1 : 0; case OSDType.Integer: return ((OSDInteger)this).value; - case OSDType.NLong: - long nlv = ((OSDNLong)this).value; + case OSDType.Long: + long nlv = ((OSDLong)this).value; if (nlv >= Int32.MaxValue) return Int32.MaxValue; if (nlv <= Int32.MinValue) @@ -194,8 +194,8 @@ public virtual uint AsUInteger() return ((OSDBoolean)this).value ? 1U : 0; case OSDType.Integer: return (uint)((OSDInteger)this).value; - case OSDType.NLong: - long nlv = ((OSDNLong)this).value; + case OSDType.Long: + long nlv = ((OSDLong)this).value; if (nlv >= UInt32.MaxValue) return Int32.MaxValue; if (nlv <= UInt32.MinValue) @@ -250,8 +250,8 @@ public virtual long AsLong() return ((OSDBoolean)this).value ? 1 : 0; case OSDType.Integer: return ((OSDInteger)this).value; - case OSDType.NLong: - return ((OSDNLong)this).value; + case OSDType.Long: + return ((OSDLong)this).value; case OSDType.Real: double v = ((OSDReal)this).value; if (Double.IsNaN(v)) @@ -331,8 +331,8 @@ public virtual ulong AsULong() return ((OSDBoolean)this).value ? 1UL : 0; case OSDType.Integer: return (ulong)((OSDInteger)this).value; - case OSDType.NLong: - return (ulong)((OSDNLong)this).value; + case OSDType.Long: + return (ulong)((OSDLong)this).value; case OSDType.Real: double v = ((OSDReal)this).value; if (Double.IsNaN(v)) @@ -411,8 +411,8 @@ public virtual double AsReal() return ((OSDBoolean)this).value ? 1.0 : 0; case OSDType.Integer: return ((OSDInteger)this).value; - case OSDType.NLong: - return ((OSDNLong)this).value; + case OSDType.Long: + return ((OSDLong)this).value; case OSDType.Real: return ((OSDReal)this).value; case OSDType.String: @@ -438,8 +438,8 @@ public virtual string AsString() return ((OSDBoolean)this).value ? "1" : "0"; case OSDType.Integer: return ((OSDInteger)this).value.ToString(); - case OSDType.NLong: - return ((OSDNLong)this).value.ToString(); + case OSDType.Long: + return ((OSDLong)this).value.ToString(); case OSDType.Real: return ((OSDReal)this).value.ToString("g", Utils.EnUsCulture); case OSDType.String: @@ -471,7 +471,7 @@ public virtual string AsString() case OSDType.LLSDxml: return ((OSDllsdxml)this).value; default: - return String.Empty; + return string.Empty; } } @@ -551,8 +551,8 @@ public virtual byte[] AsBinary() return ((OSDBoolean)this).value ? trueBinary : falseBinary; case OSDType.Integer: return Utils.IntToBytesBig(((OSDInteger)this).value); - case OSDType.NLong: - return Utils.Int64ToBytes(((OSDNLong)this).value); + case OSDType.Long: + return Utils.Int64ToBytesBig(((OSDLong)this).value); case OSDType.Real: return Utils.DoubleToBytesBig(((OSDReal)this).value); case OSDType.String: @@ -726,7 +726,7 @@ public virtual OSD Copy() { OSDType.Boolean => new OSDBoolean(((OSDBoolean)this).value), OSDType.Integer => new OSDInteger(((OSDInteger)this).value), - OSDType.NLong => new OSDNLong(((OSDNLong)this).value), + OSDType.Long => new OSDLong(((OSDLong)this).value), OSDType.Real => new OSDReal(((OSDReal)this).value), OSDType.String => new OSDString(((OSDString)this).value), OSDType.OSDUTF8 => new OSDUTF8(((OSDUTF8)this).value), @@ -749,8 +749,8 @@ public override string ToString() return ((OSDBoolean)this).value ? "1" : "0"; case OSDType.Integer: return ((OSDInteger)this).value.ToString(); - case OSDType.NLong: - return (((OSDNLong)this).value).ToString(); + case OSDType.Long: + return (((OSDLong)this).value).ToString(); case OSDType.Real: return ((OSDReal)this).value.ToString("g", Utils.EnUsCulture); case OSDType.String: @@ -797,25 +797,22 @@ public override string ToString() public static OSD FromInteger(uint value) { return new OSDInteger((int)value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static OSD FromInteger(short value) { return new OSDInteger((int)value); } + public static OSD FromInteger(short value) { return new OSDInteger(value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static OSD FromInteger(ushort value) { return new OSDInteger((int)value); } + public static OSD FromInteger(ushort value) { return new OSDInteger(value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static OSD FromInteger(sbyte value) { return new OSDInteger((int)value); } + public static OSD FromInteger(sbyte value) { return new OSDInteger(value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static OSD FromInteger(byte value) { return new OSDInteger((int)value); } + public static OSD FromInteger(byte value) { return new OSDInteger(value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static OSD FromUInteger(uint value) { return new OSDBinary(value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static OSD FromLong(long value) { return new OSDBinary(value); } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static OSD FromNLong(long value) { return new OSDNLong((long)value); } + public static OSD FromLong(long value) { return new OSDLong(value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static OSD FromULong(ulong value) { return new OSDBinary(value); } public static OSD FromReal(double value) { return new OSDReal(value); } @@ -888,7 +885,7 @@ public static OSD FromObject(object value) else if (value is DateTime dtmv) { return new OSDDate(dtmv); } else if (value is Uri uriv) { return new OSDUri(uriv); } else if (value is byte[] btav) { return new OSDBinary(btav); } - else if (value is long lv) { return new OSDBinary(lv); } + else if (value is long lv) { return new OSDLong(lv); } else if (value is ulong ulv) { return new OSDBinary(ulv); } else if (value is Vector2 v2v) { return FromVector2(v2v); } else if (value is Vector3 v3v) { return FromVector3(v3v); } @@ -957,6 +954,10 @@ public static object ToObject(Type type, OSD value) { return value.AsInteger(); } + else if (type == typeof(long)) + { + return value.AsLong(); + } else if (type == typeof(UUID)) { return value.AsUUID(); @@ -1019,7 +1020,7 @@ public static object ToObject(Type type, OSD value) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator OSD(byte value) { return new OSDInteger((int)value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator OSD(long value) { return new OSDBinary(value); } + public static implicit operator OSD(long value) { return new OSDLong(value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator OSD(ulong value) { return new OSDBinary(value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -1160,6 +1161,8 @@ public OSDBoolean(bool value) [MethodImpl(MethodImplOptions.AggressiveInlining)] public override int AsInteger() { return value ? 1 : 0; } [MethodImpl(MethodImplOptions.AggressiveInlining)] + public override long AsLong() { return value ? 1 : 0; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public override double AsReal() { return value ? 1d : 0d; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public override string AsString() { return value ? "1" : "0"; } @@ -1205,13 +1208,13 @@ public OSDInteger(int value) [MethodImpl(MethodImplOptions.AggressiveInlining)] public override string ToString() { return AsString(); } } - public sealed class OSDNLong : OSD + public sealed class OSDLong : OSD { public readonly long value; - public OSDNLong(long value) + public OSDLong(long value) { - Type = OSDType.NLong; + Type = OSDType.Long; this.value = value; } @@ -1230,9 +1233,9 @@ public OSDNLong(long value) [MethodImpl(MethodImplOptions.AggressiveInlining)] public override string AsString() { return value.ToString(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public override byte[] AsBinary() { return Utils.Int64ToBytes(value); } + public override byte[] AsBinary() { return Utils.Int64ToBytesBig(value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public override OSD Copy() { return new OSDNLong(value); } + public override OSD Copy() { return new OSDLong(value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public override string ToString() { return AsString(); } } From 51428c6b858c0988e844436dcf57e6a1ec6546b9 Mon Sep 17 00:00:00 2001 From: Mike Dickson Date: Wed, 13 May 2026 17:32:38 -0400 Subject: [PATCH 144/149] Fixes for BinaryFormatter and System.Drawing issues. These were blocking the library loading in the new plugin loader in NGC. --- OpenMetaverse.GUI/MiniMap.cs | 17 +- OpenMetaverse.GUI/OpenMetaverse.GUI.csproj | 5 +- ...OpenMetaverse.Rendering.Meshmerizer.csproj | 8 +- .../SimpleRenderer.cs | 5 +- OpenMetaverse.Tests/MessageTests.cs | 4 - OpenMetaverse/GridClient.cs | 2 +- OpenMetaverse/Helpers.cs | 31 +- OpenMetaverse/Imaging/BakeLayer.cs | 7 +- OpenMetaverse/Imaging/ManagedImage.cs | 122 +---- OpenMetaverse/Imaging/OpenJPEG.cs | 486 ++---------------- OpenMetaverse/Imaging/TGALoader.cs | 122 +---- OpenMetaverse/ImportExport/ColladalLoader.cs | 22 +- OpenMetaverse/Interfaces/IRendering.cs | 6 +- OpenMetaverse/Inventory.cs | 2 - OpenMetaverse/Messages/LindenMessages.cs | 152 +++--- OpenMetaverse/OpenMetaverse.csproj | 3 + OpenMetaverse/WorkPool.cs | 189 +------ build_log.txt | 33 ++ build_output.txt | 144 ++++++ build_status.txt | 242 +++++++++ 20 files changed, 658 insertions(+), 944 deletions(-) create mode 100644 build_log.txt create mode 100644 build_output.txt create mode 100644 build_status.txt diff --git a/OpenMetaverse.GUI/MiniMap.cs b/OpenMetaverse.GUI/MiniMap.cs index 5f7b628d..9f9d129f 100644 --- a/OpenMetaverse.GUI/MiniMap.cs +++ b/OpenMetaverse.GUI/MiniMap.cs @@ -28,7 +28,9 @@ using OpenMetaverse.Imaging; using System.Collections.Generic; using System.Drawing; +using System.IO; using System.Windows.Forms; +using SkiaSharp; namespace OpenMetaverse.GUI { @@ -216,10 +218,23 @@ void Network_OnCurrentSimChanged(object sender, SimChangedEventArgs e) delegate (TextureRequestState state, AssetTexture asset) { if (state == TextureRequestState.Finished) - OpenJPEG.DecodeToImage(asset.AssetData, out nullImage, out _MapLayer); + { + SKBitmap skMapLayer; + OpenJPEG.DecodeToImage(asset.AssetData, out nullImage, out skMapLayer); + _MapLayer = skMapLayer != null ? ConvertToBitmap(skMapLayer) : null; + } }); } } + private static Bitmap ConvertToBitmap(SKBitmap skBitmap) + { + using SKImage image = SKImage.FromBitmap(skBitmap); + using SKData data = image.Encode(SKEncodedImageFormat.Png, 100); + using MemoryStream stream = new MemoryStream(data.ToArray()); + using Bitmap tmp = new Bitmap(stream); + return new Bitmap(tmp); + } + } } diff --git a/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj b/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj index 4c183ce5..7eabdb93 100644 --- a/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj +++ b/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj @@ -1,8 +1,11 @@  Local - WinExe + Library True + net8.0-windows + true + true diff --git a/OpenMetaverse.Rendering.Meshmerizer/OpenMetaverse.Rendering.Meshmerizer.csproj b/OpenMetaverse.Rendering.Meshmerizer/OpenMetaverse.Rendering.Meshmerizer.csproj index be8eed8a..1f747d2b 100644 --- a/OpenMetaverse.Rendering.Meshmerizer/OpenMetaverse.Rendering.Meshmerizer.csproj +++ b/OpenMetaverse.Rendering.Meshmerizer/OpenMetaverse.Rendering.Meshmerizer.csproj @@ -6,10 +6,16 @@ true - + + + + + + + \ No newline at end of file diff --git a/OpenMetaverse.Rendering.Simple/SimpleRenderer.cs b/OpenMetaverse.Rendering.Simple/SimpleRenderer.cs index 370487c0..85eb0709 100644 --- a/OpenMetaverse.Rendering.Simple/SimpleRenderer.cs +++ b/OpenMetaverse.Rendering.Simple/SimpleRenderer.cs @@ -25,6 +25,7 @@ */ using System.Collections.Generic; +using SkiaSharp; namespace OpenMetaverse.Rendering { @@ -46,7 +47,7 @@ public SimpleMesh GenerateSimpleMesh(Primitive prim, DetailLevel lod) return mesh; } - public SimpleMesh GenerateSimpleSculptMesh(Primitive prim, System.Drawing.Bitmap sculptTexture, DetailLevel lod) + public SimpleMesh GenerateSimpleSculptMesh(Primitive prim, SKBitmap sculptTexture, DetailLevel lod) { return GenerateSimpleMesh(prim, lod); } @@ -65,7 +66,7 @@ public FacetedMesh GenerateFacetedMesh(Primitive prim, DetailLevel lod) return mesh; } - public FacetedMesh GenerateFacetedSculptMesh(Primitive prim, System.Drawing.Bitmap sculptTexture, DetailLevel lod) + public FacetedMesh GenerateFacetedSculptMesh(Primitive prim, SKBitmap sculptTexture, DetailLevel lod) { return GenerateFacetedMesh(prim, lod); } diff --git a/OpenMetaverse.Tests/MessageTests.cs b/OpenMetaverse.Tests/MessageTests.cs index 77cb9ba4..f9dd0eed 100644 --- a/OpenMetaverse.Tests/MessageTests.cs +++ b/OpenMetaverse.Tests/MessageTests.cs @@ -30,7 +30,6 @@ using System; using System.IO; using System.Net; -using System.Runtime.Serialization.Formatters.Binary; using System.Text; using System.Xml.Serialization; @@ -1249,7 +1248,6 @@ public void ReflectionPerformanceDirLandReply() TimeSpan duration = DateTime.UtcNow - messageTestTime; Console.WriteLine("DirLandReplyMessage: OMV Message System Serialization/Deserialization Passes: {0} Total time: {1}", TEST_ITER, duration); - BinaryFormatter formatter = new BinaryFormatter(); DateTime xmlTestTime = DateTime.UtcNow; for (int x = 0; x < TEST_ITER; x++) { @@ -1495,8 +1493,6 @@ public void ReflectionPerformanceParcelProperties() TimeSpan duration = DateTime.UtcNow - messageTestTime; Console.WriteLine("ParcelPropertiesMessage: OMV Message System Serialization/Deserialization Passes: {0} Total time: {1}", TEST_ITER, duration); - BinaryFormatter formatter = new BinaryFormatter(); - DateTime xmlTestTime = DateTime.UtcNow; for (int x = 0; x < TEST_ITER; x++) { diff --git a/OpenMetaverse/GridClient.cs b/OpenMetaverse/GridClient.cs index 713366a1..9cdf9c36 100644 --- a/OpenMetaverse/GridClient.cs +++ b/OpenMetaverse/GridClient.cs @@ -108,7 +108,7 @@ public class GridClient /// public GridClient() { - // Initialise SmartThreadPool when using mono + // Initialize work pool settings when using mono if (Type.GetType("Mono.Runtime") != null) { WorkPool.Init(true); diff --git a/OpenMetaverse/Helpers.cs b/OpenMetaverse/Helpers.cs index 9687cc0c..5b870c2f 100644 --- a/OpenMetaverse/Helpers.cs +++ b/OpenMetaverse/Helpers.cs @@ -24,13 +24,10 @@ * POSSIBILITY OF SUCH DAMAGE. */ -using ComponentAce.Compression.Libs.zlib; using OpenMetaverse.StructuredData; -using System; -using System.Collections.Generic; -using System.IO; using System.Reflection; using System.Text; +using System.IO.Compression; namespace OpenMetaverse { @@ -621,35 +618,29 @@ public static void CopyStream(Stream input, Stream output) public static byte[] ZCompressOSD(OSD data) { - byte[] ret = null; + byte[] serialized = OSDParser.SerializeLLSDBinary(data, false); using (MemoryStream outMemoryStream = new MemoryStream()) - using (ZOutputStream outZStream = new ZOutputStream(outMemoryStream, zlibConst.Z_BEST_COMPRESSION)) - using (Stream inMemoryStream = new MemoryStream(OSDParser.SerializeLLSDBinary(data, false))) { - CopyStream(inMemoryStream, outZStream); - outZStream.finish(); - ret = outMemoryStream.ToArray(); - } + using (ZLibStream outZStream = new ZLibStream(outMemoryStream, CompressionLevel.SmallestSize, true)) + { + outZStream.Write(serialized, 0, serialized.Length); + } - return ret; + return outMemoryStream.ToArray(); + } } public static OSD ZDecompressOSD(byte[] data) { - OSD ret; - using (MemoryStream input = new MemoryStream(data)) + using (ZLibStream zStream = new ZLibStream(input, CompressionMode.Decompress)) using (MemoryStream output = new MemoryStream()) - using (ZOutputStream zout = new ZOutputStream(output)) { - CopyStream(input, zout); - zout.finish(); + CopyStream(zStream, output); output.Seek(0, SeekOrigin.Begin); - ret = OSDParser.DeserializeLLSDBinary(output); + return OSDParser.DeserializeLLSDBinary(output); } - - return ret; } } } diff --git a/OpenMetaverse/Imaging/BakeLayer.cs b/OpenMetaverse/Imaging/BakeLayer.cs index bc8e6f0e..ed933e88 100644 --- a/OpenMetaverse/Imaging/BakeLayer.cs +++ b/OpenMetaverse/Imaging/BakeLayer.cs @@ -26,9 +26,9 @@ using log4net; using OpenMetaverse.Assets; +using SkiaSharp; using System; using System.Collections.Generic; -using System.Drawing; using System.IO; using System.Reflection; @@ -340,7 +340,7 @@ public static ManagedImage LoadResourceLayer(string fileName) { try { - Bitmap bitmap = null; + SKBitmap bitmap = null; lock (ResourceSync) { using (Stream stream = Helpers.GetResourceStream(fileName, Settings.RESOURCE_DIR)) @@ -355,7 +355,8 @@ public static ManagedImage LoadResourceLayer(string fileName) } else { - return new ManagedImage(bitmap); + using (bitmap) + return new ManagedImage(bitmap); } } catch (Exception e) diff --git a/OpenMetaverse/Imaging/ManagedImage.cs b/OpenMetaverse/Imaging/ManagedImage.cs index 27bb2d9d..2fd833ff 100644 --- a/OpenMetaverse/Imaging/ManagedImage.cs +++ b/OpenMetaverse/Imaging/ManagedImage.cs @@ -25,6 +25,8 @@ */ using System; +using System.Runtime.InteropServices; +using SkiaSharp; namespace OpenMetaverse.Imaging { @@ -120,101 +122,34 @@ public ManagedImage(int width, int height, ImageChannels channels) /// /// /// - public ManagedImage(System.Drawing.Bitmap bitmap) + public ManagedImage(SKBitmap bitmap) { Width = bitmap.Width; Height = bitmap.Height; int pixelCount = Width * Height; - if (bitmap.PixelFormat == System.Drawing.Imaging.PixelFormat.Format32bppArgb) - { - Channels = ImageChannels.Alpha | ImageChannels.Color; - Red = GC.AllocateUninitializedArray(pixelCount); - Green = GC.AllocateUninitializedArray(pixelCount); - Blue = GC.AllocateUninitializedArray(pixelCount); + bool hasAlpha = bitmap.AlphaType != SKAlphaType.Opaque; + Channels = ImageChannels.Color | (hasAlpha ? ImageChannels.Alpha : 0); + Red = GC.AllocateUninitializedArray(pixelCount); + Green = GC.AllocateUninitializedArray(pixelCount); + Blue = GC.AllocateUninitializedArray(pixelCount); + if (hasAlpha) Alpha = GC.AllocateUninitializedArray(pixelCount); - System.Drawing.Imaging.BitmapData bd = bitmap.LockBits(new System.Drawing.Rectangle(0, 0, Width, Height), - System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); - - unsafe - { - byte* pixel = (byte*)bd.Scan0; - - for (int i = 0; i < pixelCount; i++) - { - // GDI+ gives us BGRA and we need to turn that in to RGBA - Blue[i] = *(pixel++); - Green[i] = *(pixel++); - Red[i] = *(pixel++); - Alpha[i] = *(pixel++); - } - } - - bitmap.UnlockBits(bd); - } - else if (bitmap.PixelFormat == System.Drawing.Imaging.PixelFormat.Format16bppGrayScale) - { - Channels = ImageChannels.Gray; - Red = GC.AllocateUninitializedArray(pixelCount); - - throw new NotImplementedException("16bpp grayscale image support is incomplete"); - } - else if (bitmap.PixelFormat == System.Drawing.Imaging.PixelFormat.Format24bppRgb) + int i = 0; + for (int y = 0; y < Height; y++) { - Channels = ImageChannels.Color; - Red = GC.AllocateUninitializedArray(pixelCount); - Green = GC.AllocateUninitializedArray(pixelCount); - Blue = GC.AllocateUninitializedArray(pixelCount); - - System.Drawing.Imaging.BitmapData bd = bitmap.LockBits(new System.Drawing.Rectangle(0, 0, Width, Height), - System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format24bppRgb); - - unsafe + for (int x = 0; x < Width; x++) { - byte* pixel = (byte*)bd.Scan0; - - for (int i = 0; i < pixelCount; i++) - { - // GDI+ gives us BGR and we need to turn that in to RGB - Blue[i] = *(pixel++); - Green[i] = *(pixel++); - Red[i] = *(pixel++); - } + SKColor pixel = bitmap.GetPixel(x, y); + Red[i] = pixel.Red; + Green[i] = pixel.Green; + Blue[i] = pixel.Blue; + if (hasAlpha) + Alpha[i] = pixel.Alpha; + i++; } - - bitmap.UnlockBits(bd); - } - else if (bitmap.PixelFormat == System.Drawing.Imaging.PixelFormat.Format32bppRgb) - { - Channels = ImageChannels.Color; - Red = GC.AllocateUninitializedArray(pixelCount); - Green = GC.AllocateUninitializedArray(pixelCount); - Blue = GC.AllocateUninitializedArray(pixelCount); - - System.Drawing.Imaging.BitmapData bd = bitmap.LockBits(new System.Drawing.Rectangle(0, 0, Width, Height), - System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppRgb); - - unsafe - { - byte* pixel = (byte*)bd.Scan0; - - for (int i = 0; i < pixelCount; i++) - { - // GDI+ gives us BGR and we need to turn that in to RGB - Blue[i] = *(pixel++); - Green[i] = *(pixel++); - Red[i] = *(pixel++); - pixel++; // Skip over the empty byte where the Alpha info would normally be - } - } - - bitmap.UnlockBits(bd); - } - else - { - throw new NotSupportedException("Unrecognized pixel format: " + bitmap.PixelFormat.ToString()); } } @@ -380,7 +315,7 @@ public byte[] ExportRaw() /// origin, suitable for feeding directly into OpenGL /// /// A byte array containing raw texture data - public System.Drawing.Bitmap ExportBitmap() + public SKBitmap ExportBitmap() { byte[] raw = new byte[Width * Height * 4]; @@ -421,20 +356,9 @@ public System.Drawing.Bitmap ExportBitmap() } } - System.Drawing.Bitmap b = new System.Drawing.Bitmap( - Width, - Height, - System.Drawing.Imaging.PixelFormat.Format32bppArgb); - - System.Drawing.Imaging.BitmapData bd = b.LockBits(new System.Drawing.Rectangle(0, 0, b.Width, b.Height), - System.Drawing.Imaging.ImageLockMode.WriteOnly, - System.Drawing.Imaging.PixelFormat.Format32bppArgb); - - System.Runtime.InteropServices.Marshal.Copy(raw, 0, bd.Scan0, Width * Height * 4); - - b.UnlockBits(bd); - - return b; + SKBitmap bitmap = new SKBitmap(new SKImageInfo(Width, Height, SKColorType.Bgra8888, SKAlphaType.Unpremul)); + Marshal.Copy(raw, 0, bitmap.GetPixels(), Width * Height * 4); + return bitmap; } public byte[] ExportTGA() diff --git a/OpenMetaverse/Imaging/OpenJPEG.cs b/OpenMetaverse/Imaging/OpenJPEG.cs index 31a075d9..f967c159 100644 --- a/OpenMetaverse/Imaging/OpenJPEG.cs +++ b/OpenMetaverse/Imaging/OpenJPEG.cs @@ -24,513 +24,115 @@ * POSSIBILITY OF SUCH DAMAGE. */ +using CoreJ2K; +using SkiaSharp; using System; -using System.Drawing; -using System.Drawing.Imaging; -using System.Runtime.InteropServices; namespace OpenMetaverse.Imaging { /// - /// A Wrapper around openjpeg to encode and decode images to and from byte arrays + /// JPEG2000 codec wrapper implemented with CoreJ2K. /// - public class OpenJPEG + public static class OpenJPEG { /// TGA Header size public const int TGA_HEADER_SIZE = 32; - #region JPEG2000 Structs - /// /// Defines the beginning and ending file positions of a layer in an /// LRCP-progression JPEG2000 file /// [System.Diagnostics.DebuggerDisplay("Start = {Start} End = {End} Size = {End - Start}")] - [StructLayout(LayoutKind.Sequential, Pack = 4)] public struct J2KLayerInfo { public int Start; public int End; } - /// - /// This structure is used to marshal both encoded and decoded images. - /// MUST MATCH THE STRUCT IN dotnet.h! - /// - [StructLayout(LayoutKind.Sequential, Pack = 4)] - private struct MarshalledImage - { - public IntPtr encoded; // encoded image data - public int length; // encoded image length - public int dummy; // padding for 64-bit alignment - - public IntPtr decoded; // decoded image, contiguous components - - public int width; // width of decoded image - public int height; // height of decoded image - public int layers; // layer count - public int resolutions; // resolution count - public int components; // component count - public int packet_count; // packet count - public IntPtr packets; // pointer to the packets array - } - - /// - /// Information about a single packet in a JPEG2000 stream - /// - [StructLayout(LayoutKind.Sequential, Pack = 4)] - private struct MarshalledPacket - { - /// Packet start position - public int start_pos; - /// Packet header end position - public int end_ph_pos; - /// Packet end position - public int end_pos; - - public override string ToString() - { - return String.Format("start_pos: {0} end_ph_pos: {1} end_pos: {2}", - start_pos, end_ph_pos, end_pos); - } - } - #endregion JPEG2000 Structs - - static OpenJPEG() - { - DllmapConfigHelper.RegisterAssembly(typeof(OpenJPEG).Assembly); - } - - #region Unmanaged Function Declarations - // allocate encoded buffer based on length field - [System.Security.SuppressUnmanagedCodeSecurity] - [DllImport("openjpeg-dotnet", CallingConvention = CallingConvention.Cdecl)] - private static extern bool DotNetAllocEncoded(ref MarshalledImage image); - - // allocate decoded buffer based on width and height fields - [System.Security.SuppressUnmanagedCodeSecurity] - [DllImport("openjpeg-dotnet", CallingConvention = CallingConvention.Cdecl)] - private static extern bool DotNetAllocDecoded(ref MarshalledImage image); - - // free buffers - [System.Security.SuppressUnmanagedCodeSecurity] - [DllImport("openjpeg-dotnet", CallingConvention = CallingConvention.Cdecl)] - private static extern bool DotNetFree(ref MarshalledImage image); - - // encode raw to jpeg2000 - [System.Security.SuppressUnmanagedCodeSecurity] - [DllImport("openjpeg-dotnet", CallingConvention = CallingConvention.Cdecl)] - private static extern bool DotNetEncode(ref MarshalledImage image, bool lossless); - - // decode jpeg2000 to raw - [System.Security.SuppressUnmanagedCodeSecurity] - [DllImport("openjpeg-dotnet", CallingConvention = CallingConvention.Cdecl)] - private static extern bool DotNetDecode(ref MarshalledImage image); - - // decode jpeg2000 to raw, get jpeg2000 file info - [System.Security.SuppressUnmanagedCodeSecurity] - [DllImport("openjpeg-dotnet", CallingConvention = CallingConvention.Cdecl)] - private static extern bool DotNetDecodeWithInfo(ref MarshalledImage image); - - #endregion - /// OpenJPEG is not threadsafe, so this object is used to lock - /// during calls into unmanaged code - private static object OpenJPEGLock = new object(); - - /// - /// Encode a object into a byte array - /// - /// The object to encode - /// true to enable lossless conversion, only useful for small images ie: sculptmaps - /// A byte array containing the encoded Image object public static byte[] Encode(ManagedImage image, bool lossless) { if ((image.Channels & ManagedImage.ImageChannels.Color) == 0 || ((image.Channels & ManagedImage.ImageChannels.Bump) != 0 && (image.Channels & ManagedImage.ImageChannels.Alpha) == 0)) throw new ArgumentException("JPEG2000 encoding is not supported for this channel combination"); - byte[] encoded = null; - MarshalledImage marshalled = new MarshalledImage(); - - // allocate and copy to input buffer - marshalled.width = image.Width; - marshalled.height = image.Height; - marshalled.components = 3; - if ((image.Channels & ManagedImage.ImageChannels.Alpha) != 0) marshalled.components++; - if ((image.Channels & ManagedImage.ImageChannels.Bump) != 0) marshalled.components++; - - lock (OpenJPEGLock) - { - bool allocSuccess = DotNetAllocDecoded(ref marshalled); - if (!allocSuccess) - throw new Exception("DotNetAllocDecoded failed"); - - int n = image.Width * image.Height; - - if ((image.Channels & ManagedImage.ImageChannels.Color) != 0) - { - Marshal.Copy(image.Red, 0, marshalled.decoded, n); - Marshal.Copy(image.Green, 0, (IntPtr)(marshalled.decoded.ToInt64() + n), n); - Marshal.Copy(image.Blue, 0, (IntPtr)(marshalled.decoded.ToInt64() + n * 2), n); - } - - if ((image.Channels & ManagedImage.ImageChannels.Alpha) != 0) Marshal.Copy(image.Alpha, 0, (IntPtr)(marshalled.decoded.ToInt64() + n * 3), n); - if ((image.Channels & ManagedImage.ImageChannels.Bump) != 0) Marshal.Copy(image.Bump, 0, (IntPtr)(marshalled.decoded.ToInt64() + n * 4), n); - - // codec will allocate output buffer - bool encodeSuccess = DotNetEncode(ref marshalled, lossless); - if (!encodeSuccess) - throw new Exception("DotNetEncode failed"); - - // copy output buffer - encoded = new byte[marshalled.length]; - Marshal.Copy(marshalled.encoded, encoded, 0, marshalled.length); - - // free buffers - DotNetFree(ref marshalled); - } - - return encoded; + using SKBitmap bitmap = image.ExportBitmap(); + return J2kImage.ToBytes(bitmap); } - /// - /// Encode a object into a byte array - /// - /// The object to encode - /// a byte array of the encoded image public static byte[] Encode(ManagedImage image) { return Encode(image, false); } /// - /// Decode JPEG2000 data to an and - /// + /// Decode JPEG2000 data to a ManagedImage and SKBitmap. /// - /// JPEG2000 encoded data - /// ManagedImage object to decode to - /// Image object to decode to - /// True if the decode succeeds, otherwise false - public static bool DecodeToImage(byte[] encoded, out ManagedImage managedImage, out Image image) + public static bool DecodeToImage(byte[] encoded, out ManagedImage managedImage, out SKBitmap image) { managedImage = null; image = null; - if (DecodeToImage(encoded, out managedImage)) + try { - try - { - image = managedImage.ExportBitmap(); - return true; - } - catch (Exception ex) - { - Logger.Log("Failed to export and load TGA data from decoded image", Helpers.LogLevel.Error, ex); - return false; - } + var decoded = J2kImage.FromBytes(encoded); + image = decoded.As(); + managedImage = new ManagedImage(image); + return true; } - else + catch (Exception ex) { + Logger.Log("Failed to decode JPEG2000 data", Helpers.LogLevel.Error, ex); + image?.Dispose(); + image = null; + managedImage = null; return false; } } - /// - /// - /// - /// - /// - /// public static bool DecodeToImage(byte[] encoded, out ManagedImage managedImage) { - MarshalledImage marshalled = new MarshalledImage(); - - // Allocate and copy to input buffer - marshalled.length = encoded.Length; + managedImage = null; - lock (OpenJPEGLock) + try { - DotNetAllocEncoded(ref marshalled); - - Marshal.Copy(encoded, 0, marshalled.encoded, encoded.Length); - - // Codec will allocate output buffer - DotNetDecode(ref marshalled); - - int n = marshalled.width * marshalled.height; - - switch (marshalled.components) - { - case 1: // Grayscale - managedImage = new ManagedImage(marshalled.width, marshalled.height, - ManagedImage.ImageChannels.Color); - Marshal.Copy(marshalled.decoded, managedImage.Red, 0, n); - Buffer.BlockCopy(managedImage.Red, 0, managedImage.Green, 0, n); - Buffer.BlockCopy(managedImage.Red, 0, managedImage.Blue, 0, n); - break; - - case 2: // Grayscale + alpha - managedImage = new ManagedImage(marshalled.width, marshalled.height, - ManagedImage.ImageChannels.Color | ManagedImage.ImageChannels.Alpha); - Marshal.Copy(marshalled.decoded, managedImage.Red, 0, n); - Buffer.BlockCopy(managedImage.Red, 0, managedImage.Green, 0, n); - Buffer.BlockCopy(managedImage.Red, 0, managedImage.Blue, 0, n); - Marshal.Copy((IntPtr)(marshalled.decoded.ToInt64() + (long)n), managedImage.Alpha, 0, n); - break; - - case 3: // RGB - managedImage = new ManagedImage(marshalled.width, marshalled.height, - ManagedImage.ImageChannels.Color); - Marshal.Copy(marshalled.decoded, managedImage.Red, 0, n); - Marshal.Copy((IntPtr)(marshalled.decoded.ToInt64() + (long)n), managedImage.Green, 0, n); - Marshal.Copy((IntPtr)(marshalled.decoded.ToInt64() + (long)(n * 2)), managedImage.Blue, 0, n); - break; - - case 4: // RGBA - managedImage = new ManagedImage(marshalled.width, marshalled.height, - ManagedImage.ImageChannels.Color | ManagedImage.ImageChannels.Alpha); - Marshal.Copy(marshalled.decoded, managedImage.Red, 0, n); - Marshal.Copy((IntPtr)(marshalled.decoded.ToInt64() + (long)n), managedImage.Green, 0, n); - Marshal.Copy((IntPtr)(marshalled.decoded.ToInt64() + (long)(n * 2)), managedImage.Blue, 0, n); - Marshal.Copy((IntPtr)(marshalled.decoded.ToInt64() + (long)(n * 3)), managedImage.Alpha, 0, n); - break; - - case 5: // RGBAB - managedImage = new ManagedImage(marshalled.width, marshalled.height, - ManagedImage.ImageChannels.Color | ManagedImage.ImageChannels.Alpha | ManagedImage.ImageChannels.Bump); - Marshal.Copy(marshalled.decoded, managedImage.Red, 0, n); - Marshal.Copy((IntPtr)(marshalled.decoded.ToInt64() + (long)n), managedImage.Green, 0, n); - Marshal.Copy((IntPtr)(marshalled.decoded.ToInt64() + (long)(n * 2)), managedImage.Blue, 0, n); - Marshal.Copy((IntPtr)(marshalled.decoded.ToInt64() + (long)(n * 3)), managedImage.Alpha, 0, n); - Marshal.Copy((IntPtr)(marshalled.decoded.ToInt64() + (long)(n * 4)), managedImage.Bump, 0, n); - break; - - default: - Logger.Log("Decoded image with unhandled number of components: " + marshalled.components, - Helpers.LogLevel.Error); - - DotNetFree(ref marshalled); - - managedImage = null; - return false; - } - - DotNetFree(ref marshalled); + var decoded = J2kImage.FromBytes(encoded); + using SKBitmap image = decoded.As(); + managedImage = new ManagedImage(image); + return true; + } + catch (Exception ex) + { + Logger.Log("Failed to decode JPEG2000 data", Helpers.LogLevel.Error, ex); + managedImage = null; + return false; } - - return true; } - /// - /// - /// - /// - /// - /// - /// public static bool DecodeLayerBoundaries(byte[] encoded, out J2KLayerInfo[] layerInfo, out int components) { - bool success = false; layerInfo = null; components = 0; - MarshalledImage marshalled = new MarshalledImage(); - - // Allocate and copy to input buffer - marshalled.length = encoded.Length; - - lock (OpenJPEGLock) - { - DotNetAllocEncoded(ref marshalled); - - Marshal.Copy(encoded, 0, marshalled.encoded, encoded.Length); - - // Run the decode - bool decodeSuccess = DotNetDecodeWithInfo(ref marshalled); - if (decodeSuccess) - { - components = marshalled.components; - - // Sanity check - if (marshalled.layers * marshalled.resolutions * marshalled.components == marshalled.packet_count) - { - // Manually marshal the array of opj_packet_info structs - MarshalledPacket[] packets = new MarshalledPacket[marshalled.packet_count]; - int offset = 0; - - for (int i = 0; i < marshalled.packet_count; i++) - { - MarshalledPacket packet; - packet.start_pos = Marshal.ReadInt32(marshalled.packets, offset); - offset += 4; - packet.end_ph_pos = Marshal.ReadInt32(marshalled.packets, offset); - offset += 4; - packet.end_pos = Marshal.ReadInt32(marshalled.packets, offset); - offset += 4; - //double distortion = (double)Marshal.ReadInt64(marshalled.packets, offset); - offset += 8; - - packets[i] = packet; - } - - layerInfo = new J2KLayerInfo[marshalled.layers]; - for (int i = 0; i < marshalled.layers; i++) - { - int packetsPerLayer = marshalled.packet_count / marshalled.layers; - MarshalledPacket startPacket = packets[packetsPerLayer * i]; - MarshalledPacket endPacket = packets[(packetsPerLayer * (i + 1)) - 1]; - layerInfo[i].Start = startPacket.start_pos; - layerInfo[i].End = endPacket.end_pos; - } - - // More sanity checking - if (layerInfo.Length == 0 || layerInfo[layerInfo.Length - 1].End <= encoded.Length - 1) - { - success = true; - - for (int i = 0; i < layerInfo.Length; i++) - { - if (layerInfo[i].Start >= layerInfo[i].End || - (i > 0 && layerInfo[i].Start <= layerInfo[i - 1].End)) - { - System.Text.StringBuilder output = new System.Text.StringBuilder( - "Inconsistent packet data in JPEG2000 stream:\n"); - for (int j = 0; j < layerInfo.Length; j++) - output.AppendFormat("Layer {0}: Start: {1} End: {2}\n", j, layerInfo[j].Start, layerInfo[j].End); - Logger.DebugLog(output.ToString()); - - success = false; - break; - } - } - - if (!success) - { - for (int i = 0; i < layerInfo.Length; i++) - { - if (i < layerInfo.Length - 1) - layerInfo[i].End = layerInfo[i + 1].Start - 1; - else - layerInfo[i].End = marshalled.length; - } - - Logger.DebugLog("Corrected JPEG2000 packet data"); - success = true; - - for (int i = 0; i < layerInfo.Length; i++) - { - if (layerInfo[i].Start >= layerInfo[i].End || - (i > 0 && layerInfo[i].Start <= layerInfo[i - 1].End)) - { - System.Text.StringBuilder output = new System.Text.StringBuilder( - "Still inconsistent packet data in JPEG2000 stream, giving up:\n"); - for (int j = 0; j < layerInfo.Length; j++) - output.AppendFormat("Layer {0}: Start: {1} End: {2}\n", j, layerInfo[j].Start, layerInfo[j].End); - Logger.DebugLog(output.ToString()); - - success = false; - break; - } - } - } - } - else - { - Logger.Log(String.Format( - "Last packet end in JPEG2000 stream extends beyond the end of the file. filesize={0} layerend={1}", - encoded.Length, layerInfo[layerInfo.Length - 1].End), Helpers.LogLevel.Warning); - } - } - else - { - Logger.Log(String.Format( - "Packet count mismatch in JPEG2000 stream. layers={0} resolutions={1} components={2} packets={3}", - marshalled.layers, marshalled.resolutions, marshalled.components, marshalled.packet_count), - Helpers.LogLevel.Warning); - } - } + if (!DecodeToImage(encoded, out ManagedImage managedImage) || managedImage == null) + return false; - DotNetFree(ref marshalled); - } + if ((managedImage.Channels & ManagedImage.ImageChannels.Color) != 0) components += 3; + if ((managedImage.Channels & ManagedImage.ImageChannels.Gray) != 0) components += 1; + if ((managedImage.Channels & ManagedImage.ImageChannels.Alpha) != 0) components += 1; + if ((managedImage.Channels & ManagedImage.ImageChannels.Bump) != 0) components += 1; - return success; + layerInfo = new J2KLayerInfo[1]; + layerInfo[0].Start = 0; + layerInfo[0].End = encoded?.Length ?? 0; + return true; } - /// - /// Encode a object into a byte array - /// - /// The source object to encode - /// true to enable lossless decoding - /// A byte array containing the source Bitmap object - public unsafe static byte[] EncodeFromImage(Bitmap bitmap, bool lossless) + public static byte[] EncodeFromImage(SKBitmap bitmap, bool lossless) { - BitmapData bd; - ManagedImage decoded; - - int bitmapWidth = bitmap.Width; - int bitmapHeight = bitmap.Height; - int pixelCount = bitmapWidth * bitmapHeight; - int i; - - if ((bitmap.PixelFormat & PixelFormat.Alpha) != 0 || (bitmap.PixelFormat & PixelFormat.PAlpha) != 0) - { - // Four layers, RGBA - decoded = new ManagedImage(bitmapWidth, bitmapHeight, - ManagedImage.ImageChannels.Color | ManagedImage.ImageChannels.Alpha); - bd = bitmap.LockBits(new Rectangle(0, 0, bitmapWidth, bitmapHeight), - ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); - byte* pixel = (byte*)bd.Scan0; - - for (i = 0; i < pixelCount; i++) - { - // GDI+ gives us BGRA and we need to turn that in to RGBA - decoded.Blue[i] = *(pixel++); - decoded.Green[i] = *(pixel++); - decoded.Red[i] = *(pixel++); - decoded.Alpha[i] = *(pixel++); - } - } - else if (bitmap.PixelFormat == PixelFormat.Format16bppGrayScale) - { - // One layer - decoded = new ManagedImage(bitmapWidth, bitmapHeight, - ManagedImage.ImageChannels.Color); - bd = bitmap.LockBits(new Rectangle(0, 0, bitmapWidth, bitmapHeight), - ImageLockMode.ReadOnly, PixelFormat.Format16bppGrayScale); - byte* pixel = (byte*)bd.Scan0; - - for (i = 0; i < pixelCount; i++) - { - // Normalize 16-bit data down to 8-bit - ushort origVal = (byte)(*(pixel) + (*(pixel + 1) << 8)); - byte val = (byte)(((double)origVal / (double)UInt32.MaxValue) * (double)Byte.MaxValue); - - decoded.Red[i] = val; - decoded.Green[i] = val; - decoded.Blue[i] = val; - pixel += 2; - } - } - else - { - // Three layers, RGB - decoded = new ManagedImage(bitmapWidth, bitmapHeight, - ManagedImage.ImageChannels.Color); - bd = bitmap.LockBits(new Rectangle(0, 0, bitmapWidth, bitmapHeight), - ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb); - byte* pixel = (byte*)bd.Scan0; - - for (i = 0; i < pixelCount; i++) - { - decoded.Blue[i] = *(pixel++); - decoded.Green[i] = *(pixel++); - decoded.Red[i] = *(pixel++); - } - } + if (bitmap == null) + throw new ArgumentNullException(nameof(bitmap)); - bitmap.UnlockBits(bd); - byte[] encoded = Encode(decoded, lossless); - return encoded; + return J2kImage.ToBytes(bitmap); } } } diff --git a/OpenMetaverse/Imaging/TGALoader.cs b/OpenMetaverse/Imaging/TGALoader.cs index 111e369a..f27e9475 100644 --- a/OpenMetaverse/Imaging/TGALoader.cs +++ b/OpenMetaverse/Imaging/TGALoader.cs @@ -25,8 +25,8 @@ */ using System; -using System.Drawing; using System.IO; +using SkiaSharp; namespace OpenMetaverse.Imaging { @@ -130,6 +130,14 @@ struct tgaCD public bool NeedNoConvert; } + struct TgaBitmapData + { + public int Width; + public int Height; + public int Stride; + public IntPtr Scan0; + } + static uint UnpackColor( uint sourceColor, ref tgaCD cd) { @@ -153,7 +161,7 @@ static uint UnpackColor( } static unsafe void decodeLine( - System.Drawing.Imaging.BitmapData b, + TgaBitmapData b, int line, int byp, byte[] data, @@ -197,7 +205,7 @@ static unsafe void decodeLine( } static void decodeRle( - System.Drawing.Imaging.BitmapData b, + TgaBitmapData b, int byp, tgaCD cd, System.IO.BinaryReader br, bool bottomUp) { try @@ -262,7 +270,7 @@ static void decodeRle( } static void decodePlain( - System.Drawing.Imaging.BitmapData b, + TgaBitmapData b, int byp, tgaCD cd, System.IO.BinaryReader br, bool bottomUp) { int w = b.Width; @@ -280,7 +288,7 @@ static void decodePlain( } static void decodeStandard8( - System.Drawing.Imaging.BitmapData b, + TgaBitmapData b, tgaHeader hdr, System.IO.BinaryReader br) { @@ -301,7 +309,7 @@ static void decodeStandard8( } static void decodeSpecial16( - System.Drawing.Imaging.BitmapData b, tgaHeader hdr, System.IO.BinaryReader br) + TgaBitmapData b, tgaHeader hdr, System.IO.BinaryReader br) { // i must convert the input stream to a sequence of uint values // which I then unpack. @@ -323,7 +331,7 @@ static void decodeSpecial16( } static void decodeStandard16( - System.Drawing.Imaging.BitmapData b, + TgaBitmapData b, tgaHeader hdr, System.IO.BinaryReader br) { @@ -347,7 +355,7 @@ static void decodeStandard16( } - static void decodeSpecial24(System.Drawing.Imaging.BitmapData b, + static void decodeSpecial24(TgaBitmapData b, tgaHeader hdr, System.IO.BinaryReader br) { // i must convert the input stream to a sequence of uint values @@ -369,7 +377,7 @@ static void decodeSpecial24(System.Drawing.Imaging.BitmapData b, decodePlain(b, 3, cd, br, hdr.ImageSpec.BottomUp); } - static void decodeStandard24(System.Drawing.Imaging.BitmapData b, + static void decodeStandard24(TgaBitmapData b, tgaHeader hdr, System.IO.BinaryReader br) { // i must convert the input stream to a sequence of uint values @@ -391,7 +399,7 @@ static void decodeStandard24(System.Drawing.Imaging.BitmapData b, decodePlain(b, 3, cd, br, hdr.ImageSpec.BottomUp); } - static void decodeStandard32(System.Drawing.Imaging.BitmapData b, + static void decodeStandard32(TgaBitmapData b, tgaHeader hdr, System.IO.BinaryReader br) { // i must convert the input stream to a sequence of uint values @@ -415,7 +423,7 @@ static void decodeStandard32(System.Drawing.Imaging.BitmapData b, } - public static System.Drawing.Size GetTGASize(string filename) + public static SKSizeI GetTGASize(string filename) { System.IO.FileStream f = System.IO.File.OpenRead(filename); @@ -425,93 +433,14 @@ public static System.Drawing.Size GetTGASize(string filename) header.Read(br); br.Close(); - return new Size(header.ImageSpec.Width, header.ImageSpec.Height); + return new SKSizeI(header.ImageSpec.Width, header.ImageSpec.Height); } - public static Bitmap LoadTGA(System.IO.Stream source) + public static SKBitmap LoadTGA(System.IO.Stream source) { - byte[] buffer = new byte[source.Length]; - source.Read(buffer, 0, buffer.Length); - - using (MemoryStream ms = new MemoryStream(buffer)) - using (System.IO.BinaryReader br = new BinaryReader(ms)) - { - tgaHeader header = new tgaHeader(); - header.Read(br); - - if (header.ImageSpec.PixelDepth != 8 && - header.ImageSpec.PixelDepth != 16 && - header.ImageSpec.PixelDepth != 24 && - header.ImageSpec.PixelDepth != 32) - throw new ArgumentException("Not a supported tga file."); - - if (header.ImageSpec.AlphaBits > 8) - throw new ArgumentException("Not a supported tga file."); - - if (header.ImageSpec.Width > 4096 || - header.ImageSpec.Height > 4096) - throw new ArgumentException("Image too large."); - - System.Drawing.Bitmap b; - System.Drawing.Imaging.BitmapData bd; - - // Create a bitmap for the image. - // Only include an alpha layer when the image requires one. - if (header.ImageSpec.AlphaBits > 0 || - header.ImageSpec.PixelDepth == 8 || // Assume 8 bit images are alpha only - header.ImageSpec.PixelDepth == 32) // Assume 32 bit images are ARGB - { // Image needs an alpha layer - b = new System.Drawing.Bitmap( - header.ImageSpec.Width, - header.ImageSpec.Height, - System.Drawing.Imaging.PixelFormat.Format32bppArgb); - - bd = b.LockBits(new System.Drawing.Rectangle(0, 0, b.Width, b.Height), - System.Drawing.Imaging.ImageLockMode.WriteOnly, - System.Drawing.Imaging.PixelFormat.Format32bppPArgb); - } - else - { // Image does not need an alpha layer, so do not include one. - b = new System.Drawing.Bitmap( - header.ImageSpec.Width, - header.ImageSpec.Height, - System.Drawing.Imaging.PixelFormat.Format32bppRgb); - - bd = b.LockBits(new System.Drawing.Rectangle(0, 0, b.Width, b.Height), - System.Drawing.Imaging.ImageLockMode.WriteOnly, - System.Drawing.Imaging.PixelFormat.Format32bppRgb); - } - - switch (header.ImageSpec.PixelDepth) - { - case 8: - decodeStandard8(bd, header, br); - break; - case 16: - if (header.ImageSpec.AlphaBits > 0) - decodeSpecial16(bd, header, br); - else - decodeStandard16(bd, header, br); - break; - case 24: - if (header.ImageSpec.AlphaBits > 0) - decodeSpecial24(bd, header, br); - else - decodeStandard24(bd, header, br); - break; - case 32: - decodeStandard32(bd, header, br); - break; - default: - b.UnlockBits(bd); - b.Dispose(); - return null; - } - - b.UnlockBits(bd); - return b; - } + ManagedImage image = LoadTGAImage(source); + return image?.ExportBitmap(); } public static unsafe ManagedImage LoadTGAImage(System.IO.Stream source) @@ -544,13 +473,12 @@ public static unsafe ManagedImage LoadTGAImage(System.IO.Stream source, bool mas throw new ArgumentException("Image too large."); byte[] decoded = new byte[header.ImageSpec.Width * header.ImageSpec.Height * 4]; - System.Drawing.Imaging.BitmapData bd = new System.Drawing.Imaging.BitmapData(); + TgaBitmapData bd = new TgaBitmapData(); fixed (byte* pdecoded = &decoded[0]) { bd.Width = header.ImageSpec.Width; bd.Height = header.ImageSpec.Height; - bd.PixelFormat = System.Drawing.Imaging.PixelFormat.Format32bppPArgb; bd.Stride = header.ImageSpec.Width * 4; bd.Scan0 = (IntPtr)pdecoded; @@ -614,7 +542,7 @@ public static unsafe ManagedImage LoadTGAImage(System.IO.Stream source, bool mas } } - public static System.Drawing.Bitmap LoadTGA(string filename) + public static SKBitmap LoadTGA(string filename) { try { diff --git a/OpenMetaverse/ImportExport/ColladalLoader.cs b/OpenMetaverse/ImportExport/ColladalLoader.cs index 1885d846..ce4de33e 100644 --- a/OpenMetaverse/ImportExport/ColladalLoader.cs +++ b/OpenMetaverse/ImportExport/ColladalLoader.cs @@ -28,9 +28,9 @@ using OpenMetaverse.Imaging; using OpenMetaverse.ImportExport.Collada14; using OpenMetaverse.Rendering; +using SkiaSharp; using System; using System.Collections.Generic; -using System.Drawing; using System.IO; using System.Text.RegularExpressions; using System.Xml; @@ -114,7 +114,7 @@ void LoadImage(ModelMaterial material) { string ext = System.IO.Path.GetExtension(material.Texture).ToLower(); - Bitmap bitmap = null; + SKBitmap bitmap = null; if (ext == ".jp2" || ext == ".j2c") { @@ -128,9 +128,15 @@ void LoadImage(ModelMaterial material) } else { - bitmap = (Bitmap)Image.FromFile(fname); + using (var stream = File.OpenRead(fname)) + { + bitmap = SKBitmap.Decode(stream); + } } + if (bitmap == null) + throw new Exception("Failed to decode texture image"); + int width = bitmap.Width; int height = bitmap.Height; @@ -148,19 +154,15 @@ void LoadImage(ModelMaterial material) Logger.Log("Image has irregular dimensions " + origWidth + "x" + origHieght + ". Resizing to " + width + "x" + height, Helpers.LogLevel.Info); - Bitmap resized = new Bitmap(width, height, bitmap.PixelFormat); - Graphics graphics = Graphics.FromImage(resized); - - graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; - graphics.InterpolationMode = - System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; - graphics.DrawImage(bitmap, 0, 0, width, height); + SKBitmap resized = bitmap.Resize(new SKImageInfo(width, height), SKFilterQuality.High) + ?? throw new Exception("Failed to resize texture image"); bitmap.Dispose(); bitmap = resized; } material.TextureData = OpenJPEG.EncodeFromImage(bitmap, false); + bitmap.Dispose(); Logger.Log("Successfully encoded " + fname, Helpers.LogLevel.Info); } diff --git a/OpenMetaverse/Interfaces/IRendering.cs b/OpenMetaverse/Interfaces/IRendering.cs index 8af30d3c..706ac071 100644 --- a/OpenMetaverse/Interfaces/IRendering.cs +++ b/OpenMetaverse/Interfaces/IRendering.cs @@ -26,7 +26,7 @@ using System; using System.Collections.Generic; -using System.Drawing; +using SkiaSharp; namespace OpenMetaverse.Rendering { @@ -68,7 +68,7 @@ public interface IRendering /// Sculpt texture /// Level of detail to generate the mesh at /// The generated mesh - SimpleMesh GenerateSimpleSculptMesh(Primitive prim, Bitmap sculptTexture, DetailLevel lod); + SimpleMesh GenerateSimpleSculptMesh(Primitive prim, SKBitmap sculptTexture, DetailLevel lod); /// /// Generates a series of faces, each face containing a mesh and @@ -87,7 +87,7 @@ public interface IRendering /// Sculpt texture /// Level of detail to generate the mesh at /// The generated mesh - FacetedMesh GenerateFacetedSculptMesh(Primitive prim, Bitmap sculptTexture, DetailLevel lod); + FacetedMesh GenerateFacetedSculptMesh(Primitive prim, SKBitmap sculptTexture, DetailLevel lod); /// /// Apply texture coordinate modifications from a diff --git a/OpenMetaverse/Inventory.cs b/OpenMetaverse/Inventory.cs index cfeadd17..ce574a8c 100644 --- a/OpenMetaverse/Inventory.cs +++ b/OpenMetaverse/Inventory.cs @@ -27,7 +27,6 @@ using System; using System.Collections.Generic; using System.IO; -using System.Runtime.Serialization.Formatters.Binary; namespace OpenMetaverse { @@ -357,7 +356,6 @@ public void SaveToDisk(string filename) { using (Stream stream = File.Open(filename, FileMode.Create)) { - BinaryFormatter bformatter = new BinaryFormatter(); lock (Items) { Logger.Log("Caching " + Items.Count.ToString() + " inventory items to " + filename, Helpers.LogLevel.Info); diff --git a/OpenMetaverse/Messages/LindenMessages.cs b/OpenMetaverse/Messages/LindenMessages.cs index e52f4399..4a5363ec 100644 --- a/OpenMetaverse/Messages/LindenMessages.cs +++ b/OpenMetaverse/Messages/LindenMessages.cs @@ -24,12 +24,12 @@ * POSSIBILITY OF SUCH DAMAGE. */ -using ComponentAce.Compression.Libs.zlib; using OpenMetaverse.Interfaces; using OpenMetaverse.StructuredData; using System; using System.Collections.Generic; using System.IO; +using System.IO.Compression; using System.Net; namespace OpenMetaverse.Messages.Linden @@ -1813,76 +1813,76 @@ public OSDMap Serialize() } - public class LargeGenericMessage : IMessage - { - private OSDMap RawData; - public UUID AgentID; - public UUID SessionID; - public UUID TransactionID; - - public string Method; - public UUID Invoice; - - public class Parameter - { - public string value; - } - - public Parameter[] Parameters; - - public void Deserialize(OSDMap map) - { - RawData = map; - OSD osdtmp, osdtmp2; - if (map.TryGetValue("AgentData", out osdtmp)) - { - if (osdtmp is OSDArray agdArray && agdArray.Count > 0) - { - if (agdArray[0] is OSDMap agdMap) - { - if (agdMap.TryGetValue("AgentID", out osdtmp2)) - AgentID = osdtmp2.AsUUID(); - if (agdMap.TryGetValue("SessionID", out osdtmp2)) - SessionID = osdtmp2.AsUUID(); - if (agdMap.TryGetValue("TransactionID", out osdtmp2)) - TransactionID = osdtmp2.AsUUID(); - } - } - } - if (map.TryGetValue("MethodData", out osdtmp)) - { - if (osdtmp is OSDArray mdArray && mdArray.Count > 0) - { - if (mdArray[0] is OSDMap mdMap) - { - if (mdMap.TryGetValue("Method", out osdtmp2)) - Method = osdtmp2.AsString(); - if (mdMap.TryGetValue("Invoice", out osdtmp2)) - Invoice = osdtmp2.AsUUID(); - } - } - } - if (map.TryGetValue("ParamList", out osdtmp)) - { - if (osdtmp is OSDArray pArray && pArray.Count > 0) - { - Parameters = new Parameter[pArray.Count]; - for(int i = 0; i < Parameters.Length; i++) - { - Parameters[i] = new Parameter(){value = pArray[i].ToString() }; - } - } - } - - Method ??="MissingMethod"; - } - - public OSDMap Serialize() - { - return RawData; - } - } - + public class LargeGenericMessage : IMessage + { + private OSDMap RawData; + public UUID AgentID; + public UUID SessionID; + public UUID TransactionID; + + public string Method; + public UUID Invoice; + + public class Parameter + { + public string value; + } + + public Parameter[] Parameters; + + public void Deserialize(OSDMap map) + { + RawData = map; + OSD osdtmp, osdtmp2; + if (map.TryGetValue("AgentData", out osdtmp)) + { + if (osdtmp is OSDArray agdArray && agdArray.Count > 0) + { + if (agdArray[0] is OSDMap agdMap) + { + if (agdMap.TryGetValue("AgentID", out osdtmp2)) + AgentID = osdtmp2.AsUUID(); + if (agdMap.TryGetValue("SessionID", out osdtmp2)) + SessionID = osdtmp2.AsUUID(); + if (agdMap.TryGetValue("TransactionID", out osdtmp2)) + TransactionID = osdtmp2.AsUUID(); + } + } + } + if (map.TryGetValue("MethodData", out osdtmp)) + { + if (osdtmp is OSDArray mdArray && mdArray.Count > 0) + { + if (mdArray[0] is OSDMap mdMap) + { + if (mdMap.TryGetValue("Method", out osdtmp2)) + Method = osdtmp2.AsString(); + if (mdMap.TryGetValue("Invoice", out osdtmp2)) + Invoice = osdtmp2.AsUUID(); + } + } + } + if (map.TryGetValue("ParamList", out osdtmp)) + { + if (osdtmp is OSDArray pArray && pArray.Count > 0) + { + Parameters = new Parameter[pArray.Count]; + for(int i = 0; i < Parameters.Length; i++) + { + Parameters[i] = new Parameter(){value = pArray[i].ToString() }; + } + } + } + + Method ??="MissingMethod"; + } + + public OSDMap Serialize() + { + return RawData; + } + } + /// Base class for Asset uploads/results via Capabilities public abstract class AssetUploaderBlock { @@ -4504,15 +4504,9 @@ public void Deserialize(OSDMap map) { using (MemoryStream output = new MemoryStream()) { - using (ZOutputStream zout = new ZOutputStream(output)) + using (ZLibStream zStream = new ZLibStream(input, CompressionMode.Decompress)) { - byte[] buffer = new byte[2048]; - int len; - while ((len = input.Read(buffer, 0, buffer.Length)) > 0) - { - zout.Write(buffer, 0, len); - } - zout.Flush(); + Helpers.CopyStream(zStream, output); output.Seek(0, SeekOrigin.Begin); MaterialData = OSDParser.DeserializeLLSDBinary(output); } diff --git a/OpenMetaverse/OpenMetaverse.csproj b/OpenMetaverse/OpenMetaverse.csproj index e07ca3fd..5aa648b8 100644 --- a/OpenMetaverse/OpenMetaverse.csproj +++ b/OpenMetaverse/OpenMetaverse.csproj @@ -8,6 +8,9 @@ + + + diff --git a/OpenMetaverse/WorkPool.cs b/OpenMetaverse/WorkPool.cs index 0604f52f..cc0267ca 100644 --- a/OpenMetaverse/WorkPool.cs +++ b/OpenMetaverse/WorkPool.cs @@ -24,208 +24,39 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#define SMARTHREADPOOL_REF - - -#if SMARTHREADPOOL_REF -using Amib.Threading; -#else using System.Threading; -#endif namespace OpenMetaverse { - - // Use statically referenced SmartThreadPool.dll -#if SMARTHREADPOOL_REF public static class WorkPool { - internal static SmartThreadPool Pool = null; + private static bool _initialized; public static bool Init(bool useSmartThredPool) { - if (Pool == null) - { - STPStartInfo param = new STPStartInfo(); - param.MinWorkerThreads = 2; - param.MaxWorkerThreads = 50; - param.ThreadPoolName = "LibOpenMetaverse Main ThreadPool"; - param.AreThreadsBackground = true; - - Pool = new SmartThreadPool(param); - } - return true; - } - - public static void Shutdown() - { - if (Pool != null) - { - Pool.Shutdown(); - Pool = null; - } - } - - public static void QueueUserWorkItem(System.Threading.WaitCallback callback) - { - if (Pool != null) - { - Pool.QueueWorkItem(state => { callback.Invoke(state); return null; }); - } - else - { - System.Threading.ThreadPool.QueueUserWorkItem(state => callback.Invoke(state)); - } - } - - public static void QueueUserWorkItem(System.Threading.WaitCallback callback, object state) - { - if (Pool != null) - { - Pool.QueueWorkItem(sync => { callback.Invoke(sync); return null; }, state); - } - else - { - System.Threading.ThreadPool.QueueUserWorkItem(sync => callback.Invoke(sync), state); - } - } - } - -#else - - // Try to load SmartThreadPool.dll during initialization - // Fallback to System.Threading.ThreadPool if that fails - public static class WorkPoolDynamic - { - internal static object Pool = null; - - private static Type SmartThreadPoolType; - private static Type WorkItemCallbackType; - private static MethodInfo QueueWorkItemFunc, QueueWorkItemFunc2; - private static MethodInfo ShutdownFunc; - private static Func Invoker; - - public static bool Init() - { - try - { - string dir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); - Assembly assembly = Assembly.LoadFile(Path.Combine(dir, "SmartThreadPool.dll")); - Type STPStartInfo = assembly.GetType("Amib.Threading.STPStartInfo"); - SmartThreadPoolType = assembly.GetType("Amib.Threading.SmartThreadPool"); - WorkItemCallbackType = assembly.GetType("Amib.Threading.WorkItemCallback"); - var param = Activator.CreateInstance(STPStartInfo); - STPStartInfo.GetProperty("MinWorkerThreads").SetValue(param, 2, null); - STPStartInfo.GetProperty("MaxWorkerThreads").SetValue(param, 50, null); - STPStartInfo.GetProperty("ThreadPoolName").SetValue(param, "LibOpenMetaverse Main ThreadPool", null); - STPStartInfo.GetProperty("AreThreadsBackground").SetValue(param, true, null); - STPStartInfo.GetProperty("MinWorkerThreads").SetValue(param, 2, null); - Pool = Activator.CreateInstance(SmartThreadPoolType, new object[] { param }); - QueueWorkItemFunc = SmartThreadPoolType.GetMethod("QueueWorkItem", new Type[] { WorkItemCallbackType }); - QueueWorkItemFunc2 = SmartThreadPoolType.GetMethod("QueueWorkItem", new Type[] { WorkItemCallbackType, typeof(object) }); - ShutdownFunc = SmartThreadPoolType.GetMethod("Shutdown", new Type[] { }); - - Invoker = (inv, state) => - { - inv.Invoke(state); - return null; - }; - - return true; - } - catch - { - Pool = null; - return false; - } - } - - public static void Shutdown() - { - if (Pool != null) - { - ShutdownFunc.Invoke(Pool, null); - Pool = null; - } - } - - - public static void QueueUserWorkItem(System.Threading.WaitCallback callback) - { - if (Pool != null) - { - QueueWorkItemFunc.Invoke(Pool, new object[] { Delegate.CreateDelegate(WorkItemCallbackType, callback, Invoker.Method) }); - } - else - { - System.Threading.ThreadPool.QueueUserWorkItem(state => callback.Invoke(state)); - } - } - - public static void QueueUserWorkItem(System.Threading.WaitCallback callback, object state) - { - if (Pool != null) - { - QueueWorkItemFunc2.Invoke(Pool, new object[] { Delegate.CreateDelegate(WorkItemCallbackType, callback, Invoker.Method), state }); - } - else + if (!_initialized) { - System.Threading.ThreadPool.QueueUserWorkItem(sync => callback.Invoke(sync), state); + // Preserve previous tuning intent while using the runtime thread pool. + ThreadPool.SetMinThreads(2, 2); + _initialized = true; } - } - } - - - public static class WorkPool - { - private static bool UseSmartThreadPool = false; - public static bool Init(bool useSmartThredPool) - { - if (useSmartThredPool) - { - if (WorkPoolDynamic.Init()) - { - UseSmartThreadPool = true; - return true; - } - return false; - } return true; } public static void Shutdown() { - if (UseSmartThreadPool) - { - WorkPoolDynamic.Shutdown(); - UseSmartThreadPool = false; - } + // System.Threading.ThreadPool is process-wide and cannot be explicitly shut down. } - public static void QueueUserWorkItem(System.Threading.WaitCallback callback) + public static void QueueUserWorkItem(WaitCallback callback) { - if (UseSmartThreadPool) - { - WorkPoolDynamic.QueueUserWorkItem(sync => callback.Invoke(sync)); - } - else - { - ThreadPool.QueueUserWorkItem(sync => callback.Invoke(sync)); - } + ThreadPool.QueueUserWorkItem(state => callback.Invoke(state)); } - public static void QueueUserWorkItem(System.Threading.WaitCallback callback, object state) + public static void QueueUserWorkItem(WaitCallback callback, object state) { - if (UseSmartThreadPool) - { - WorkPoolDynamic.QueueUserWorkItem(sync => callback.Invoke(sync), state); - } - else - { - ThreadPool.QueueUserWorkItem(sync => callback.Invoke(sync), state); - } + ThreadPool.QueueUserWorkItem(sync => callback.Invoke(sync), state); } } -#endif } diff --git a/build_log.txt b/build_log.txt new file mode 100644 index 00000000..cbce967b --- /dev/null +++ b/build_log.txt @@ -0,0 +1,33 @@ + Determining projects to restore... +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj : warning NU1902: Package 'log4net' 2.0.14 has a known moderate severity vulnerability, https://github.com/advisories/GHSA-4f7c-pmjv-c25w [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.sln] + All projects are up-to-date for restore. +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj : warning NU1902: Package 'log4net' 2.0.14 has a known moderate severity vulnerability, https://github.com/advisories/GHSA-4f7c-pmjv-c25w + OpenMetaverse.Types -> /home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.Types/bin/Debug/net8.0/OpenMetaverse.Types.dll + OpenMetaverse.StructuredData -> /home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.StructuredData/bin/Debug/net8.0/OpenMetaverse.StructuredData.dll + OpenMetaverse -> /home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/bin/Debug/net8.0/OpenMetaverse.dll +/usr/lib/dotnet/sdk/10.0.107/Microsoft.Common.CurrentVersion.targets(2437,5): warning MSB3245: Could not resolve this reference. Could not locate the assembly "System.Windows.Forms". Check to make sure the assembly exists on disk. If this reference is required by your code, you may get compilation errors. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/usr/lib/dotnet/sdk/10.0.107/Microsoft.Common.CurrentVersion.targets(2437,5): warning MSB3243: No way to resolve conflict between "System.Windows.Forms, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" and "System.Windows.Forms". Choosing "System.Windows.Forms, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" arbitrarily. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj : warning NU1902: Package 'log4net' 2.0.14 has a known moderate severity vulnerability, https://github.com/advisories/GHSA-4f7c-pmjv-c25w + OpenMetaverse.Utilities -> /home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.Utilities/bin/Debug/net8.0/OpenMetaverse.Utilities.dll + OpenMetaverse.Rendering.Simple -> /home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.Rendering.Simple/bin/Debug/net8.0/OpenMetaverse.Rendering.Simple.dll +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/LoginPanel.cs(196,17): warning SYSLIB0006: 'Thread.Abort()' is obsolete: 'Thread.Abort is not supported and throws PlatformNotSupportedException.' (https://aka.ms/dotnet-warnings/SYSLIB0006) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/LoginPanel.cs(246,25): warning SYSLIB0006: 'Thread.Abort()' is obsolete: 'Thread.Abort is not supported and throws PlatformNotSupportedException.' (https://aka.ms/dotnet-warnings/SYSLIB0006) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] + OpenMetaverse.GUI -> /home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/bin/Debug/net8.0-windows/OpenMetaverse.GUI.dll + OpenMetaverse.Tests -> /home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.Tests/bin/Debug/net8.0/OpenMetaverse.Tests.dll + OpenMetaverse.Rendering.Meshmerizer -> /home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.Rendering.Meshmerizer/bin/Debug/net8.0/OpenMetaverse.Rendering.Meshmerizer.dll + The package OpenMetaverse.Rendering.Meshmerizer.1.2.0-beta-gc1eec2331d is missing a readme. Go to https://aka.ms/nuget/authoring-best-practices/readme to learn why package readmes are important. + Successfully created package '/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.Rendering.Meshmerizer/bin/Debug/OpenMetaverse.Rendering.Meshmerizer.1.2.0-beta-gc1eec2331d.nupkg'. + +Build succeeded. + +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj : warning NU1902: Package 'log4net' 2.0.14 has a known moderate severity vulnerability, https://github.com/advisories/GHSA-4f7c-pmjv-c25w [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.sln] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj : warning NU1902: Package 'log4net' 2.0.14 has a known moderate severity vulnerability, https://github.com/advisories/GHSA-4f7c-pmjv-c25w +/usr/lib/dotnet/sdk/10.0.107/Microsoft.Common.CurrentVersion.targets(2437,5): warning MSB3245: Could not resolve this reference. Could not locate the assembly "System.Windows.Forms". Check to make sure the assembly exists on disk. If this reference is required by your code, you may get compilation errors. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/usr/lib/dotnet/sdk/10.0.107/Microsoft.Common.CurrentVersion.targets(2437,5): warning MSB3243: No way to resolve conflict between "System.Windows.Forms, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" and "System.Windows.Forms". Choosing "System.Windows.Forms, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" arbitrarily. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj : warning NU1902: Package 'log4net' 2.0.14 has a known moderate severity vulnerability, https://github.com/advisories/GHSA-4f7c-pmjv-c25w +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/LoginPanel.cs(196,17): warning SYSLIB0006: 'Thread.Abort()' is obsolete: 'Thread.Abort is not supported and throws PlatformNotSupportedException.' (https://aka.ms/dotnet-warnings/SYSLIB0006) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/LoginPanel.cs(246,25): warning SYSLIB0006: 'Thread.Abort()' is obsolete: 'Thread.Abort is not supported and throws PlatformNotSupportedException.' (https://aka.ms/dotnet-warnings/SYSLIB0006) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] + 7 Warning(s) + 0 Error(s) + +Time Elapsed 00:00:02.77 diff --git a/build_output.txt b/build_output.txt new file mode 100644 index 00000000..3f6b6781 --- /dev/null +++ b/build_output.txt @@ -0,0 +1,144 @@ + Determining projects to restore... +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj : warning NU1902: Package 'log4net' 2.0.14 has a known moderate severity vulnerability, https://github.com/advisories/GHSA-4f7c-pmjv-c25w [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.sln] + All projects are up-to-date for restore. +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj : warning NU1902: Package 'log4net' 2.0.14 has a known moderate severity vulnerability, https://github.com/advisories/GHSA-4f7c-pmjv-c25w + OpenMetaverse.Types -> /home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.Types/bin/Debug/net8.0/OpenMetaverse.Types.dll + OpenMetaverse.StructuredData -> /home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.StructuredData/bin/Debug/net8.0/OpenMetaverse.StructuredData.dll +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/Assets/AssetTypes/AssetMesh.cs(32,7): warning CS0105: The using directive for 'OpenMetaverse.StructuredData' appeared previously in this namespace [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/DllmapConfigHelper.cs(42,22): warning CS8981: The type name 'dllmap' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/DllmapConfigHelper.cs(55,22): warning CS8981: The type name 'configuration' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(174,26): warning CS8981: The type name 'asset' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(13040,26): warning CS8981: The type name 'sampler' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(13083,26): warning CS8981: The type name 'source' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(13699,26): warning CS8981: The type name 'accessor' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(13798,26): warning CS8981: The type name 'param' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(2538,26): warning CS8981: The type name 'extra' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(2628,26): warning CS8981: The type name 'technique' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(13979,26): warning CS8981: The type name 'camera' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(14485,26): warning CS8981: The type name 'controller' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(14576,26): warning CS8981: The type name 'morph' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(14728,26): warning CS8981: The type name 'skin' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(15052,26): warning CS8981: The type name 'effect' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(15193,26): warning CS8981: The type name 'image' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(31533,26): warning CS8981: The type name 'vertices' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(31608,26): warning CS8981: The type name 'lines' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(31714,26): warning CS8981: The type name 'linestrips' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(31821,26): warning CS8981: The type name 'polygons' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(31970,26): warning CS8981: The type name 'polylist' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(32091,26): warning CS8981: The type name 'triangles' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(33302,26): warning CS8981: The type name 'material' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(32197,26): warning CS8981: The type name 'trifans' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(38217,26): warning CS8981: The type name 'ellipsoid' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(32304,26): warning CS8981: The type name 'tristrips' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(32411,26): warning CS8981: The type name 'mesh' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(34212,26): warning CS8981: The type name 'node' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(34475,26): warning CS8981: The type name 'lookat' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(34524,26): warning CS8981: The type name 'matrix' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(34573,26): warning CS8981: The type name 'rotate' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(34622,26): warning CS8981: The type name 'skew' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(32491,26): warning CS8981: The type name 'spline' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(32793,26): warning CS8981: The type name 'light' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(31345,26): warning CS8981: The type name 'geometry' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(12904,26): warning CS8981: The type name 'animation' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(12997,26): warning CS8981: The type name 'channel' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(35851,26): warning CS8981: The type name 'box' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(35893,26): warning CS8981: The type name 'capsule' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(35950,26): warning CS8981: The type name 'cylinder' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(36007,26): warning CS8981: The type name 'plane' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(36049,26): warning CS8981: The type name 'sphere' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/Capabilities/CapsBase.cs(137,54): warning SYSLIB0014: 'WebRequest.Create(Uri)' is obsolete: 'WebRequest, HttpWebRequest, ServicePoint, and WebClient are obsolete. Use HttpClient instead.' (https://aka.ms/dotnet-warnings/SYSLIB0014) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/DownloadManager.cs(130,54): warning SYSLIB0014: 'WebRequest.Create(Uri)' is obsolete: 'WebRequest, HttpWebRequest, ServicePoint, and WebClient are obsolete. Use HttpClient instead.' (https://aka.ms/dotnet-warnings/SYSLIB0014) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/Imaging/BakeLayer.cs(212,22): warning CS0219: The variable 'processingSkin' is assigned but its value is never used [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/ColladalLoader.cs(157,86): warning CS0618: 'SKFilterQuality' is obsolete: 'Use SKSamplingOptions instead.' [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/ColladalLoader.cs(157,40): warning CS0618: 'SKBitmap.Resize(SKImageInfo, SKFilterQuality)' is obsolete: 'Use Resize(SKImageInfo info, SKSamplingOptions sampling) instead.' [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/AgentManagerMovement.cs(554,99): warning CS9193: Argument 1 should be a variable because it is passed to a 'ref readonly' parameter [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/EventDictionary.cs(215,27): warning CS0649: Field 'CapsEventDictionary.CapsCallbackWrapper.CapsEvent' is never assigned to, and will always have its default value null [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/ColladalLoader.cs(56,27): warning CS0649: Field 'ColladaLoader.Node.Name' is never assigned to, and will always have its default value null [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/EventDictionary.cs(213,44): warning CS0649: Field 'CapsEventDictionary.CapsCallbackWrapper.Callback' is never assigned to, and will always have its default value null [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/EventDictionary.cs(217,29): warning CS0649: Field 'CapsEventDictionary.CapsCallbackWrapper.Message' is never assigned to, and will always have its default value null [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/EventDictionary.cs(219,30): warning CS0649: Field 'CapsEventDictionary.CapsCallbackWrapper.Simulator' is never assigned to, and will always have its default value null [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] + OpenMetaverse -> /home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/bin/Debug/net8.0/OpenMetaverse.dll +/usr/lib/dotnet/sdk/10.0.107/Microsoft.Common.CurrentVersion.targets(2437,5): warning MSB3245: Could not resolve this reference. Could not locate the assembly "System.Windows.Forms". Check to make sure the assembly exists on disk. If this reference is required by your code, you may get compilation errors. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/usr/lib/dotnet/sdk/10.0.107/Microsoft.Common.CurrentVersion.targets(2437,5): warning MSB3243: No way to resolve conflict between "System.Windows.Forms, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" and "System.Windows.Forms". Choosing "System.Windows.Forms, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" arbitrarily. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj : warning NU1902: Package 'log4net' 2.0.14 has a known moderate severity vulnerability, https://github.com/advisories/GHSA-4f7c-pmjv-c25w + OpenMetaverse.Rendering.Simple -> /home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.Rendering.Simple/bin/Debug/net8.0/OpenMetaverse.Rendering.Simple.dll + OpenMetaverse.Utilities -> /home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.Utilities/bin/Debug/net8.0/OpenMetaverse.Utilities.dll + OpenMetaverse.Tests -> /home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.Tests/bin/Debug/net8.0/OpenMetaverse.Tests.dll +CSC : error CS5001: Program does not contain a static 'Main' method suitable for an entry point [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/LoginPanel.cs(196,17): warning SYSLIB0006: 'Thread.Abort()' is obsolete: 'Thread.Abort is not supported and throws PlatformNotSupportedException.' (https://aka.ms/dotnet-warnings/SYSLIB0006) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/LoginPanel.cs(246,25): warning SYSLIB0006: 'Thread.Abort()' is obsolete: 'Thread.Abort is not supported and throws PlatformNotSupportedException.' (https://aka.ms/dotnet-warnings/SYSLIB0006) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/MiniMap.cs(219,92): error CS1503: Argument 3: cannot convert from 'out System.Drawing.Image' to 'out SkiaSharp.SKBitmap' [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] + The package OpenMetaverse.1.2.0-beta-gc1eec2331d is missing a readme. Go to https://aka.ms/nuget/authoring-best-practices/readme to learn why package readmes are important. + Successfully created package '/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/bin/Debug/OpenMetaverse.1.2.0-beta-gc1eec2331d.nupkg'. + OpenMetaverse.Rendering.Meshmerizer -> /home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.Rendering.Meshmerizer/bin/Debug/net8.0/OpenMetaverse.Rendering.Meshmerizer.dll + The package OpenMetaverse.Rendering.Meshmerizer.1.2.0-beta-gc1eec2331d is missing a readme. Go to https://aka.ms/nuget/authoring-best-practices/readme to learn why package readmes are important. + Successfully created package '/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.Rendering.Meshmerizer/bin/Debug/OpenMetaverse.Rendering.Meshmerizer.1.2.0-beta-gc1eec2331d.nupkg'. + +Build FAILED. + +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj : warning NU1902: Package 'log4net' 2.0.14 has a known moderate severity vulnerability, https://github.com/advisories/GHSA-4f7c-pmjv-c25w [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.sln] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj : warning NU1902: Package 'log4net' 2.0.14 has a known moderate severity vulnerability, https://github.com/advisories/GHSA-4f7c-pmjv-c25w +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/Assets/AssetTypes/AssetMesh.cs(32,7): warning CS0105: The using directive for 'OpenMetaverse.StructuredData' appeared previously in this namespace [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/DllmapConfigHelper.cs(42,22): warning CS8981: The type name 'dllmap' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/DllmapConfigHelper.cs(55,22): warning CS8981: The type name 'configuration' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(174,26): warning CS8981: The type name 'asset' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(13040,26): warning CS8981: The type name 'sampler' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(13083,26): warning CS8981: The type name 'source' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(13699,26): warning CS8981: The type name 'accessor' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(13798,26): warning CS8981: The type name 'param' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(2538,26): warning CS8981: The type name 'extra' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(2628,26): warning CS8981: The type name 'technique' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(13979,26): warning CS8981: The type name 'camera' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(14485,26): warning CS8981: The type name 'controller' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(14576,26): warning CS8981: The type name 'morph' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(14728,26): warning CS8981: The type name 'skin' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(15052,26): warning CS8981: The type name 'effect' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(15193,26): warning CS8981: The type name 'image' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(31533,26): warning CS8981: The type name 'vertices' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(31608,26): warning CS8981: The type name 'lines' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(31714,26): warning CS8981: The type name 'linestrips' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(31821,26): warning CS8981: The type name 'polygons' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(31970,26): warning CS8981: The type name 'polylist' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(32091,26): warning CS8981: The type name 'triangles' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(33302,26): warning CS8981: The type name 'material' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(32197,26): warning CS8981: The type name 'trifans' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(38217,26): warning CS8981: The type name 'ellipsoid' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(32304,26): warning CS8981: The type name 'tristrips' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(32411,26): warning CS8981: The type name 'mesh' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(34212,26): warning CS8981: The type name 'node' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(34475,26): warning CS8981: The type name 'lookat' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(34524,26): warning CS8981: The type name 'matrix' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(34573,26): warning CS8981: The type name 'rotate' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(34622,26): warning CS8981: The type name 'skew' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(32491,26): warning CS8981: The type name 'spline' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(32793,26): warning CS8981: The type name 'light' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(31345,26): warning CS8981: The type name 'geometry' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(12904,26): warning CS8981: The type name 'animation' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(12997,26): warning CS8981: The type name 'channel' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(35851,26): warning CS8981: The type name 'box' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(35893,26): warning CS8981: The type name 'capsule' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(35950,26): warning CS8981: The type name 'cylinder' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(36007,26): warning CS8981: The type name 'plane' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(36049,26): warning CS8981: The type name 'sphere' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/Capabilities/CapsBase.cs(137,54): warning SYSLIB0014: 'WebRequest.Create(Uri)' is obsolete: 'WebRequest, HttpWebRequest, ServicePoint, and WebClient are obsolete. Use HttpClient instead.' (https://aka.ms/dotnet-warnings/SYSLIB0014) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/DownloadManager.cs(130,54): warning SYSLIB0014: 'WebRequest.Create(Uri)' is obsolete: 'WebRequest, HttpWebRequest, ServicePoint, and WebClient are obsolete. Use HttpClient instead.' (https://aka.ms/dotnet-warnings/SYSLIB0014) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/Imaging/BakeLayer.cs(212,22): warning CS0219: The variable 'processingSkin' is assigned but its value is never used [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/ColladalLoader.cs(157,86): warning CS0618: 'SKFilterQuality' is obsolete: 'Use SKSamplingOptions instead.' [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/ColladalLoader.cs(157,40): warning CS0618: 'SKBitmap.Resize(SKImageInfo, SKFilterQuality)' is obsolete: 'Use Resize(SKImageInfo info, SKSamplingOptions sampling) instead.' [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/AgentManagerMovement.cs(554,99): warning CS9193: Argument 1 should be a variable because it is passed to a 'ref readonly' parameter [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/EventDictionary.cs(215,27): warning CS0649: Field 'CapsEventDictionary.CapsCallbackWrapper.CapsEvent' is never assigned to, and will always have its default value null [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/ColladalLoader.cs(56,27): warning CS0649: Field 'ColladaLoader.Node.Name' is never assigned to, and will always have its default value null [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/EventDictionary.cs(213,44): warning CS0649: Field 'CapsEventDictionary.CapsCallbackWrapper.Callback' is never assigned to, and will always have its default value null [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/EventDictionary.cs(217,29): warning CS0649: Field 'CapsEventDictionary.CapsCallbackWrapper.Message' is never assigned to, and will always have its default value null [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/EventDictionary.cs(219,30): warning CS0649: Field 'CapsEventDictionary.CapsCallbackWrapper.Simulator' is never assigned to, and will always have its default value null [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/usr/lib/dotnet/sdk/10.0.107/Microsoft.Common.CurrentVersion.targets(2437,5): warning MSB3245: Could not resolve this reference. Could not locate the assembly "System.Windows.Forms". Check to make sure the assembly exists on disk. If this reference is required by your code, you may get compilation errors. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/usr/lib/dotnet/sdk/10.0.107/Microsoft.Common.CurrentVersion.targets(2437,5): warning MSB3243: No way to resolve conflict between "System.Windows.Forms, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" and "System.Windows.Forms". Choosing "System.Windows.Forms, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" arbitrarily. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj : warning NU1902: Package 'log4net' 2.0.14 has a known moderate severity vulnerability, https://github.com/advisories/GHSA-4f7c-pmjv-c25w +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/LoginPanel.cs(196,17): warning SYSLIB0006: 'Thread.Abort()' is obsolete: 'Thread.Abort is not supported and throws PlatformNotSupportedException.' (https://aka.ms/dotnet-warnings/SYSLIB0006) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/LoginPanel.cs(246,25): warning SYSLIB0006: 'Thread.Abort()' is obsolete: 'Thread.Abort is not supported and throws PlatformNotSupportedException.' (https://aka.ms/dotnet-warnings/SYSLIB0006) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +CSC : error CS5001: Program does not contain a static 'Main' method suitable for an entry point [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/MiniMap.cs(219,92): error CS1503: Argument 3: cannot convert from 'out System.Drawing.Image' to 'out SkiaSharp.SKBitmap' [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] + 60 Warning(s) + 2 Error(s) + +Time Elapsed 00:00:05.88 diff --git a/build_status.txt b/build_status.txt new file mode 100644 index 00000000..d4017df5 --- /dev/null +++ b/build_status.txt @@ -0,0 +1,242 @@ + Determining projects to restore... + Skipping project "/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.PrimMesher/OpenMetaverse.PrimMesher.csproj" because it was not found. + Skipping project "/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.PrimMesher/OpenMetaverse.PrimMesher.csproj" because it was not found. +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj : warning NU1902: Package 'log4net' 2.0.14 has a known moderate severity vulnerability, https://github.com/advisories/GHSA-4f7c-pmjv-c25w [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.sln] + All projects are up-to-date for restore. +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj : warning NU1902: Package 'log4net' 2.0.14 has a known moderate severity vulnerability, https://github.com/advisories/GHSA-4f7c-pmjv-c25w + OpenMetaverse.Types -> /home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.Types/bin/Debug/net8.0/OpenMetaverse.Types.dll + OpenMetaverse.StructuredData -> /home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.StructuredData/bin/Debug/net8.0/OpenMetaverse.StructuredData.dll +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/Assets/AssetTypes/AssetMesh.cs(32,7): warning CS0105: The using directive for 'OpenMetaverse.StructuredData' appeared previously in this namespace [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(174,26): warning CS8981: The type name 'asset' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/DllmapConfigHelper.cs(42,22): warning CS8981: The type name 'dllmap' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/DllmapConfigHelper.cs(55,22): warning CS8981: The type name 'configuration' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(13040,26): warning CS8981: The type name 'sampler' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(13083,26): warning CS8981: The type name 'source' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(13699,26): warning CS8981: The type name 'accessor' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(13798,26): warning CS8981: The type name 'param' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(13979,26): warning CS8981: The type name 'camera' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(14485,26): warning CS8981: The type name 'controller' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(14576,26): warning CS8981: The type name 'morph' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(14728,26): warning CS8981: The type name 'skin' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(38217,26): warning CS8981: The type name 'ellipsoid' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(15052,26): warning CS8981: The type name 'effect' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(15193,26): warning CS8981: The type name 'image' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(33302,26): warning CS8981: The type name 'material' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(2538,26): warning CS8981: The type name 'extra' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(2628,26): warning CS8981: The type name 'technique' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(34212,26): warning CS8981: The type name 'node' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(34475,26): warning CS8981: The type name 'lookat' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(34524,26): warning CS8981: The type name 'matrix' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(34573,26): warning CS8981: The type name 'rotate' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(34622,26): warning CS8981: The type name 'skew' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(35851,26): warning CS8981: The type name 'box' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(35893,26): warning CS8981: The type name 'capsule' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(35950,26): warning CS8981: The type name 'cylinder' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(36007,26): warning CS8981: The type name 'plane' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(36049,26): warning CS8981: The type name 'sphere' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(31533,26): warning CS8981: The type name 'vertices' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(31608,26): warning CS8981: The type name 'lines' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(31714,26): warning CS8981: The type name 'linestrips' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(31821,26): warning CS8981: The type name 'polygons' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(31970,26): warning CS8981: The type name 'polylist' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(32091,26): warning CS8981: The type name 'triangles' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(32197,26): warning CS8981: The type name 'trifans' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(31345,26): warning CS8981: The type name 'geometry' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(32304,26): warning CS8981: The type name 'tristrips' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(32411,26): warning CS8981: The type name 'mesh' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(32491,26): warning CS8981: The type name 'spline' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(32793,26): warning CS8981: The type name 'light' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(12904,26): warning CS8981: The type name 'animation' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(12997,26): warning CS8981: The type name 'channel' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/Capabilities/CapsBase.cs(137,54): warning SYSLIB0014: 'WebRequest.Create(Uri)' is obsolete: 'WebRequest, HttpWebRequest, ServicePoint, and WebClient are obsolete. Use HttpClient instead.' (https://aka.ms/dotnet-warnings/SYSLIB0014) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/DownloadManager.cs(130,54): warning SYSLIB0014: 'WebRequest.Create(Uri)' is obsolete: 'WebRequest, HttpWebRequest, ServicePoint, and WebClient are obsolete. Use HttpClient instead.' (https://aka.ms/dotnet-warnings/SYSLIB0014) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/Imaging/BakeLayer.cs(212,22): warning CS0219: The variable 'processingSkin' is assigned but its value is never used [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/ColladalLoader.cs(157,86): warning CS0618: 'SKFilterQuality' is obsolete: 'Use SKSamplingOptions instead.' [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/ColladalLoader.cs(157,40): warning CS0618: 'SKBitmap.Resize(SKImageInfo, SKFilterQuality)' is obsolete: 'Use Resize(SKImageInfo info, SKSamplingOptions sampling) instead.' [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/AgentManagerMovement.cs(554,99): warning CS9193: Argument 1 should be a variable because it is passed to a 'ref readonly' parameter [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/EventDictionary.cs(219,30): warning CS0649: Field 'CapsEventDictionary.CapsCallbackWrapper.Simulator' is never assigned to, and will always have its default value null [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/EventDictionary.cs(217,29): warning CS0649: Field 'CapsEventDictionary.CapsCallbackWrapper.Message' is never assigned to, and will always have its default value null [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/EventDictionary.cs(215,27): warning CS0649: Field 'CapsEventDictionary.CapsCallbackWrapper.CapsEvent' is never assigned to, and will always have its default value null [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/EventDictionary.cs(213,44): warning CS0649: Field 'CapsEventDictionary.CapsCallbackWrapper.Callback' is never assigned to, and will always have its default value null [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/ColladalLoader.cs(56,27): warning CS0649: Field 'ColladaLoader.Node.Name' is never assigned to, and will always have its default value null [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] + OpenMetaverse -> /home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/bin/Debug/net8.0/OpenMetaverse.dll +/usr/lib/dotnet/sdk/10.0.107/Microsoft.Common.CurrentVersion.targets(2437,5): warning MSB3245: Could not resolve this reference. Could not locate the assembly "System.Windows.Forms". Check to make sure the assembly exists on disk. If this reference is required by your code, you may get compilation errors. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj : warning NU1902: Package 'log4net' 2.0.14 has a known moderate severity vulnerability, https://github.com/advisories/GHSA-4f7c-pmjv-c25w +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/AvatarList.cs(30,22): error CS0234: The type or namespace name 'Forms' does not exist in the namespace 'System.Windows' (are you missing an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/FriendList.cs(29,22): error CS0234: The type or namespace name 'Forms' does not exist in the namespace 'System.Windows' (are you missing an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/GroupList.cs(29,22): error CS0234: The type or namespace name 'Forms' does not exist in the namespace 'System.Windows' (are you missing an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/InventoryTree.cs(30,22): error CS0234: The type or namespace name 'Forms' does not exist in the namespace 'System.Windows' (are you missing an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/ListColumnSorter.cs(28,22): error CS0234: The type or namespace name 'Forms' does not exist in the namespace 'System.Windows' (are you missing an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/LocalChat.cs(30,22): error CS0234: The type or namespace name 'Forms' does not exist in the namespace 'System.Windows' (are you missing an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/LoginPanel.cs(31,22): error CS0234: The type or namespace name 'Forms' does not exist in the namespace 'System.Windows' (are you missing an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/MessageBar.cs(4,22): error CS0234: The type or namespace name 'Forms' does not exist in the namespace 'System.Windows' (are you missing an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/MiniMap.cs(31,22): error CS0234: The type or namespace name 'Forms' does not exist in the namespace 'System.Windows' (are you missing an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/StatusOutput.cs(30,22): error CS0234: The type or namespace name 'Forms' does not exist in the namespace 'System.Windows' (are you missing an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/AvatarList.cs(38,31): error CS0246: The type or namespace name 'ListView' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/FriendList.cs(37,31): error CS0246: The type or namespace name 'ListView' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/GroupList.cs(37,30): error CS0246: The type or namespace name 'ListView' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/AvatarList.cs(491,16): error CS0246: The type or namespace name 'ListViewItem' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/InventoryTree.cs(38,34): error CS0246: The type or namespace name 'TreeView' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/FriendList.cs(154,60): error CS0246: The type or namespace name 'ColumnClickEventArgs' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/GroupList.cs(104,59): error CS0246: The type or namespace name 'ColumnClickEventArgs' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/InventoryTree.cs(41,17): error CS0246: The type or namespace name 'ContextMenuStrip' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/AvatarList.cs(391,52): error CS0246: The type or namespace name 'ColumnClickEventArgs' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/InventoryTree.cs(47,16): error CS0246: The type or namespace name 'ContextMenuStrip' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/LocalChat.cs(37,30): error CS0246: The type or namespace name 'Panel' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/InventoryTree.cs(98,34): error CS0246: The type or namespace name 'TreeNode' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/LoginPanel.cs(35,31): error CS0246: The type or namespace name 'Panel' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/LocalChat.cs(45,17): error CS0246: The type or namespace name 'RichTextBox' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/InventoryTree.cs(108,32): error CS0246: The type or namespace name 'TreeNode' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/MessageBar.cs(11,31): error CS0246: The type or namespace name 'ToolStrip' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/LocalChat.cs(46,17): error CS0246: The type or namespace name 'TextBox' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/InventoryTree.cs(208,58): error CS0246: The type or namespace name 'TreeNodeMouseClickEventArgs' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/LoginPanel.cs(41,17): error CS0246: The type or namespace name 'Button' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/InventoryTree.cs(217,64): error CS0246: The type or namespace name 'TreeViewCancelEventArgs' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/LoginPanel.cs(42,17): error CS0246: The type or namespace name 'Label' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/LocalChat.cs(173,46): error CS0246: The type or namespace name 'KeyEventArgs' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/LoginPanel.cs(43,17): error CS0246: The type or namespace name 'Label' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/MessageBar.cs(244,52): error CS0246: The type or namespace name 'ToolStripItemClickedEventArgs' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/MiniMap.cs(38,28): error CS0246: The type or namespace name 'PictureBox' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/LoginPanel.cs(44,17): error CS0246: The type or namespace name 'Label' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/StatusOutput.cs(37,33): error CS0246: The type or namespace name 'RichTextBox' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/LoginPanel.cs(45,17): error CS0246: The type or namespace name 'ComboBox' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/MessageBar.cs(19,34): error CS0246: The type or namespace name 'ToolStripButton' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/LoginPanel.cs(46,17): error CS0246: The type or namespace name 'ComboBox' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/LoginPanel.cs(47,17): error CS0246: The type or namespace name 'TextBox' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/MessageBar.cs(49,52): error CS0246: The type or namespace name 'FormClosingEventArgs' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/MiniMap.cs(47,9): error CS0246: The type or namespace name 'ToolTip' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/MessageBar.cs(65,31): error CS0246: The type or namespace name 'Form' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/MessageBar.cs(67,21): error CS0246: The type or namespace name 'RichTextBox' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/MiniMap.cs(196,47): error CS0246: The type or namespace name 'MouseEventArgs' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/MessageBar.cs(68,21): error CS0246: The type or namespace name 'TextBox' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/MessageBar.cs(138,50): error CS0246: The type or namespace name 'KeyEventArgs' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] + OpenMetaverse.Rendering.Simple -> /home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.Rendering.Simple/bin/Debug/net8.0/OpenMetaverse.Rendering.Simple.dll + The package OpenMetaverse.1.2.0-beta-gc1eec2331d is missing a readme. Go to https://aka.ms/nuget/authoring-best-practices/readme to learn why package readmes are important. + Successfully created package '/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/bin/Debug/OpenMetaverse.1.2.0-beta-gc1eec2331d.nupkg'. +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.Tests/MessageTests.cs(1252,13): error SYSLIB0011: 'BinaryFormatter' is obsolete: 'BinaryFormatter serialization is obsolete and should not be used. See https://aka.ms/binaryformatter for more information.' (https://aka.ms/dotnet-warnings/SYSLIB0011) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.Tests/OpenMetaverse.Tests.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.Tests/MessageTests.cs(1252,45): error SYSLIB0011: 'BinaryFormatter' is obsolete: 'BinaryFormatter serialization is obsolete and should not be used. See https://aka.ms/binaryformatter for more information.' (https://aka.ms/dotnet-warnings/SYSLIB0011) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.Tests/OpenMetaverse.Tests.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.Tests/MessageTests.cs(1498,13): error SYSLIB0011: 'BinaryFormatter' is obsolete: 'BinaryFormatter serialization is obsolete and should not be used. See https://aka.ms/binaryformatter for more information.' (https://aka.ms/dotnet-warnings/SYSLIB0011) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.Tests/OpenMetaverse.Tests.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.Tests/MessageTests.cs(1498,45): error SYSLIB0011: 'BinaryFormatter' is obsolete: 'BinaryFormatter serialization is obsolete and should not be used. See https://aka.ms/binaryformatter for more information.' (https://aka.ms/dotnet-warnings/SYSLIB0011) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.Tests/OpenMetaverse.Tests.csproj] + OpenMetaverse.Utilities -> /home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.Utilities/bin/Debug/net8.0/OpenMetaverse.Utilities.dll + The package OpenMetaverse.Rendering.Simple.1.2.0-beta-gc1eec2331d is missing a readme. Go to https://aka.ms/nuget/authoring-best-practices/readme to learn why package readmes are important. + Successfully created package '/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.Rendering.Simple/bin/Debug/OpenMetaverse.Rendering.Simple.1.2.0-beta-gc1eec2331d.nupkg'. +/usr/lib/dotnet/sdk/10.0.107/Microsoft.Common.CurrentVersion.targets(2189,5): warning MSB9008: The referenced project ../OpenMetaverse.PrimMesher/OpenMetaverse.PrimMesher.csproj does not exist. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.Rendering.Meshmerizer/OpenMetaverse.Rendering.Meshmerizer.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.Rendering.Meshmerizer/MeshmerizerR.cs(432,17): error CS0246: The type or namespace name 'PrimMesher' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.Rendering.Meshmerizer/OpenMetaverse.Rendering.Meshmerizer.csproj] + +Build FAILED. + +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj : warning NU1902: Package 'log4net' 2.0.14 has a known moderate severity vulnerability, https://github.com/advisories/GHSA-4f7c-pmjv-c25w [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.sln] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj : warning NU1902: Package 'log4net' 2.0.14 has a known moderate severity vulnerability, https://github.com/advisories/GHSA-4f7c-pmjv-c25w +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/Assets/AssetTypes/AssetMesh.cs(32,7): warning CS0105: The using directive for 'OpenMetaverse.StructuredData' appeared previously in this namespace [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(174,26): warning CS8981: The type name 'asset' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/DllmapConfigHelper.cs(42,22): warning CS8981: The type name 'dllmap' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/DllmapConfigHelper.cs(55,22): warning CS8981: The type name 'configuration' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(13040,26): warning CS8981: The type name 'sampler' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(13083,26): warning CS8981: The type name 'source' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(13699,26): warning CS8981: The type name 'accessor' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(13798,26): warning CS8981: The type name 'param' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(13979,26): warning CS8981: The type name 'camera' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(14485,26): warning CS8981: The type name 'controller' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(14576,26): warning CS8981: The type name 'morph' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(14728,26): warning CS8981: The type name 'skin' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(38217,26): warning CS8981: The type name 'ellipsoid' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(15052,26): warning CS8981: The type name 'effect' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(15193,26): warning CS8981: The type name 'image' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(33302,26): warning CS8981: The type name 'material' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(2538,26): warning CS8981: The type name 'extra' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(2628,26): warning CS8981: The type name 'technique' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(34212,26): warning CS8981: The type name 'node' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(34475,26): warning CS8981: The type name 'lookat' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(34524,26): warning CS8981: The type name 'matrix' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(34573,26): warning CS8981: The type name 'rotate' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(34622,26): warning CS8981: The type name 'skew' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(35851,26): warning CS8981: The type name 'box' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(35893,26): warning CS8981: The type name 'capsule' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(35950,26): warning CS8981: The type name 'cylinder' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(36007,26): warning CS8981: The type name 'plane' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(36049,26): warning CS8981: The type name 'sphere' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(31533,26): warning CS8981: The type name 'vertices' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(31608,26): warning CS8981: The type name 'lines' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(31714,26): warning CS8981: The type name 'linestrips' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(31821,26): warning CS8981: The type name 'polygons' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(31970,26): warning CS8981: The type name 'polylist' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(32091,26): warning CS8981: The type name 'triangles' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(32197,26): warning CS8981: The type name 'trifans' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(31345,26): warning CS8981: The type name 'geometry' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(32304,26): warning CS8981: The type name 'tristrips' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(32411,26): warning CS8981: The type name 'mesh' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(32491,26): warning CS8981: The type name 'spline' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(32793,26): warning CS8981: The type name 'light' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(12904,26): warning CS8981: The type name 'animation' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(12997,26): warning CS8981: The type name 'channel' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/Capabilities/CapsBase.cs(137,54): warning SYSLIB0014: 'WebRequest.Create(Uri)' is obsolete: 'WebRequest, HttpWebRequest, ServicePoint, and WebClient are obsolete. Use HttpClient instead.' (https://aka.ms/dotnet-warnings/SYSLIB0014) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/DownloadManager.cs(130,54): warning SYSLIB0014: 'WebRequest.Create(Uri)' is obsolete: 'WebRequest, HttpWebRequest, ServicePoint, and WebClient are obsolete. Use HttpClient instead.' (https://aka.ms/dotnet-warnings/SYSLIB0014) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/Imaging/BakeLayer.cs(212,22): warning CS0219: The variable 'processingSkin' is assigned but its value is never used [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/ColladalLoader.cs(157,86): warning CS0618: 'SKFilterQuality' is obsolete: 'Use SKSamplingOptions instead.' [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/ColladalLoader.cs(157,40): warning CS0618: 'SKBitmap.Resize(SKImageInfo, SKFilterQuality)' is obsolete: 'Use Resize(SKImageInfo info, SKSamplingOptions sampling) instead.' [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/AgentManagerMovement.cs(554,99): warning CS9193: Argument 1 should be a variable because it is passed to a 'ref readonly' parameter [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/EventDictionary.cs(219,30): warning CS0649: Field 'CapsEventDictionary.CapsCallbackWrapper.Simulator' is never assigned to, and will always have its default value null [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/EventDictionary.cs(217,29): warning CS0649: Field 'CapsEventDictionary.CapsCallbackWrapper.Message' is never assigned to, and will always have its default value null [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/EventDictionary.cs(215,27): warning CS0649: Field 'CapsEventDictionary.CapsCallbackWrapper.CapsEvent' is never assigned to, and will always have its default value null [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/EventDictionary.cs(213,44): warning CS0649: Field 'CapsEventDictionary.CapsCallbackWrapper.Callback' is never assigned to, and will always have its default value null [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/ColladalLoader.cs(56,27): warning CS0649: Field 'ColladaLoader.Node.Name' is never assigned to, and will always have its default value null [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] +/usr/lib/dotnet/sdk/10.0.107/Microsoft.Common.CurrentVersion.targets(2437,5): warning MSB3245: Could not resolve this reference. Could not locate the assembly "System.Windows.Forms". Check to make sure the assembly exists on disk. If this reference is required by your code, you may get compilation errors. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj : warning NU1902: Package 'log4net' 2.0.14 has a known moderate severity vulnerability, https://github.com/advisories/GHSA-4f7c-pmjv-c25w +/usr/lib/dotnet/sdk/10.0.107/Microsoft.Common.CurrentVersion.targets(2189,5): warning MSB9008: The referenced project ../OpenMetaverse.PrimMesher/OpenMetaverse.PrimMesher.csproj does not exist. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.Rendering.Meshmerizer/OpenMetaverse.Rendering.Meshmerizer.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/AvatarList.cs(30,22): error CS0234: The type or namespace name 'Forms' does not exist in the namespace 'System.Windows' (are you missing an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/FriendList.cs(29,22): error CS0234: The type or namespace name 'Forms' does not exist in the namespace 'System.Windows' (are you missing an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/GroupList.cs(29,22): error CS0234: The type or namespace name 'Forms' does not exist in the namespace 'System.Windows' (are you missing an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/InventoryTree.cs(30,22): error CS0234: The type or namespace name 'Forms' does not exist in the namespace 'System.Windows' (are you missing an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/ListColumnSorter.cs(28,22): error CS0234: The type or namespace name 'Forms' does not exist in the namespace 'System.Windows' (are you missing an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/LocalChat.cs(30,22): error CS0234: The type or namespace name 'Forms' does not exist in the namespace 'System.Windows' (are you missing an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/LoginPanel.cs(31,22): error CS0234: The type or namespace name 'Forms' does not exist in the namespace 'System.Windows' (are you missing an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/MessageBar.cs(4,22): error CS0234: The type or namespace name 'Forms' does not exist in the namespace 'System.Windows' (are you missing an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/MiniMap.cs(31,22): error CS0234: The type or namespace name 'Forms' does not exist in the namespace 'System.Windows' (are you missing an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/StatusOutput.cs(30,22): error CS0234: The type or namespace name 'Forms' does not exist in the namespace 'System.Windows' (are you missing an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/AvatarList.cs(38,31): error CS0246: The type or namespace name 'ListView' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/FriendList.cs(37,31): error CS0246: The type or namespace name 'ListView' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/GroupList.cs(37,30): error CS0246: The type or namespace name 'ListView' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/AvatarList.cs(491,16): error CS0246: The type or namespace name 'ListViewItem' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/InventoryTree.cs(38,34): error CS0246: The type or namespace name 'TreeView' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/FriendList.cs(154,60): error CS0246: The type or namespace name 'ColumnClickEventArgs' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/GroupList.cs(104,59): error CS0246: The type or namespace name 'ColumnClickEventArgs' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/InventoryTree.cs(41,17): error CS0246: The type or namespace name 'ContextMenuStrip' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/AvatarList.cs(391,52): error CS0246: The type or namespace name 'ColumnClickEventArgs' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/InventoryTree.cs(47,16): error CS0246: The type or namespace name 'ContextMenuStrip' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/LocalChat.cs(37,30): error CS0246: The type or namespace name 'Panel' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/InventoryTree.cs(98,34): error CS0246: The type or namespace name 'TreeNode' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/LoginPanel.cs(35,31): error CS0246: The type or namespace name 'Panel' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/LocalChat.cs(45,17): error CS0246: The type or namespace name 'RichTextBox' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/InventoryTree.cs(108,32): error CS0246: The type or namespace name 'TreeNode' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/MessageBar.cs(11,31): error CS0246: The type or namespace name 'ToolStrip' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/LocalChat.cs(46,17): error CS0246: The type or namespace name 'TextBox' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/InventoryTree.cs(208,58): error CS0246: The type or namespace name 'TreeNodeMouseClickEventArgs' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/LoginPanel.cs(41,17): error CS0246: The type or namespace name 'Button' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/InventoryTree.cs(217,64): error CS0246: The type or namespace name 'TreeViewCancelEventArgs' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/LoginPanel.cs(42,17): error CS0246: The type or namespace name 'Label' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/LocalChat.cs(173,46): error CS0246: The type or namespace name 'KeyEventArgs' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/LoginPanel.cs(43,17): error CS0246: The type or namespace name 'Label' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/MessageBar.cs(244,52): error CS0246: The type or namespace name 'ToolStripItemClickedEventArgs' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/MiniMap.cs(38,28): error CS0246: The type or namespace name 'PictureBox' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/LoginPanel.cs(44,17): error CS0246: The type or namespace name 'Label' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/StatusOutput.cs(37,33): error CS0246: The type or namespace name 'RichTextBox' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/LoginPanel.cs(45,17): error CS0246: The type or namespace name 'ComboBox' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/MessageBar.cs(19,34): error CS0246: The type or namespace name 'ToolStripButton' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/LoginPanel.cs(46,17): error CS0246: The type or namespace name 'ComboBox' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/LoginPanel.cs(47,17): error CS0246: The type or namespace name 'TextBox' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/MessageBar.cs(49,52): error CS0246: The type or namespace name 'FormClosingEventArgs' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/MiniMap.cs(47,9): error CS0246: The type or namespace name 'ToolTip' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/MessageBar.cs(65,31): error CS0246: The type or namespace name 'Form' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/MessageBar.cs(67,21): error CS0246: The type or namespace name 'RichTextBox' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/MiniMap.cs(196,47): error CS0246: The type or namespace name 'MouseEventArgs' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/MessageBar.cs(68,21): error CS0246: The type or namespace name 'TextBox' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/MessageBar.cs(138,50): error CS0246: The type or namespace name 'KeyEventArgs' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.Tests/MessageTests.cs(1252,13): error SYSLIB0011: 'BinaryFormatter' is obsolete: 'BinaryFormatter serialization is obsolete and should not be used. See https://aka.ms/binaryformatter for more information.' (https://aka.ms/dotnet-warnings/SYSLIB0011) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.Tests/OpenMetaverse.Tests.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.Tests/MessageTests.cs(1252,45): error SYSLIB0011: 'BinaryFormatter' is obsolete: 'BinaryFormatter serialization is obsolete and should not be used. See https://aka.ms/binaryformatter for more information.' (https://aka.ms/dotnet-warnings/SYSLIB0011) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.Tests/OpenMetaverse.Tests.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.Tests/MessageTests.cs(1498,13): error SYSLIB0011: 'BinaryFormatter' is obsolete: 'BinaryFormatter serialization is obsolete and should not be used. See https://aka.ms/binaryformatter for more information.' (https://aka.ms/dotnet-warnings/SYSLIB0011) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.Tests/OpenMetaverse.Tests.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.Tests/MessageTests.cs(1498,45): error SYSLIB0011: 'BinaryFormatter' is obsolete: 'BinaryFormatter serialization is obsolete and should not be used. See https://aka.ms/binaryformatter for more information.' (https://aka.ms/dotnet-warnings/SYSLIB0011) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.Tests/OpenMetaverse.Tests.csproj] +/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.Rendering.Meshmerizer/MeshmerizerR.cs(432,17): error CS0246: The type or namespace name 'PrimMesher' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.Rendering.Meshmerizer/OpenMetaverse.Rendering.Meshmerizer.csproj] + 58 Warning(s) + 53 Error(s) + +Time Elapsed 00:00:05.88 From f9e035a08563edb91bce39f84d8e051f0c1bc74f Mon Sep 17 00:00:00 2001 From: Mike Dickson Date: Fri, 15 May 2026 11:51:22 -0400 Subject: [PATCH 145/149] Clean up a specific use of BinaryFormatter that blocks compilation on dotnet 8+. This was in Inventory.cs and is used in client apps to serialize/deserialize and cache inventory contents to disk. Minimal impact on our use with OpenSim NGC. --- .gitignore | 7 +- Directory.Build.props | 6 +- OpenMetaverse.GUI/OpenMetaverse.GUI.csproj | 2 +- .../OpenMetaverse.Tests.csproj | 4 +- OpenMetaverse/Inventory.cs | 69 +++-- OpenMetaverse/OpenMetaverse.csproj | 6 +- build_log.txt | 33 --- build_output.txt | 144 ----------- build_status.txt | 242 ------------------ 9 files changed, 64 insertions(+), 449 deletions(-) delete mode 100644 build_log.txt delete mode 100644 build_output.txt delete mode 100644 build_status.txt diff --git a/.gitignore b/.gitignore index 8bb6ce42..52a02ba9 100644 --- a/.gitignore +++ b/.gitignore @@ -3,11 +3,12 @@ compile.bat *.userprefs *.suo *.cache +*.csproj.lscache .vs/ [Oo]bj/ [Bb]in/ [Bb]uild/ PublishProfiles/ - - -.idea/.idea.OpenMetaverse/.idea/ +build_log.txt +build_output.txt +build_status.txt \ No newline at end of file diff --git a/Directory.Build.props b/Directory.Build.props index caa65a3e..abfc78ce 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -14,10 +14,6 @@ - 1.1.8 - 1.1.7 - 1.1.7 - 1.1.7 BSD-3-Clause https://github.com/OpenSim-NGC/libopenmetaverse false @@ -26,4 +22,4 @@ git master - \ No newline at end of file + diff --git a/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj b/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj index 7eabdb93..13728e9e 100644 --- a/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj +++ b/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj @@ -8,7 +8,7 @@ true - + diff --git a/OpenMetaverse.Tests/OpenMetaverse.Tests.csproj b/OpenMetaverse.Tests/OpenMetaverse.Tests.csproj index 835f69df..7eb39807 100644 --- a/OpenMetaverse.Tests/OpenMetaverse.Tests.csproj +++ b/OpenMetaverse.Tests/OpenMetaverse.Tests.csproj @@ -3,8 +3,8 @@ Local - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/OpenMetaverse/Inventory.cs b/OpenMetaverse/Inventory.cs index ce574a8c..a7c18c82 100644 --- a/OpenMetaverse/Inventory.cs +++ b/OpenMetaverse/Inventory.cs @@ -27,6 +27,8 @@ using System; using System.Collections.Generic; using System.IO; +using MessagePack; +using OpenMetaverse.StructuredData; namespace OpenMetaverse { @@ -49,6 +51,41 @@ public InventoryException(string message) /// public class Inventory { + [MessagePackObject] + private sealed class InventoryCacheEntry + { + [Key(0)] + public UUID ParentID { get; set; } + + [Key(1)] + public bool IsFolder { get; set; } + + [Key(2)] + public string Data { get; set; } + } + + private static InventoryCacheEntry SerializeInventoryNode(InventoryNode node) + { + InventoryBase data = node.Data; + return new InventoryCacheEntry + { + ParentID = data.ParentUUID, + IsFolder = data is InventoryFolder, + Data = OSDParser.SerializeLLSDXmlString(data.GetOSD()) + }; + } + + private static InventoryNode DeserializeInventoryNode(InventoryCacheEntry cacheNode) + { + OSD osd = OSDParser.DeserializeLLSDXml(cacheNode.Data); + InventoryBase data = cacheNode.IsFolder + ? (InventoryBase)InventoryFolder.FromOSD(osd) + : (InventoryBase)InventoryItem.FromOSD(osd); + + data.ParentUUID = cacheNode.ParentID; + return new InventoryNode(data); + } + /// The event subscribers, null of no subscribers private EventHandler m_InventoryObjectUpdated; @@ -359,13 +396,14 @@ public void SaveToDisk(string filename) lock (Items) { Logger.Log("Caching " + Items.Count.ToString() + " inventory items to " + filename, Helpers.LogLevel.Info); + List cacheNodes = new List(Items.Count); + foreach (KeyValuePair kvp in Items) { - /* Removed as binary formatter is obsolete - bformatter.Serialize(stream, kvp.Value); - */ - ZeroFormatter.ZeroFormatterSerializer.Serialize(stream, kvp.Value); //added from LibreMetaverse + cacheNodes.Add(SerializeInventoryNode(kvp.Value)); } + + MessagePackSerializer.Serialize(stream, cacheNodes); } } } @@ -392,17 +430,15 @@ public int RestoreFromDisk(string filename) using (Stream stream = File.Open(filename, FileMode.Open)) { - //BinaryFormatter bformatter = new BinaryFormatter(); //removed as part of binary formatter replacements - - while (stream.Position < stream.Length) + List cacheNodes = MessagePackSerializer.Deserialize>(stream); + if (cacheNodes != null) { - /* Removed as binaryformatter is obsolte - OpenMetaverse.InventoryNode node = (InventoryNode)bformatter.Deserialize(stream); - */ - - var node = ZeroFormatter.ZeroFormatterSerializer.Deserialize(stream); //added from LibreOpenMetaverse - nodes.Add(node); - item_count++; + foreach (InventoryCacheEntry cacheNode in cacheNodes) + { + OpenMetaverse.InventoryNode node = DeserializeInventoryNode(cacheNode); + nodes.Add(node); + item_count++; + } } } } @@ -428,7 +464,8 @@ public int RestoreFromDisk(string filename) foreach (InventoryNode node in nodes) { InventoryNode pnode; - if (node.ParentID.IsZero()) + UUID parentID = (node.Data != null) ? node.Data.ParentUUID : UUID.Zero; + if (parentID.IsZero()) { //We don't need the root nodes "My Inventory" etc as they will already exist for the correct // user of this cache. @@ -457,7 +494,7 @@ public int RestoreFromDisk(string filename) del_nodes.Add(node); } } - else if (Items.TryGetValue(node.ParentID, out pnode)) + else if (Items.TryGetValue(parentID, out pnode)) { if (node.Data != null) { diff --git a/OpenMetaverse/OpenMetaverse.csproj b/OpenMetaverse/OpenMetaverse.csproj index 5aa648b8..bcad839b 100644 --- a/OpenMetaverse/OpenMetaverse.csproj +++ b/OpenMetaverse/OpenMetaverse.csproj @@ -7,11 +7,11 @@ true - + + - - + diff --git a/build_log.txt b/build_log.txt deleted file mode 100644 index cbce967b..00000000 --- a/build_log.txt +++ /dev/null @@ -1,33 +0,0 @@ - Determining projects to restore... -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj : warning NU1902: Package 'log4net' 2.0.14 has a known moderate severity vulnerability, https://github.com/advisories/GHSA-4f7c-pmjv-c25w [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.sln] - All projects are up-to-date for restore. -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj : warning NU1902: Package 'log4net' 2.0.14 has a known moderate severity vulnerability, https://github.com/advisories/GHSA-4f7c-pmjv-c25w - OpenMetaverse.Types -> /home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.Types/bin/Debug/net8.0/OpenMetaverse.Types.dll - OpenMetaverse.StructuredData -> /home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.StructuredData/bin/Debug/net8.0/OpenMetaverse.StructuredData.dll - OpenMetaverse -> /home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/bin/Debug/net8.0/OpenMetaverse.dll -/usr/lib/dotnet/sdk/10.0.107/Microsoft.Common.CurrentVersion.targets(2437,5): warning MSB3245: Could not resolve this reference. Could not locate the assembly "System.Windows.Forms". Check to make sure the assembly exists on disk. If this reference is required by your code, you may get compilation errors. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/usr/lib/dotnet/sdk/10.0.107/Microsoft.Common.CurrentVersion.targets(2437,5): warning MSB3243: No way to resolve conflict between "System.Windows.Forms, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" and "System.Windows.Forms". Choosing "System.Windows.Forms, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" arbitrarily. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj : warning NU1902: Package 'log4net' 2.0.14 has a known moderate severity vulnerability, https://github.com/advisories/GHSA-4f7c-pmjv-c25w - OpenMetaverse.Utilities -> /home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.Utilities/bin/Debug/net8.0/OpenMetaverse.Utilities.dll - OpenMetaverse.Rendering.Simple -> /home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.Rendering.Simple/bin/Debug/net8.0/OpenMetaverse.Rendering.Simple.dll -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/LoginPanel.cs(196,17): warning SYSLIB0006: 'Thread.Abort()' is obsolete: 'Thread.Abort is not supported and throws PlatformNotSupportedException.' (https://aka.ms/dotnet-warnings/SYSLIB0006) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/LoginPanel.cs(246,25): warning SYSLIB0006: 'Thread.Abort()' is obsolete: 'Thread.Abort is not supported and throws PlatformNotSupportedException.' (https://aka.ms/dotnet-warnings/SYSLIB0006) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] - OpenMetaverse.GUI -> /home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/bin/Debug/net8.0-windows/OpenMetaverse.GUI.dll - OpenMetaverse.Tests -> /home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.Tests/bin/Debug/net8.0/OpenMetaverse.Tests.dll - OpenMetaverse.Rendering.Meshmerizer -> /home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.Rendering.Meshmerizer/bin/Debug/net8.0/OpenMetaverse.Rendering.Meshmerizer.dll - The package OpenMetaverse.Rendering.Meshmerizer.1.2.0-beta-gc1eec2331d is missing a readme. Go to https://aka.ms/nuget/authoring-best-practices/readme to learn why package readmes are important. - Successfully created package '/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.Rendering.Meshmerizer/bin/Debug/OpenMetaverse.Rendering.Meshmerizer.1.2.0-beta-gc1eec2331d.nupkg'. - -Build succeeded. - -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj : warning NU1902: Package 'log4net' 2.0.14 has a known moderate severity vulnerability, https://github.com/advisories/GHSA-4f7c-pmjv-c25w [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.sln] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj : warning NU1902: Package 'log4net' 2.0.14 has a known moderate severity vulnerability, https://github.com/advisories/GHSA-4f7c-pmjv-c25w -/usr/lib/dotnet/sdk/10.0.107/Microsoft.Common.CurrentVersion.targets(2437,5): warning MSB3245: Could not resolve this reference. Could not locate the assembly "System.Windows.Forms". Check to make sure the assembly exists on disk. If this reference is required by your code, you may get compilation errors. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/usr/lib/dotnet/sdk/10.0.107/Microsoft.Common.CurrentVersion.targets(2437,5): warning MSB3243: No way to resolve conflict between "System.Windows.Forms, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" and "System.Windows.Forms". Choosing "System.Windows.Forms, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" arbitrarily. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj : warning NU1902: Package 'log4net' 2.0.14 has a known moderate severity vulnerability, https://github.com/advisories/GHSA-4f7c-pmjv-c25w -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/LoginPanel.cs(196,17): warning SYSLIB0006: 'Thread.Abort()' is obsolete: 'Thread.Abort is not supported and throws PlatformNotSupportedException.' (https://aka.ms/dotnet-warnings/SYSLIB0006) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/LoginPanel.cs(246,25): warning SYSLIB0006: 'Thread.Abort()' is obsolete: 'Thread.Abort is not supported and throws PlatformNotSupportedException.' (https://aka.ms/dotnet-warnings/SYSLIB0006) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] - 7 Warning(s) - 0 Error(s) - -Time Elapsed 00:00:02.77 diff --git a/build_output.txt b/build_output.txt deleted file mode 100644 index 3f6b6781..00000000 --- a/build_output.txt +++ /dev/null @@ -1,144 +0,0 @@ - Determining projects to restore... -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj : warning NU1902: Package 'log4net' 2.0.14 has a known moderate severity vulnerability, https://github.com/advisories/GHSA-4f7c-pmjv-c25w [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.sln] - All projects are up-to-date for restore. -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj : warning NU1902: Package 'log4net' 2.0.14 has a known moderate severity vulnerability, https://github.com/advisories/GHSA-4f7c-pmjv-c25w - OpenMetaverse.Types -> /home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.Types/bin/Debug/net8.0/OpenMetaverse.Types.dll - OpenMetaverse.StructuredData -> /home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.StructuredData/bin/Debug/net8.0/OpenMetaverse.StructuredData.dll -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/Assets/AssetTypes/AssetMesh.cs(32,7): warning CS0105: The using directive for 'OpenMetaverse.StructuredData' appeared previously in this namespace [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/DllmapConfigHelper.cs(42,22): warning CS8981: The type name 'dllmap' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/DllmapConfigHelper.cs(55,22): warning CS8981: The type name 'configuration' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(174,26): warning CS8981: The type name 'asset' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(13040,26): warning CS8981: The type name 'sampler' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(13083,26): warning CS8981: The type name 'source' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(13699,26): warning CS8981: The type name 'accessor' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(13798,26): warning CS8981: The type name 'param' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(2538,26): warning CS8981: The type name 'extra' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(2628,26): warning CS8981: The type name 'technique' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(13979,26): warning CS8981: The type name 'camera' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(14485,26): warning CS8981: The type name 'controller' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(14576,26): warning CS8981: The type name 'morph' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(14728,26): warning CS8981: The type name 'skin' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(15052,26): warning CS8981: The type name 'effect' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(15193,26): warning CS8981: The type name 'image' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(31533,26): warning CS8981: The type name 'vertices' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(31608,26): warning CS8981: The type name 'lines' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(31714,26): warning CS8981: The type name 'linestrips' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(31821,26): warning CS8981: The type name 'polygons' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(31970,26): warning CS8981: The type name 'polylist' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(32091,26): warning CS8981: The type name 'triangles' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(33302,26): warning CS8981: The type name 'material' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(32197,26): warning CS8981: The type name 'trifans' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(38217,26): warning CS8981: The type name 'ellipsoid' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(32304,26): warning CS8981: The type name 'tristrips' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(32411,26): warning CS8981: The type name 'mesh' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(34212,26): warning CS8981: The type name 'node' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(34475,26): warning CS8981: The type name 'lookat' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(34524,26): warning CS8981: The type name 'matrix' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(34573,26): warning CS8981: The type name 'rotate' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(34622,26): warning CS8981: The type name 'skew' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(32491,26): warning CS8981: The type name 'spline' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(32793,26): warning CS8981: The type name 'light' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(31345,26): warning CS8981: The type name 'geometry' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(12904,26): warning CS8981: The type name 'animation' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(12997,26): warning CS8981: The type name 'channel' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(35851,26): warning CS8981: The type name 'box' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(35893,26): warning CS8981: The type name 'capsule' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(35950,26): warning CS8981: The type name 'cylinder' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(36007,26): warning CS8981: The type name 'plane' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(36049,26): warning CS8981: The type name 'sphere' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/Capabilities/CapsBase.cs(137,54): warning SYSLIB0014: 'WebRequest.Create(Uri)' is obsolete: 'WebRequest, HttpWebRequest, ServicePoint, and WebClient are obsolete. Use HttpClient instead.' (https://aka.ms/dotnet-warnings/SYSLIB0014) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/DownloadManager.cs(130,54): warning SYSLIB0014: 'WebRequest.Create(Uri)' is obsolete: 'WebRequest, HttpWebRequest, ServicePoint, and WebClient are obsolete. Use HttpClient instead.' (https://aka.ms/dotnet-warnings/SYSLIB0014) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/Imaging/BakeLayer.cs(212,22): warning CS0219: The variable 'processingSkin' is assigned but its value is never used [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/ColladalLoader.cs(157,86): warning CS0618: 'SKFilterQuality' is obsolete: 'Use SKSamplingOptions instead.' [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/ColladalLoader.cs(157,40): warning CS0618: 'SKBitmap.Resize(SKImageInfo, SKFilterQuality)' is obsolete: 'Use Resize(SKImageInfo info, SKSamplingOptions sampling) instead.' [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/AgentManagerMovement.cs(554,99): warning CS9193: Argument 1 should be a variable because it is passed to a 'ref readonly' parameter [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/EventDictionary.cs(215,27): warning CS0649: Field 'CapsEventDictionary.CapsCallbackWrapper.CapsEvent' is never assigned to, and will always have its default value null [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/ColladalLoader.cs(56,27): warning CS0649: Field 'ColladaLoader.Node.Name' is never assigned to, and will always have its default value null [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/EventDictionary.cs(213,44): warning CS0649: Field 'CapsEventDictionary.CapsCallbackWrapper.Callback' is never assigned to, and will always have its default value null [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/EventDictionary.cs(217,29): warning CS0649: Field 'CapsEventDictionary.CapsCallbackWrapper.Message' is never assigned to, and will always have its default value null [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/EventDictionary.cs(219,30): warning CS0649: Field 'CapsEventDictionary.CapsCallbackWrapper.Simulator' is never assigned to, and will always have its default value null [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] - OpenMetaverse -> /home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/bin/Debug/net8.0/OpenMetaverse.dll -/usr/lib/dotnet/sdk/10.0.107/Microsoft.Common.CurrentVersion.targets(2437,5): warning MSB3245: Could not resolve this reference. Could not locate the assembly "System.Windows.Forms". Check to make sure the assembly exists on disk. If this reference is required by your code, you may get compilation errors. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/usr/lib/dotnet/sdk/10.0.107/Microsoft.Common.CurrentVersion.targets(2437,5): warning MSB3243: No way to resolve conflict between "System.Windows.Forms, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" and "System.Windows.Forms". Choosing "System.Windows.Forms, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" arbitrarily. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj : warning NU1902: Package 'log4net' 2.0.14 has a known moderate severity vulnerability, https://github.com/advisories/GHSA-4f7c-pmjv-c25w - OpenMetaverse.Rendering.Simple -> /home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.Rendering.Simple/bin/Debug/net8.0/OpenMetaverse.Rendering.Simple.dll - OpenMetaverse.Utilities -> /home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.Utilities/bin/Debug/net8.0/OpenMetaverse.Utilities.dll - OpenMetaverse.Tests -> /home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.Tests/bin/Debug/net8.0/OpenMetaverse.Tests.dll -CSC : error CS5001: Program does not contain a static 'Main' method suitable for an entry point [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/LoginPanel.cs(196,17): warning SYSLIB0006: 'Thread.Abort()' is obsolete: 'Thread.Abort is not supported and throws PlatformNotSupportedException.' (https://aka.ms/dotnet-warnings/SYSLIB0006) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/LoginPanel.cs(246,25): warning SYSLIB0006: 'Thread.Abort()' is obsolete: 'Thread.Abort is not supported and throws PlatformNotSupportedException.' (https://aka.ms/dotnet-warnings/SYSLIB0006) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/MiniMap.cs(219,92): error CS1503: Argument 3: cannot convert from 'out System.Drawing.Image' to 'out SkiaSharp.SKBitmap' [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] - The package OpenMetaverse.1.2.0-beta-gc1eec2331d is missing a readme. Go to https://aka.ms/nuget/authoring-best-practices/readme to learn why package readmes are important. - Successfully created package '/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/bin/Debug/OpenMetaverse.1.2.0-beta-gc1eec2331d.nupkg'. - OpenMetaverse.Rendering.Meshmerizer -> /home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.Rendering.Meshmerizer/bin/Debug/net8.0/OpenMetaverse.Rendering.Meshmerizer.dll - The package OpenMetaverse.Rendering.Meshmerizer.1.2.0-beta-gc1eec2331d is missing a readme. Go to https://aka.ms/nuget/authoring-best-practices/readme to learn why package readmes are important. - Successfully created package '/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.Rendering.Meshmerizer/bin/Debug/OpenMetaverse.Rendering.Meshmerizer.1.2.0-beta-gc1eec2331d.nupkg'. - -Build FAILED. - -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj : warning NU1902: Package 'log4net' 2.0.14 has a known moderate severity vulnerability, https://github.com/advisories/GHSA-4f7c-pmjv-c25w [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.sln] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj : warning NU1902: Package 'log4net' 2.0.14 has a known moderate severity vulnerability, https://github.com/advisories/GHSA-4f7c-pmjv-c25w -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/Assets/AssetTypes/AssetMesh.cs(32,7): warning CS0105: The using directive for 'OpenMetaverse.StructuredData' appeared previously in this namespace [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/DllmapConfigHelper.cs(42,22): warning CS8981: The type name 'dllmap' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/DllmapConfigHelper.cs(55,22): warning CS8981: The type name 'configuration' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(174,26): warning CS8981: The type name 'asset' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(13040,26): warning CS8981: The type name 'sampler' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(13083,26): warning CS8981: The type name 'source' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(13699,26): warning CS8981: The type name 'accessor' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(13798,26): warning CS8981: The type name 'param' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(2538,26): warning CS8981: The type name 'extra' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(2628,26): warning CS8981: The type name 'technique' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(13979,26): warning CS8981: The type name 'camera' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(14485,26): warning CS8981: The type name 'controller' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(14576,26): warning CS8981: The type name 'morph' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(14728,26): warning CS8981: The type name 'skin' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(15052,26): warning CS8981: The type name 'effect' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(15193,26): warning CS8981: The type name 'image' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(31533,26): warning CS8981: The type name 'vertices' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(31608,26): warning CS8981: The type name 'lines' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(31714,26): warning CS8981: The type name 'linestrips' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(31821,26): warning CS8981: The type name 'polygons' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(31970,26): warning CS8981: The type name 'polylist' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(32091,26): warning CS8981: The type name 'triangles' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(33302,26): warning CS8981: The type name 'material' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(32197,26): warning CS8981: The type name 'trifans' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(38217,26): warning CS8981: The type name 'ellipsoid' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(32304,26): warning CS8981: The type name 'tristrips' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(32411,26): warning CS8981: The type name 'mesh' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(34212,26): warning CS8981: The type name 'node' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(34475,26): warning CS8981: The type name 'lookat' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(34524,26): warning CS8981: The type name 'matrix' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(34573,26): warning CS8981: The type name 'rotate' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(34622,26): warning CS8981: The type name 'skew' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(32491,26): warning CS8981: The type name 'spline' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(32793,26): warning CS8981: The type name 'light' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(31345,26): warning CS8981: The type name 'geometry' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(12904,26): warning CS8981: The type name 'animation' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(12997,26): warning CS8981: The type name 'channel' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(35851,26): warning CS8981: The type name 'box' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(35893,26): warning CS8981: The type name 'capsule' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(35950,26): warning CS8981: The type name 'cylinder' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(36007,26): warning CS8981: The type name 'plane' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(36049,26): warning CS8981: The type name 'sphere' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/Capabilities/CapsBase.cs(137,54): warning SYSLIB0014: 'WebRequest.Create(Uri)' is obsolete: 'WebRequest, HttpWebRequest, ServicePoint, and WebClient are obsolete. Use HttpClient instead.' (https://aka.ms/dotnet-warnings/SYSLIB0014) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/DownloadManager.cs(130,54): warning SYSLIB0014: 'WebRequest.Create(Uri)' is obsolete: 'WebRequest, HttpWebRequest, ServicePoint, and WebClient are obsolete. Use HttpClient instead.' (https://aka.ms/dotnet-warnings/SYSLIB0014) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/Imaging/BakeLayer.cs(212,22): warning CS0219: The variable 'processingSkin' is assigned but its value is never used [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/ColladalLoader.cs(157,86): warning CS0618: 'SKFilterQuality' is obsolete: 'Use SKSamplingOptions instead.' [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/ColladalLoader.cs(157,40): warning CS0618: 'SKBitmap.Resize(SKImageInfo, SKFilterQuality)' is obsolete: 'Use Resize(SKImageInfo info, SKSamplingOptions sampling) instead.' [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/AgentManagerMovement.cs(554,99): warning CS9193: Argument 1 should be a variable because it is passed to a 'ref readonly' parameter [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/EventDictionary.cs(215,27): warning CS0649: Field 'CapsEventDictionary.CapsCallbackWrapper.CapsEvent' is never assigned to, and will always have its default value null [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/ColladalLoader.cs(56,27): warning CS0649: Field 'ColladaLoader.Node.Name' is never assigned to, and will always have its default value null [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/EventDictionary.cs(213,44): warning CS0649: Field 'CapsEventDictionary.CapsCallbackWrapper.Callback' is never assigned to, and will always have its default value null [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/EventDictionary.cs(217,29): warning CS0649: Field 'CapsEventDictionary.CapsCallbackWrapper.Message' is never assigned to, and will always have its default value null [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/EventDictionary.cs(219,30): warning CS0649: Field 'CapsEventDictionary.CapsCallbackWrapper.Simulator' is never assigned to, and will always have its default value null [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/usr/lib/dotnet/sdk/10.0.107/Microsoft.Common.CurrentVersion.targets(2437,5): warning MSB3245: Could not resolve this reference. Could not locate the assembly "System.Windows.Forms". Check to make sure the assembly exists on disk. If this reference is required by your code, you may get compilation errors. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/usr/lib/dotnet/sdk/10.0.107/Microsoft.Common.CurrentVersion.targets(2437,5): warning MSB3243: No way to resolve conflict between "System.Windows.Forms, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" and "System.Windows.Forms". Choosing "System.Windows.Forms, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" arbitrarily. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj : warning NU1902: Package 'log4net' 2.0.14 has a known moderate severity vulnerability, https://github.com/advisories/GHSA-4f7c-pmjv-c25w -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/LoginPanel.cs(196,17): warning SYSLIB0006: 'Thread.Abort()' is obsolete: 'Thread.Abort is not supported and throws PlatformNotSupportedException.' (https://aka.ms/dotnet-warnings/SYSLIB0006) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/LoginPanel.cs(246,25): warning SYSLIB0006: 'Thread.Abort()' is obsolete: 'Thread.Abort is not supported and throws PlatformNotSupportedException.' (https://aka.ms/dotnet-warnings/SYSLIB0006) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -CSC : error CS5001: Program does not contain a static 'Main' method suitable for an entry point [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/MiniMap.cs(219,92): error CS1503: Argument 3: cannot convert from 'out System.Drawing.Image' to 'out SkiaSharp.SKBitmap' [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] - 60 Warning(s) - 2 Error(s) - -Time Elapsed 00:00:05.88 diff --git a/build_status.txt b/build_status.txt deleted file mode 100644 index d4017df5..00000000 --- a/build_status.txt +++ /dev/null @@ -1,242 +0,0 @@ - Determining projects to restore... - Skipping project "/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.PrimMesher/OpenMetaverse.PrimMesher.csproj" because it was not found. - Skipping project "/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.PrimMesher/OpenMetaverse.PrimMesher.csproj" because it was not found. -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj : warning NU1902: Package 'log4net' 2.0.14 has a known moderate severity vulnerability, https://github.com/advisories/GHSA-4f7c-pmjv-c25w [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.sln] - All projects are up-to-date for restore. -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj : warning NU1902: Package 'log4net' 2.0.14 has a known moderate severity vulnerability, https://github.com/advisories/GHSA-4f7c-pmjv-c25w - OpenMetaverse.Types -> /home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.Types/bin/Debug/net8.0/OpenMetaverse.Types.dll - OpenMetaverse.StructuredData -> /home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.StructuredData/bin/Debug/net8.0/OpenMetaverse.StructuredData.dll -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/Assets/AssetTypes/AssetMesh.cs(32,7): warning CS0105: The using directive for 'OpenMetaverse.StructuredData' appeared previously in this namespace [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(174,26): warning CS8981: The type name 'asset' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/DllmapConfigHelper.cs(42,22): warning CS8981: The type name 'dllmap' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/DllmapConfigHelper.cs(55,22): warning CS8981: The type name 'configuration' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(13040,26): warning CS8981: The type name 'sampler' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(13083,26): warning CS8981: The type name 'source' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(13699,26): warning CS8981: The type name 'accessor' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(13798,26): warning CS8981: The type name 'param' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(13979,26): warning CS8981: The type name 'camera' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(14485,26): warning CS8981: The type name 'controller' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(14576,26): warning CS8981: The type name 'morph' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(14728,26): warning CS8981: The type name 'skin' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(38217,26): warning CS8981: The type name 'ellipsoid' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(15052,26): warning CS8981: The type name 'effect' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(15193,26): warning CS8981: The type name 'image' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(33302,26): warning CS8981: The type name 'material' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(2538,26): warning CS8981: The type name 'extra' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(2628,26): warning CS8981: The type name 'technique' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(34212,26): warning CS8981: The type name 'node' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(34475,26): warning CS8981: The type name 'lookat' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(34524,26): warning CS8981: The type name 'matrix' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(34573,26): warning CS8981: The type name 'rotate' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(34622,26): warning CS8981: The type name 'skew' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(35851,26): warning CS8981: The type name 'box' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(35893,26): warning CS8981: The type name 'capsule' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(35950,26): warning CS8981: The type name 'cylinder' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(36007,26): warning CS8981: The type name 'plane' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(36049,26): warning CS8981: The type name 'sphere' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(31533,26): warning CS8981: The type name 'vertices' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(31608,26): warning CS8981: The type name 'lines' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(31714,26): warning CS8981: The type name 'linestrips' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(31821,26): warning CS8981: The type name 'polygons' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(31970,26): warning CS8981: The type name 'polylist' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(32091,26): warning CS8981: The type name 'triangles' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(32197,26): warning CS8981: The type name 'trifans' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(31345,26): warning CS8981: The type name 'geometry' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(32304,26): warning CS8981: The type name 'tristrips' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(32411,26): warning CS8981: The type name 'mesh' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(32491,26): warning CS8981: The type name 'spline' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(32793,26): warning CS8981: The type name 'light' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(12904,26): warning CS8981: The type name 'animation' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(12997,26): warning CS8981: The type name 'channel' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/Capabilities/CapsBase.cs(137,54): warning SYSLIB0014: 'WebRequest.Create(Uri)' is obsolete: 'WebRequest, HttpWebRequest, ServicePoint, and WebClient are obsolete. Use HttpClient instead.' (https://aka.ms/dotnet-warnings/SYSLIB0014) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/DownloadManager.cs(130,54): warning SYSLIB0014: 'WebRequest.Create(Uri)' is obsolete: 'WebRequest, HttpWebRequest, ServicePoint, and WebClient are obsolete. Use HttpClient instead.' (https://aka.ms/dotnet-warnings/SYSLIB0014) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/Imaging/BakeLayer.cs(212,22): warning CS0219: The variable 'processingSkin' is assigned but its value is never used [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/ColladalLoader.cs(157,86): warning CS0618: 'SKFilterQuality' is obsolete: 'Use SKSamplingOptions instead.' [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/ColladalLoader.cs(157,40): warning CS0618: 'SKBitmap.Resize(SKImageInfo, SKFilterQuality)' is obsolete: 'Use Resize(SKImageInfo info, SKSamplingOptions sampling) instead.' [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/AgentManagerMovement.cs(554,99): warning CS9193: Argument 1 should be a variable because it is passed to a 'ref readonly' parameter [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/EventDictionary.cs(219,30): warning CS0649: Field 'CapsEventDictionary.CapsCallbackWrapper.Simulator' is never assigned to, and will always have its default value null [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/EventDictionary.cs(217,29): warning CS0649: Field 'CapsEventDictionary.CapsCallbackWrapper.Message' is never assigned to, and will always have its default value null [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/EventDictionary.cs(215,27): warning CS0649: Field 'CapsEventDictionary.CapsCallbackWrapper.CapsEvent' is never assigned to, and will always have its default value null [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/EventDictionary.cs(213,44): warning CS0649: Field 'CapsEventDictionary.CapsCallbackWrapper.Callback' is never assigned to, and will always have its default value null [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/ColladalLoader.cs(56,27): warning CS0649: Field 'ColladaLoader.Node.Name' is never assigned to, and will always have its default value null [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] - OpenMetaverse -> /home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/bin/Debug/net8.0/OpenMetaverse.dll -/usr/lib/dotnet/sdk/10.0.107/Microsoft.Common.CurrentVersion.targets(2437,5): warning MSB3245: Could not resolve this reference. Could not locate the assembly "System.Windows.Forms". Check to make sure the assembly exists on disk. If this reference is required by your code, you may get compilation errors. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj : warning NU1902: Package 'log4net' 2.0.14 has a known moderate severity vulnerability, https://github.com/advisories/GHSA-4f7c-pmjv-c25w -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/AvatarList.cs(30,22): error CS0234: The type or namespace name 'Forms' does not exist in the namespace 'System.Windows' (are you missing an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/FriendList.cs(29,22): error CS0234: The type or namespace name 'Forms' does not exist in the namespace 'System.Windows' (are you missing an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/GroupList.cs(29,22): error CS0234: The type or namespace name 'Forms' does not exist in the namespace 'System.Windows' (are you missing an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/InventoryTree.cs(30,22): error CS0234: The type or namespace name 'Forms' does not exist in the namespace 'System.Windows' (are you missing an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/ListColumnSorter.cs(28,22): error CS0234: The type or namespace name 'Forms' does not exist in the namespace 'System.Windows' (are you missing an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/LocalChat.cs(30,22): error CS0234: The type or namespace name 'Forms' does not exist in the namespace 'System.Windows' (are you missing an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/LoginPanel.cs(31,22): error CS0234: The type or namespace name 'Forms' does not exist in the namespace 'System.Windows' (are you missing an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/MessageBar.cs(4,22): error CS0234: The type or namespace name 'Forms' does not exist in the namespace 'System.Windows' (are you missing an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/MiniMap.cs(31,22): error CS0234: The type or namespace name 'Forms' does not exist in the namespace 'System.Windows' (are you missing an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/StatusOutput.cs(30,22): error CS0234: The type or namespace name 'Forms' does not exist in the namespace 'System.Windows' (are you missing an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/AvatarList.cs(38,31): error CS0246: The type or namespace name 'ListView' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/FriendList.cs(37,31): error CS0246: The type or namespace name 'ListView' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/GroupList.cs(37,30): error CS0246: The type or namespace name 'ListView' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/AvatarList.cs(491,16): error CS0246: The type or namespace name 'ListViewItem' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/InventoryTree.cs(38,34): error CS0246: The type or namespace name 'TreeView' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/FriendList.cs(154,60): error CS0246: The type or namespace name 'ColumnClickEventArgs' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/GroupList.cs(104,59): error CS0246: The type or namespace name 'ColumnClickEventArgs' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/InventoryTree.cs(41,17): error CS0246: The type or namespace name 'ContextMenuStrip' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/AvatarList.cs(391,52): error CS0246: The type or namespace name 'ColumnClickEventArgs' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/InventoryTree.cs(47,16): error CS0246: The type or namespace name 'ContextMenuStrip' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/LocalChat.cs(37,30): error CS0246: The type or namespace name 'Panel' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/InventoryTree.cs(98,34): error CS0246: The type or namespace name 'TreeNode' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/LoginPanel.cs(35,31): error CS0246: The type or namespace name 'Panel' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/LocalChat.cs(45,17): error CS0246: The type or namespace name 'RichTextBox' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/InventoryTree.cs(108,32): error CS0246: The type or namespace name 'TreeNode' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/MessageBar.cs(11,31): error CS0246: The type or namespace name 'ToolStrip' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/LocalChat.cs(46,17): error CS0246: The type or namespace name 'TextBox' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/InventoryTree.cs(208,58): error CS0246: The type or namespace name 'TreeNodeMouseClickEventArgs' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/LoginPanel.cs(41,17): error CS0246: The type or namespace name 'Button' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/InventoryTree.cs(217,64): error CS0246: The type or namespace name 'TreeViewCancelEventArgs' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/LoginPanel.cs(42,17): error CS0246: The type or namespace name 'Label' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/LocalChat.cs(173,46): error CS0246: The type or namespace name 'KeyEventArgs' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/LoginPanel.cs(43,17): error CS0246: The type or namespace name 'Label' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/MessageBar.cs(244,52): error CS0246: The type or namespace name 'ToolStripItemClickedEventArgs' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/MiniMap.cs(38,28): error CS0246: The type or namespace name 'PictureBox' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/LoginPanel.cs(44,17): error CS0246: The type or namespace name 'Label' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/StatusOutput.cs(37,33): error CS0246: The type or namespace name 'RichTextBox' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/LoginPanel.cs(45,17): error CS0246: The type or namespace name 'ComboBox' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/MessageBar.cs(19,34): error CS0246: The type or namespace name 'ToolStripButton' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/LoginPanel.cs(46,17): error CS0246: The type or namespace name 'ComboBox' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/LoginPanel.cs(47,17): error CS0246: The type or namespace name 'TextBox' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/MessageBar.cs(49,52): error CS0246: The type or namespace name 'FormClosingEventArgs' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/MiniMap.cs(47,9): error CS0246: The type or namespace name 'ToolTip' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/MessageBar.cs(65,31): error CS0246: The type or namespace name 'Form' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/MessageBar.cs(67,21): error CS0246: The type or namespace name 'RichTextBox' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/MiniMap.cs(196,47): error CS0246: The type or namespace name 'MouseEventArgs' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/MessageBar.cs(68,21): error CS0246: The type or namespace name 'TextBox' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/MessageBar.cs(138,50): error CS0246: The type or namespace name 'KeyEventArgs' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] - OpenMetaverse.Rendering.Simple -> /home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.Rendering.Simple/bin/Debug/net8.0/OpenMetaverse.Rendering.Simple.dll - The package OpenMetaverse.1.2.0-beta-gc1eec2331d is missing a readme. Go to https://aka.ms/nuget/authoring-best-practices/readme to learn why package readmes are important. - Successfully created package '/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/bin/Debug/OpenMetaverse.1.2.0-beta-gc1eec2331d.nupkg'. -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.Tests/MessageTests.cs(1252,13): error SYSLIB0011: 'BinaryFormatter' is obsolete: 'BinaryFormatter serialization is obsolete and should not be used. See https://aka.ms/binaryformatter for more information.' (https://aka.ms/dotnet-warnings/SYSLIB0011) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.Tests/OpenMetaverse.Tests.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.Tests/MessageTests.cs(1252,45): error SYSLIB0011: 'BinaryFormatter' is obsolete: 'BinaryFormatter serialization is obsolete and should not be used. See https://aka.ms/binaryformatter for more information.' (https://aka.ms/dotnet-warnings/SYSLIB0011) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.Tests/OpenMetaverse.Tests.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.Tests/MessageTests.cs(1498,13): error SYSLIB0011: 'BinaryFormatter' is obsolete: 'BinaryFormatter serialization is obsolete and should not be used. See https://aka.ms/binaryformatter for more information.' (https://aka.ms/dotnet-warnings/SYSLIB0011) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.Tests/OpenMetaverse.Tests.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.Tests/MessageTests.cs(1498,45): error SYSLIB0011: 'BinaryFormatter' is obsolete: 'BinaryFormatter serialization is obsolete and should not be used. See https://aka.ms/binaryformatter for more information.' (https://aka.ms/dotnet-warnings/SYSLIB0011) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.Tests/OpenMetaverse.Tests.csproj] - OpenMetaverse.Utilities -> /home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.Utilities/bin/Debug/net8.0/OpenMetaverse.Utilities.dll - The package OpenMetaverse.Rendering.Simple.1.2.0-beta-gc1eec2331d is missing a readme. Go to https://aka.ms/nuget/authoring-best-practices/readme to learn why package readmes are important. - Successfully created package '/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.Rendering.Simple/bin/Debug/OpenMetaverse.Rendering.Simple.1.2.0-beta-gc1eec2331d.nupkg'. -/usr/lib/dotnet/sdk/10.0.107/Microsoft.Common.CurrentVersion.targets(2189,5): warning MSB9008: The referenced project ../OpenMetaverse.PrimMesher/OpenMetaverse.PrimMesher.csproj does not exist. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.Rendering.Meshmerizer/OpenMetaverse.Rendering.Meshmerizer.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.Rendering.Meshmerizer/MeshmerizerR.cs(432,17): error CS0246: The type or namespace name 'PrimMesher' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.Rendering.Meshmerizer/OpenMetaverse.Rendering.Meshmerizer.csproj] - -Build FAILED. - -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj : warning NU1902: Package 'log4net' 2.0.14 has a known moderate severity vulnerability, https://github.com/advisories/GHSA-4f7c-pmjv-c25w [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.sln] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj : warning NU1902: Package 'log4net' 2.0.14 has a known moderate severity vulnerability, https://github.com/advisories/GHSA-4f7c-pmjv-c25w -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/Assets/AssetTypes/AssetMesh.cs(32,7): warning CS0105: The using directive for 'OpenMetaverse.StructuredData' appeared previously in this namespace [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(174,26): warning CS8981: The type name 'asset' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/DllmapConfigHelper.cs(42,22): warning CS8981: The type name 'dllmap' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/DllmapConfigHelper.cs(55,22): warning CS8981: The type name 'configuration' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(13040,26): warning CS8981: The type name 'sampler' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(13083,26): warning CS8981: The type name 'source' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(13699,26): warning CS8981: The type name 'accessor' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(13798,26): warning CS8981: The type name 'param' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(13979,26): warning CS8981: The type name 'camera' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(14485,26): warning CS8981: The type name 'controller' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(14576,26): warning CS8981: The type name 'morph' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(14728,26): warning CS8981: The type name 'skin' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(38217,26): warning CS8981: The type name 'ellipsoid' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(15052,26): warning CS8981: The type name 'effect' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(15193,26): warning CS8981: The type name 'image' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(33302,26): warning CS8981: The type name 'material' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(2538,26): warning CS8981: The type name 'extra' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(2628,26): warning CS8981: The type name 'technique' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(34212,26): warning CS8981: The type name 'node' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(34475,26): warning CS8981: The type name 'lookat' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(34524,26): warning CS8981: The type name 'matrix' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(34573,26): warning CS8981: The type name 'rotate' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(34622,26): warning CS8981: The type name 'skew' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(35851,26): warning CS8981: The type name 'box' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(35893,26): warning CS8981: The type name 'capsule' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(35950,26): warning CS8981: The type name 'cylinder' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(36007,26): warning CS8981: The type name 'plane' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(36049,26): warning CS8981: The type name 'sphere' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(31533,26): warning CS8981: The type name 'vertices' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(31608,26): warning CS8981: The type name 'lines' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(31714,26): warning CS8981: The type name 'linestrips' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(31821,26): warning CS8981: The type name 'polygons' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(31970,26): warning CS8981: The type name 'polylist' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(32091,26): warning CS8981: The type name 'triangles' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(32197,26): warning CS8981: The type name 'trifans' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(31345,26): warning CS8981: The type name 'geometry' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(32304,26): warning CS8981: The type name 'tristrips' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(32411,26): warning CS8981: The type name 'mesh' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(32491,26): warning CS8981: The type name 'spline' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(32793,26): warning CS8981: The type name 'light' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(12904,26): warning CS8981: The type name 'animation' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/Collada.cs(12997,26): warning CS8981: The type name 'channel' only contains lower-cased ascii characters. Such names may become reserved for the language. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/Capabilities/CapsBase.cs(137,54): warning SYSLIB0014: 'WebRequest.Create(Uri)' is obsolete: 'WebRequest, HttpWebRequest, ServicePoint, and WebClient are obsolete. Use HttpClient instead.' (https://aka.ms/dotnet-warnings/SYSLIB0014) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/DownloadManager.cs(130,54): warning SYSLIB0014: 'WebRequest.Create(Uri)' is obsolete: 'WebRequest, HttpWebRequest, ServicePoint, and WebClient are obsolete. Use HttpClient instead.' (https://aka.ms/dotnet-warnings/SYSLIB0014) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/Imaging/BakeLayer.cs(212,22): warning CS0219: The variable 'processingSkin' is assigned but its value is never used [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/ColladalLoader.cs(157,86): warning CS0618: 'SKFilterQuality' is obsolete: 'Use SKSamplingOptions instead.' [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/ColladalLoader.cs(157,40): warning CS0618: 'SKBitmap.Resize(SKImageInfo, SKFilterQuality)' is obsolete: 'Use Resize(SKImageInfo info, SKSamplingOptions sampling) instead.' [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/AgentManagerMovement.cs(554,99): warning CS9193: Argument 1 should be a variable because it is passed to a 'ref readonly' parameter [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/EventDictionary.cs(219,30): warning CS0649: Field 'CapsEventDictionary.CapsCallbackWrapper.Simulator' is never assigned to, and will always have its default value null [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/EventDictionary.cs(217,29): warning CS0649: Field 'CapsEventDictionary.CapsCallbackWrapper.Message' is never assigned to, and will always have its default value null [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/EventDictionary.cs(215,27): warning CS0649: Field 'CapsEventDictionary.CapsCallbackWrapper.CapsEvent' is never assigned to, and will always have its default value null [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/EventDictionary.cs(213,44): warning CS0649: Field 'CapsEventDictionary.CapsCallbackWrapper.Callback' is never assigned to, and will always have its default value null [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/ImportExport/ColladalLoader.cs(56,27): warning CS0649: Field 'ColladaLoader.Node.Name' is never assigned to, and will always have its default value null [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj] -/usr/lib/dotnet/sdk/10.0.107/Microsoft.Common.CurrentVersion.targets(2437,5): warning MSB3245: Could not resolve this reference. Could not locate the assembly "System.Windows.Forms". Check to make sure the assembly exists on disk. If this reference is required by your code, you may get compilation errors. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse/OpenMetaverse.csproj : warning NU1902: Package 'log4net' 2.0.14 has a known moderate severity vulnerability, https://github.com/advisories/GHSA-4f7c-pmjv-c25w -/usr/lib/dotnet/sdk/10.0.107/Microsoft.Common.CurrentVersion.targets(2189,5): warning MSB9008: The referenced project ../OpenMetaverse.PrimMesher/OpenMetaverse.PrimMesher.csproj does not exist. [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.Rendering.Meshmerizer/OpenMetaverse.Rendering.Meshmerizer.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/AvatarList.cs(30,22): error CS0234: The type or namespace name 'Forms' does not exist in the namespace 'System.Windows' (are you missing an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/FriendList.cs(29,22): error CS0234: The type or namespace name 'Forms' does not exist in the namespace 'System.Windows' (are you missing an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/GroupList.cs(29,22): error CS0234: The type or namespace name 'Forms' does not exist in the namespace 'System.Windows' (are you missing an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/InventoryTree.cs(30,22): error CS0234: The type or namespace name 'Forms' does not exist in the namespace 'System.Windows' (are you missing an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/ListColumnSorter.cs(28,22): error CS0234: The type or namespace name 'Forms' does not exist in the namespace 'System.Windows' (are you missing an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/LocalChat.cs(30,22): error CS0234: The type or namespace name 'Forms' does not exist in the namespace 'System.Windows' (are you missing an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/LoginPanel.cs(31,22): error CS0234: The type or namespace name 'Forms' does not exist in the namespace 'System.Windows' (are you missing an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/MessageBar.cs(4,22): error CS0234: The type or namespace name 'Forms' does not exist in the namespace 'System.Windows' (are you missing an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/MiniMap.cs(31,22): error CS0234: The type or namespace name 'Forms' does not exist in the namespace 'System.Windows' (are you missing an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/StatusOutput.cs(30,22): error CS0234: The type or namespace name 'Forms' does not exist in the namespace 'System.Windows' (are you missing an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/AvatarList.cs(38,31): error CS0246: The type or namespace name 'ListView' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/FriendList.cs(37,31): error CS0246: The type or namespace name 'ListView' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/GroupList.cs(37,30): error CS0246: The type or namespace name 'ListView' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/AvatarList.cs(491,16): error CS0246: The type or namespace name 'ListViewItem' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/InventoryTree.cs(38,34): error CS0246: The type or namespace name 'TreeView' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/FriendList.cs(154,60): error CS0246: The type or namespace name 'ColumnClickEventArgs' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/GroupList.cs(104,59): error CS0246: The type or namespace name 'ColumnClickEventArgs' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/InventoryTree.cs(41,17): error CS0246: The type or namespace name 'ContextMenuStrip' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/AvatarList.cs(391,52): error CS0246: The type or namespace name 'ColumnClickEventArgs' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/InventoryTree.cs(47,16): error CS0246: The type or namespace name 'ContextMenuStrip' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/LocalChat.cs(37,30): error CS0246: The type or namespace name 'Panel' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/InventoryTree.cs(98,34): error CS0246: The type or namespace name 'TreeNode' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/LoginPanel.cs(35,31): error CS0246: The type or namespace name 'Panel' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/LocalChat.cs(45,17): error CS0246: The type or namespace name 'RichTextBox' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/InventoryTree.cs(108,32): error CS0246: The type or namespace name 'TreeNode' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/MessageBar.cs(11,31): error CS0246: The type or namespace name 'ToolStrip' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/LocalChat.cs(46,17): error CS0246: The type or namespace name 'TextBox' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/InventoryTree.cs(208,58): error CS0246: The type or namespace name 'TreeNodeMouseClickEventArgs' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/LoginPanel.cs(41,17): error CS0246: The type or namespace name 'Button' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/InventoryTree.cs(217,64): error CS0246: The type or namespace name 'TreeViewCancelEventArgs' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/LoginPanel.cs(42,17): error CS0246: The type or namespace name 'Label' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/LocalChat.cs(173,46): error CS0246: The type or namespace name 'KeyEventArgs' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/LoginPanel.cs(43,17): error CS0246: The type or namespace name 'Label' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/MessageBar.cs(244,52): error CS0246: The type or namespace name 'ToolStripItemClickedEventArgs' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/MiniMap.cs(38,28): error CS0246: The type or namespace name 'PictureBox' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/LoginPanel.cs(44,17): error CS0246: The type or namespace name 'Label' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/StatusOutput.cs(37,33): error CS0246: The type or namespace name 'RichTextBox' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/LoginPanel.cs(45,17): error CS0246: The type or namespace name 'ComboBox' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/MessageBar.cs(19,34): error CS0246: The type or namespace name 'ToolStripButton' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/LoginPanel.cs(46,17): error CS0246: The type or namespace name 'ComboBox' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/LoginPanel.cs(47,17): error CS0246: The type or namespace name 'TextBox' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/MessageBar.cs(49,52): error CS0246: The type or namespace name 'FormClosingEventArgs' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/MiniMap.cs(47,9): error CS0246: The type or namespace name 'ToolTip' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/MessageBar.cs(65,31): error CS0246: The type or namespace name 'Form' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/MessageBar.cs(67,21): error CS0246: The type or namespace name 'RichTextBox' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/MiniMap.cs(196,47): error CS0246: The type or namespace name 'MouseEventArgs' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/MessageBar.cs(68,21): error CS0246: The type or namespace name 'TextBox' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/MessageBar.cs(138,50): error CS0246: The type or namespace name 'KeyEventArgs' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.GUI/OpenMetaverse.GUI.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.Tests/MessageTests.cs(1252,13): error SYSLIB0011: 'BinaryFormatter' is obsolete: 'BinaryFormatter serialization is obsolete and should not be used. See https://aka.ms/binaryformatter for more information.' (https://aka.ms/dotnet-warnings/SYSLIB0011) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.Tests/OpenMetaverse.Tests.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.Tests/MessageTests.cs(1252,45): error SYSLIB0011: 'BinaryFormatter' is obsolete: 'BinaryFormatter serialization is obsolete and should not be used. See https://aka.ms/binaryformatter for more information.' (https://aka.ms/dotnet-warnings/SYSLIB0011) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.Tests/OpenMetaverse.Tests.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.Tests/MessageTests.cs(1498,13): error SYSLIB0011: 'BinaryFormatter' is obsolete: 'BinaryFormatter serialization is obsolete and should not be used. See https://aka.ms/binaryformatter for more information.' (https://aka.ms/dotnet-warnings/SYSLIB0011) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.Tests/OpenMetaverse.Tests.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.Tests/MessageTests.cs(1498,45): error SYSLIB0011: 'BinaryFormatter' is obsolete: 'BinaryFormatter serialization is obsolete and should not be used. See https://aka.ms/binaryformatter for more information.' (https://aka.ms/dotnet-warnings/SYSLIB0011) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.Tests/OpenMetaverse.Tests.csproj] -/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.Rendering.Meshmerizer/MeshmerizerR.cs(432,17): error CS0246: The type or namespace name 'PrimMesher' could not be found (are you missing a using directive or an assembly reference?) [/home/mdickson/Documents/Projects/OpenSimulator/source/libopenmetaverse/OpenMetaverse.Rendering.Meshmerizer/OpenMetaverse.Rendering.Meshmerizer.csproj] - 58 Warning(s) - 53 Error(s) - -Time Elapsed 00:00:05.88 From 8cf793fa4fcae494537d13e7c20ba9400a425a19 Mon Sep 17 00:00:00 2001 From: Mike Dickson Date: Fri, 15 May 2026 12:13:21 -0400 Subject: [PATCH 146/149] Add GitHub Packages NuGet publishing workflow - Add .github/workflows/publish-nuget.yml: publishes 5 library projects (OpenMetaverse, OpenMetaverse.Types, OpenMetaverse.StructuredData, OpenMetaverse.Rendering.Simple, OpenMetaverse.Rendering.Meshmerizer) to GitHub Packages on v* tag push - Add nuget.config: registers nuget.org and github feed sources - Directory.Build.props: add IncludeSymbols/snupkg and EmbedAllSources so every pack produces a .snupkg companion for source-level debugging - version.json: add v* tag pattern to publicReleaseRefSpec so Nerdbank.GitVersioning stamps a clean release version on tagged commits - Each published .csproj: add explicit PackageId and Description --- .github/workflows/publish-nuget.yml | 63 +++++++++++++++++++ Directory.Build.props | 8 +++ ...OpenMetaverse.Rendering.Meshmerizer.csproj | 2 + .../OpenMetaverse.Rendering.Simple.csproj | 2 + .../OpenMetaverse.StructuredData.csproj | 2 + .../OpenMetaverse.Types.csproj | 2 + OpenMetaverse/OpenMetaverse.csproj | 2 + nuget.config | 19 ++++++ version.json | 3 +- 9 files changed, 102 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/publish-nuget.yml create mode 100644 nuget.config diff --git a/.github/workflows/publish-nuget.yml b/.github/workflows/publish-nuget.yml new file mode 100644 index 00000000..16969201 --- /dev/null +++ b/.github/workflows/publish-nuget.yml @@ -0,0 +1,63 @@ +name: Publish NuGet Packages + +on: + push: + tags: + - 'v*' + +jobs: + publish: + runs-on: ubuntu-latest + + permissions: + packages: write + contents: read + + steps: + - name: Checkout (full history for Nerdbank.GitVersioning) + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Setup .NET + uses: actions/setup-dotnet@v4 + with: + dotnet-version: '8.0.x' + + - name: Add GitHub Packages source + run: | + dotnet nuget add source \ + "https://nuget.pkg.github.com/OpenSim-NGC/index.json" \ + --name "github" \ + --username "${{ github.actor }}" \ + --password "${{ secrets.GITHUB_TOKEN }}" \ + --store-password-in-clear-text + + - name: Restore dependencies + run: dotnet restore OpenMetaverse.sln + + - name: Build (Release) + run: dotnet build OpenMetaverse.sln -c Release --no-restore + + - name: Pack library projects + run: | + mkdir -p ./nupkgs + for proj in \ + OpenMetaverse.Types/OpenMetaverse.Types.csproj \ + OpenMetaverse.StructuredData/OpenMetaverse.StructuredData.csproj \ + OpenMetaverse/OpenMetaverse.csproj \ + OpenMetaverse.Rendering.Simple/OpenMetaverse.Rendering.Simple.csproj \ + OpenMetaverse.Rendering.Meshmerizer/OpenMetaverse.Rendering.Meshmerizer.csproj; do + dotnet pack "$proj" \ + -c Release \ + --no-build \ + --include-symbols \ + -o ./nupkgs + done + + - name: Publish packages to GitHub Packages + run: | + dotnet nuget push "./nupkgs/*.nupkg" \ + --api-key "${{ secrets.GITHUB_TOKEN }}" \ + --source "github" \ + --skip-duplicate diff --git a/Directory.Build.props b/Directory.Build.props index abfc78ce..e080a9ee 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -22,4 +22,12 @@ git master + + + true + snupkg + + true + true + diff --git a/OpenMetaverse.Rendering.Meshmerizer/OpenMetaverse.Rendering.Meshmerizer.csproj b/OpenMetaverse.Rendering.Meshmerizer/OpenMetaverse.Rendering.Meshmerizer.csproj index 1f747d2b..2efdd8d8 100644 --- a/OpenMetaverse.Rendering.Meshmerizer/OpenMetaverse.Rendering.Meshmerizer.csproj +++ b/OpenMetaverse.Rendering.Meshmerizer/OpenMetaverse.Rendering.Meshmerizer.csproj @@ -2,6 +2,8 @@ Local Library + OpenMetaverse.Rendering.Meshmerizer + Full primitive and sculpt mesh renderer using the Meshmerizer engine for the OpenMetaverse library. True true diff --git a/OpenMetaverse.Rendering.Simple/OpenMetaverse.Rendering.Simple.csproj b/OpenMetaverse.Rendering.Simple/OpenMetaverse.Rendering.Simple.csproj index 2d6e3a7e..5724560c 100644 --- a/OpenMetaverse.Rendering.Simple/OpenMetaverse.Rendering.Simple.csproj +++ b/OpenMetaverse.Rendering.Simple/OpenMetaverse.Rendering.Simple.csproj @@ -2,6 +2,8 @@ Local Library + OpenMetaverse.Rendering.Simple + Simple faceted primitive mesh renderer for the OpenMetaverse library. True true diff --git a/OpenMetaverse.StructuredData/OpenMetaverse.StructuredData.csproj b/OpenMetaverse.StructuredData/OpenMetaverse.StructuredData.csproj index 9c6cf0e4..bd7d2492 100644 --- a/OpenMetaverse.StructuredData/OpenMetaverse.StructuredData.csproj +++ b/OpenMetaverse.StructuredData/OpenMetaverse.StructuredData.csproj @@ -2,6 +2,8 @@ Local Library + OpenMetaverse.StructuredData + LLSD/OSD structured data serialization (XML, JSON, binary) for the OpenMetaverse library. true true diff --git a/OpenMetaverse.Types/OpenMetaverse.Types.csproj b/OpenMetaverse.Types/OpenMetaverse.Types.csproj index 1e443107..5bf1ce46 100644 --- a/OpenMetaverse.Types/OpenMetaverse.Types.csproj +++ b/OpenMetaverse.Types/OpenMetaverse.Types.csproj @@ -2,6 +2,8 @@ Local Library + OpenMetaverse.Types + Core value types for the OpenMetaverse library: UUID, Vector2/3/4, Quaternion, Matrix4, Color4, and related utilities. OpenMetaverse True true diff --git a/OpenMetaverse/OpenMetaverse.csproj b/OpenMetaverse/OpenMetaverse.csproj index bcad839b..ada947fa 100644 --- a/OpenMetaverse/OpenMetaverse.csproj +++ b/OpenMetaverse/OpenMetaverse.csproj @@ -2,6 +2,8 @@ Local Library + OpenMetaverse + Client library for OpenMetaverse-compatible virtual world servers such as OpenSimulator. Provides login, inventory, asset, object, and messaging APIs. OpenMetaverse True true diff --git a/nuget.config b/nuget.config new file mode 100644 index 00000000..ec65b0db --- /dev/null +++ b/nuget.config @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + diff --git a/version.json b/version.json index a6930844..d51a1459 100644 --- a/version.json +++ b/version.json @@ -3,7 +3,8 @@ "version": "1.2-beta", "publicReleaseRefSpec": [ "^refs/heads/master$", - "^refs/heads/v\\d+(?:\\.\\d+)?$" + "^refs/heads/v\\d+(?:\\.\\d+)?$", + "^refs/tags/v\\d+(?:\\.\\d+(?:\\.\\d+)?)?$" ], "cloudBuild": { "buildNumber": { From 8d9fa49a41b3a9d8a15f98d12b82061e289ec4b7 Mon Sep 17 00:00:00 2001 From: Mike Dickson Date: Fri, 15 May 2026 12:19:11 -0400 Subject: [PATCH 147/149] ci: update dotnet.yml to current action versions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - actions/checkout@v3 → @v4 - actions/setup-dotnet@v1 → @v4 - dotnet-version 5.0.x → 8.0.x - Add fetch-depth: 0 for Nerdbank.GitVersioning --- .github/workflows/dotnet.yml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index a2bdca47..dcfe67eb 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -12,11 +12,13 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 + with: + fetch-depth: 0 # Required for Nerdbank.GitVersioning - name: Setup .NET - uses: actions/setup-dotnet@v1 + uses: actions/setup-dotnet@v4 with: - dotnet-version: 5.0.x + dotnet-version: '8.0.x' - name: Restore dependencies run: dotnet restore - name: Build From 4a26b002278f39c52ba14939bc7c619421a8f123 Mon Sep 17 00:00:00 2001 From: Mike Dickson Date: Fri, 15 May 2026 13:12:55 -0400 Subject: [PATCH 148/149] tests: migrate to xUnit and stabilize CI test selection - Convert OpenMetaverse.Tests from NUnit to xUnit - Replace benchmark ZeroFormatter usage with MessagePack over LLSD binary payloads - Preserve benchmark traiting and fix MessagePack UUID constructor issues - Update CI workflow to exclude Network and Benchmark categories in default run - Keep test project buildable on .NET 8 --- .github/workflows/dotnet.yml | 2 +- OpenMetaverse.Tests/BinaryLLSDTests.cs | 352 +++---- OpenMetaverse.Tests/MessageTests.cs | 919 +++++++++--------- OpenMetaverse.Tests/NetworkTests.cs | 59 +- OpenMetaverse.Tests/NotationLLSDTests.cs | 450 ++++----- .../OpenMetaverse.Tests.csproj | 8 +- OpenMetaverse.Tests/PacketTests.cs | 78 +- OpenMetaverse.Tests/PrimObjectTests.cs | 40 +- OpenMetaverse.Tests/TypeTests.cs | 144 +-- OpenMetaverse.Tests/XmlLLSDTests.cs | 260 ++--- 10 files changed, 1162 insertions(+), 1150 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index dcfe67eb..fff48955 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -24,4 +24,4 @@ jobs: - name: Build run: dotnet build --no-restore - name: Test - run: dotnet test --no-build --verbosity normal + run: dotnet test --no-build --verbosity normal --filter "Category!=Network&Category!=Benchmark" diff --git a/OpenMetaverse.Tests/BinaryLLSDTests.cs b/OpenMetaverse.Tests/BinaryLLSDTests.cs index 0f9e31f8..67962320 100644 --- a/OpenMetaverse.Tests/BinaryLLSDTests.cs +++ b/OpenMetaverse.Tests/BinaryLLSDTests.cs @@ -36,7 +36,7 @@ * */ -using NUnit.Framework; +using Xunit; using OpenMetaverse.StructuredData; using System; using System.IO; @@ -46,12 +46,12 @@ namespace OpenMetaverse.Tests { - [TestFixture()] + public class BinarySDTests { private static readonly byte[] binaryHead = Encoding.ASCII.GetBytes("\n"); - [Test()] + [Fact] public void HelperFunctions() { string s = "this is a teststring so that we can find something from the beginning"; @@ -60,39 +60,39 @@ public void HelperFunctions() stream.Position = 0L; bool result = OSDParser.FindString(stream, "this"); - Assert.AreEqual(true, result); - Assert.AreEqual(4L, stream.Position); + Assert.Equal(true, result); + Assert.Equal(4L, stream.Position); stream.Position = 10L; result = OSDParser.FindString(stream, "teststring"); - Assert.AreEqual(true, result); - Assert.AreEqual(20L, stream.Position); + Assert.Equal(true, result); + Assert.Equal(20L, stream.Position); stream.Position = 25L; result = OSDParser.FindString(stream, "notfound"); - Assert.AreEqual(false, result); - Assert.AreEqual(25L, stream.Position); + Assert.Equal(false, result); + Assert.Equal(25L, stream.Position); stream.Position = 60L; result = OSDParser.FindString(stream, "beginningAndMore"); - Assert.AreEqual(false, result); - Assert.AreEqual(60L, stream.Position); + Assert.Equal(false, result); + Assert.Equal(60L, stream.Position); byte[] sFrontWhiteSpace = Encoding.ASCII.GetBytes(" \t\t\n\rtest"); MemoryStream streamTwo = new MemoryStream(sFrontWhiteSpace); OSDParser.SkipWhiteSpace(streamTwo); - Assert.AreEqual(7L, streamTwo.Position); + Assert.Equal(7L, streamTwo.Position); byte[] sMiddleWhiteSpace = Encoding.ASCII.GetBytes("test \t\t\n\rtest"); MemoryStream streamThree = new MemoryStream(sMiddleWhiteSpace); streamThree.Position = 4L; OSDParser.SkipWhiteSpace(streamThree); - Assert.AreEqual(9L, streamThree.Position); + Assert.Equal(9L, streamThree.Position); byte[] sNoWhiteSpace = Encoding.ASCII.GetBytes("testtesttest"); MemoryStream streamFour = new MemoryStream(sNoWhiteSpace); OSDParser.SkipWhiteSpace(streamFour); - Assert.AreEqual(0L, streamFour.Position); + Assert.Equal(0L, streamFour.Position); } @@ -100,19 +100,19 @@ public void HelperFunctions() private static byte[] binaryUndefValue = { 0x21 }; private static byte[] binaryUndef = (byte[])ConcatenateArrays(binaryHead, binaryUndefValue); - [Test()] + [Fact] public void DeserializeUndef() { OSD llsdUndef = OSDParser.DeserializeLLSDBinary(binaryUndef); - Assert.AreEqual(OSDType.Unknown, llsdUndef.Type); + Assert.Equal(OSDType.Unknown, llsdUndef.Type); } - [Test()] + [Fact] public void SerializeUndef() { OSD llsdUndef = new OSD(); byte[] binaryUndefSerialized = OSDParser.SerializeLLSDBinary(llsdUndef); - Assert.AreEqual(binaryUndef, binaryUndefSerialized); + Assert.Equal(binaryUndef, binaryUndefSerialized); } private static byte[] binaryTrueValue = { 0x31 }; @@ -122,28 +122,28 @@ public void SerializeUndef() private static byte[] binaryFalseValue = { 0x30 }; private static byte[] binaryFalse = (byte[])ConcatenateArrays(binaryHead, binaryFalseValue); - [Test()] + [Fact] public void DeserializeBool() { OSD llsdTrue = OSDParser.DeserializeLLSDBinary(binaryTrue); - Assert.AreEqual(OSDType.Boolean, llsdTrue.Type); - Assert.AreEqual(true, llsdTrue.AsBoolean()); + Assert.Equal(OSDType.Boolean, llsdTrue.Type); + Assert.Equal(true, llsdTrue.AsBoolean()); OSD llsdFalse = OSDParser.DeserializeLLSDBinary(binaryFalse); - Assert.AreEqual(OSDType.Boolean, llsdFalse.Type); - Assert.AreEqual(false, llsdFalse.AsBoolean()); + Assert.Equal(OSDType.Boolean, llsdFalse.Type); + Assert.Equal(false, llsdFalse.AsBoolean()); } - [Test()] + [Fact] public void SerializeBool() { OSD llsdTrue = OSD.FromBoolean(true); byte[] binaryTrueSerialized = OSDParser.SerializeLLSDBinary(llsdTrue); - Assert.AreEqual(binaryTrue, binaryTrueSerialized); + Assert.Equal(binaryTrue, binaryTrueSerialized); OSD llsdFalse = OSD.FromBoolean(false); byte[] binaryFalseSerialized = OSDParser.SerializeLLSDBinary(llsdFalse); - Assert.AreEqual(binaryFalse, binaryFalseSerialized); + Assert.Equal(binaryFalse, binaryFalseSerialized); } private static byte[] binaryZeroIntValue = { 0x69, 0x0, 0x0, 0x0, 0x0 }; @@ -152,57 +152,57 @@ public void SerializeBool() private static byte[] binaryAnIntValue = { 0x69, 0x0, 0x12, 0xd7, 0x9b }; private static byte[] binaryAnInt = (byte[])ConcatenateArrays(binaryHead, binaryAnIntValue); - [Test()] + [Fact] public void DeserializeInteger() { OSD llsdZeroInteger = OSDParser.DeserializeLLSDBinary(binaryZeroInt); - Assert.AreEqual(OSDType.Integer, llsdZeroInteger.Type); - Assert.AreEqual(0, llsdZeroInteger.AsInteger()); + Assert.Equal(OSDType.Integer, llsdZeroInteger.Type); + Assert.Equal(0, llsdZeroInteger.AsInteger()); OSD llsdAnInteger = OSDParser.DeserializeLLSDBinary(binaryAnInt); - Assert.AreEqual(OSDType.Integer, llsdAnInteger.Type); - Assert.AreEqual(1234843, llsdAnInteger.AsInteger()); + Assert.Equal(OSDType.Integer, llsdAnInteger.Type); + Assert.Equal(1234843, llsdAnInteger.AsInteger()); } - [Test()] + [Fact] public void SerializeInteger() { OSD llsdZeroInt = OSD.FromInteger(0); byte[] binaryZeroIntSerialized = OSDParser.SerializeLLSDBinary(llsdZeroInt); - Assert.AreEqual(binaryZeroInt, binaryZeroIntSerialized); + Assert.Equal(binaryZeroInt, binaryZeroIntSerialized); binaryZeroIntSerialized = OSDParser.SerializeLLSDBinary(llsdZeroInt, false); - Assert.AreEqual(binaryZeroIntValue, binaryZeroIntSerialized); + Assert.Equal(binaryZeroIntValue, binaryZeroIntSerialized); OSD llsdAnInt = OSD.FromInteger(1234843); byte[] binaryAnIntSerialized = OSDParser.SerializeLLSDBinary(llsdAnInt); - Assert.AreEqual(binaryAnInt, binaryAnIntSerialized); + Assert.Equal(binaryAnInt, binaryAnIntSerialized); binaryAnIntSerialized = OSDParser.SerializeLLSDBinary(llsdAnInt, false); - Assert.AreEqual(binaryAnIntValue, binaryAnIntSerialized); + Assert.Equal(binaryAnIntValue, binaryAnIntSerialized); } private static byte[] binaryRealValue = { 0x72, 0x41, 0x2c, 0xec, 0xf6, 0x77, 0xce, 0xd9, 0x17 }; private static byte[] binaryReal = (byte[])ConcatenateArrays(binaryHead, binaryRealValue); - [Test()] + [Fact] public void DeserializeReal() { OSD llsdReal = OSDParser.DeserializeLLSDBinary(binaryReal); - Assert.AreEqual(OSDType.Real, llsdReal.Type); - Assert.AreEqual(947835.234d, llsdReal.AsReal()); + Assert.Equal(OSDType.Real, llsdReal.Type); + Assert.Equal(947835.234d, llsdReal.AsReal()); } - [Test()] + [Fact] public void SerializeReal() { OSD llsdReal = OSD.FromReal(947835.234d); byte[] binaryRealSerialized = OSDParser.SerializeLLSDBinary(llsdReal); - Assert.AreEqual(binaryReal, binaryRealSerialized); + Assert.Equal(binaryReal, binaryRealSerialized); binaryRealSerialized = OSDParser.SerializeLLSDBinary(llsdReal); - Assert.AreEqual(binaryReal, binaryRealSerialized); + Assert.Equal(binaryReal, binaryRealSerialized); } private static byte[] binaryAUUIDValue = { 0x75, 0x97, 0xf4, 0xae, 0xca, 0x88, 0xa1, 0x42, 0xa1, @@ -213,35 +213,35 @@ public void SerializeReal() private static byte[] binaryZeroUUID = (byte[])ConcatenateArrays(binaryHead, binaryZeroUUIDValue); - [Test()] + [Fact] public void DeserializeUUID() { OSD llsdAUUID = OSDParser.DeserializeLLSDBinary(binaryAUUID); - Assert.AreEqual(OSDType.UUID, llsdAUUID.Type); - Assert.AreEqual("97f4aeca-88a1-42a1-b385-b97b18abb255", llsdAUUID.AsString()); + Assert.Equal(OSDType.UUID, llsdAUUID.Type); + Assert.Equal("97f4aeca-88a1-42a1-b385-b97b18abb255", llsdAUUID.AsString()); OSD llsdZeroUUID = OSDParser.DeserializeLLSDBinary(binaryZeroUUID); - Assert.AreEqual(OSDType.UUID, llsdZeroUUID.Type); - Assert.AreEqual("00000000-0000-0000-0000-000000000000", llsdZeroUUID.AsString()); + Assert.Equal(OSDType.UUID, llsdZeroUUID.Type); + Assert.Equal("00000000-0000-0000-0000-000000000000", llsdZeroUUID.AsString()); } - [Test()] + [Fact] public void SerializeUUID() { OSD llsdAUUID = OSD.FromUUID(new UUID("97f4aeca-88a1-42a1-b385-b97b18abb255")); byte[] binaryAUUIDSerialized = OSDParser.SerializeLLSDBinary(llsdAUUID); - Assert.AreEqual(binaryAUUID, binaryAUUIDSerialized); + Assert.Equal(binaryAUUID, binaryAUUIDSerialized); binaryAUUIDSerialized = OSDParser.SerializeLLSDBinary(llsdAUUID); - Assert.AreEqual(binaryAUUID, binaryAUUIDSerialized); + Assert.Equal(binaryAUUID, binaryAUUIDSerialized); OSD llsdZeroUUID = OSD.FromUUID(new UUID("00000000-0000-0000-0000-000000000000")); byte[] binaryZeroUUIDSerialized = OSDParser.SerializeLLSDBinary(llsdZeroUUID); - Assert.AreEqual(binaryZeroUUID, binaryZeroUUIDSerialized); + Assert.Equal(binaryZeroUUID, binaryZeroUUIDSerialized); binaryZeroUUIDSerialized = OSDParser.SerializeLLSDBinary(llsdZeroUUID); - Assert.AreEqual(binaryZeroUUID, binaryZeroUUIDSerialized); + Assert.Equal(binaryZeroUUID, binaryZeroUUIDSerialized); } private static byte[] binaryBinStringValue = { 0x62, 0x0, 0x0, 0x0, 0x34, // this line is the encoding header @@ -251,19 +251,19 @@ public void SerializeUUID() 0x69, 0x73, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0xa, 0xd }; private static byte[] binaryBinString = (byte[])ConcatenateArrays(binaryHead, binaryBinStringValue); - [Test()] + [Fact] public void DeserializeLLSDBinary() { OSD llsdBytes = OSDParser.DeserializeLLSDBinary(binaryBinString); - Assert.AreEqual(OSDType.Binary, llsdBytes.Type); + Assert.Equal(OSDType.Binary, llsdBytes.Type); byte[] contentBinString = { 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x20, 0x73, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x20, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0xa, 0xd }; - Assert.AreEqual(contentBinString, llsdBytes.AsBinary()); + Assert.Equal(contentBinString, llsdBytes.AsBinary()); } - [Test()] + [Fact] public void SerializeLLSDBinary() { byte[] contentBinString = { 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x20, 0x73, @@ -272,7 +272,7 @@ public void SerializeLLSDBinary() 0x69, 0x73, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0xa, 0xd }; OSD llsdBinary = OSD.FromBinary(contentBinString); byte[] binaryBinarySerialized = OSDParser.SerializeLLSDBinary(llsdBinary); - Assert.AreEqual(binaryBinString, binaryBinarySerialized); + Assert.Equal(binaryBinString, binaryBinarySerialized); } private static byte[] binaryEmptyStringValue = { 0x73, 0x0, 0x0, 0x0, 0x0 }; @@ -286,26 +286,26 @@ public void SerializeLLSDBinary() 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30 }; private static byte[] binaryLongString = (byte[])ConcatenateArrays(binaryHead, binaryLongStringValue); - [Test()] + [Fact] public void DeserializeString() { OSD llsdEmptyString = OSDParser.DeserializeLLSDBinary(binaryEmptyString); - Assert.AreEqual(OSDType.String, llsdEmptyString.Type); + Assert.Equal(OSDType.String, llsdEmptyString.Type); string contentEmptyString = ""; - Assert.AreEqual(contentEmptyString, llsdEmptyString.AsString()); + Assert.Equal(contentEmptyString, llsdEmptyString.AsString()); OSD llsdLongString = OSDParser.DeserializeLLSDBinary(binaryLongString); - Assert.AreEqual(OSDType.String, llsdLongString.Type); + Assert.Equal(OSDType.String, llsdLongString.Type); string contentLongString = "abcdefghijklmnopqrstuvwxyz01234567890"; - Assert.AreEqual(contentLongString, llsdLongString.AsString()); + Assert.Equal(contentLongString, llsdLongString.AsString()); } - [Test()] + [Fact] public void SerializeString() { OSD llsdString = OSD.FromString("abcdefghijklmnopqrstuvwxyz01234567890"); byte[] binaryLongStringSerialized = OSDParser.SerializeLLSDBinary(llsdString); - Assert.AreEqual(binaryLongString, binaryLongStringSerialized); + Assert.Equal(binaryLongString, binaryLongStringSerialized); // A test with some utf8 characters string contentAStringXML = "ƖȔȠȨɆɒ"; @@ -318,8 +318,8 @@ public void SerializeString() OSD llsdAString = OSD.FromString(contentAString); byte[] binaryAString = OSDParser.SerializeLLSDBinary(llsdAString); OSD llsdAStringDS = OSDParser.DeserializeLLSDBinary(binaryAString); - Assert.AreEqual(OSDType.String, llsdAStringDS.Type); - Assert.AreEqual(contentAString, llsdAStringDS.AsString()); + Assert.Equal(OSDType.String, llsdAStringDS.Type); + Assert.Equal(contentAString, llsdAStringDS.AsString()); // we also test for a 4byte character. string xml = "𐄷"; @@ -332,8 +332,8 @@ public void SerializeString() OSD llsdStringOne = OSD.FromString(content); byte[] binaryAStringOneSerialized = OSDParser.SerializeLLSDBinary(llsdStringOne); OSD llsdStringOneDS = OSDParser.DeserializeLLSDBinary(binaryAStringOneSerialized); - Assert.AreEqual(OSDType.String, llsdStringOneDS.Type); - Assert.AreEqual(content, llsdStringOneDS.AsString()); + Assert.Equal(OSDType.String, llsdStringOneDS.Type); + Assert.Equal(content, llsdStringOneDS.AsString()); } @@ -345,22 +345,22 @@ public void SerializeString() 0x65, 0x73, 0x74, 0x75, 0x72, 0x6c, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2f }; private static byte[] binaryURI = (byte[])ConcatenateArrays(binaryHead, binaryURIValue); - [Test()] + [Fact] public void DeserializeURI() { OSD llsdURI = OSDParser.DeserializeLLSDBinary(binaryURI); - Assert.AreEqual(OSDType.URI, llsdURI.Type); + Assert.Equal(OSDType.URI, llsdURI.Type); Uri uri = new Uri("http://www.testurl.test/"); - Assert.AreEqual(uri, llsdURI.AsUri()); + Assert.Equal(uri, llsdURI.AsUri()); } - [Test()] + [Fact] public void SerializeURI() { OSD llsdUri = OSD.FromUri(new Uri("http://www.testurl.test/")); byte[] binaryURISerialized = OSDParser.SerializeLLSDBinary(llsdUri); - Assert.AreEqual(binaryURI, binaryURISerialized); + Assert.Equal(binaryURI, binaryURISerialized); } // Here is a problem. @@ -371,38 +371,38 @@ public void SerializeURI() private static byte[] binaryDateTimeValue = { 100, 0, 0, 192, 141, 167, 222, 209, 65 }; private static byte[] binaryDateTime = (byte[])ConcatenateArrays(binaryHead, binaryDateTimeValue); - [Test()] + [Fact] public void DeserializeDateTime() { OSD llsdDateTime = OSDParser.DeserializeLLSDBinary(binaryDateTime); - Assert.AreEqual(OSDType.Date, llsdDateTime.Type); + Assert.Equal(OSDType.Date, llsdDateTime.Type); DateTime dt = new DateTime(2008, 1, 1, 20, 10, 31, 0, DateTimeKind.Utc); DateTime dateLocal = llsdDateTime.AsDate(); - Assert.AreEqual(dt, dateLocal.ToUniversalTime()); + Assert.Equal(dt, dateLocal.ToUniversalTime()); } - [Test()] + [Fact] public void SerializeDateTime() { DateTime dt = new DateTime(2008, 1, 1, 20, 10, 31, 0, DateTimeKind.Utc); OSD llsdDate = OSD.FromDate(dt); byte[] binaryDateSerialized = OSDParser.SerializeLLSDBinary(llsdDate); - Assert.AreEqual(binaryDateTime, binaryDateSerialized); + Assert.Equal(binaryDateTime, binaryDateSerialized); // check if a *local* time can be serialized and deserialized DateTime dtOne = new DateTime(2009, 12, 30, 8, 25, 10, DateTimeKind.Local); OSD llsdDateOne = OSD.FromDate(dtOne); byte[] binaryDateOneSerialized = OSDParser.SerializeLLSDBinary(llsdDateOne); OSD llsdDateOneDS = OSDParser.DeserializeLLSDBinary(binaryDateOneSerialized); - Assert.AreEqual(OSDType.Date, llsdDateOneDS.Type); - Assert.AreEqual(dtOne, llsdDateOneDS.AsDate()); + Assert.Equal(OSDType.Date, llsdDateOneDS.Type); + Assert.Equal(dtOne, llsdDateOneDS.AsDate()); DateTime dtTwo = new DateTime(2010, 11, 11, 10, 8, 20, DateTimeKind.Utc); OSD llsdDateTwo = OSD.FromDate(dtTwo); byte[] binaryDateTwoSerialized = OSDParser.SerializeLLSDBinary(llsdDateTwo); OSD llsdDateTwoDS = OSDParser.DeserializeLLSDBinary(binaryDateTwoSerialized); - Assert.AreEqual(OSDType.Date, llsdDateOneDS.Type); - Assert.AreEqual(dtTwo.ToLocalTime(), llsdDateTwoDS.AsDate()); + Assert.Equal(OSDType.Date, llsdDateOneDS.Type); + Assert.Equal(dtTwo.ToLocalTime(), llsdDateTwoDS.AsDate()); } // Data for empty array { } @@ -420,59 +420,59 @@ public void SerializeDateTime() 0x69, 0x0, 0x0, 0x0, 0x0, 0x5d }; private static byte[] binarySimpleArrayTwo = (byte[])ConcatenateArrays(binaryHead, binarySimpleArrayTwoValue); - [Test()] + [Fact] public void DeserializeArray() { OSD llsdEmptyArray = OSDParser.DeserializeLLSDBinary(binaryEmptyArray); - Assert.AreEqual(OSDType.Array, llsdEmptyArray.Type); + Assert.Equal(OSDType.Array, llsdEmptyArray.Type); OSDArray llsdEmptyArrayArray = (OSDArray)llsdEmptyArray; - Assert.AreEqual(0, llsdEmptyArrayArray.Count); + Assert.Equal(0, llsdEmptyArrayArray.Count); OSD llsdSimpleArray = OSDParser.DeserializeLLSDBinary(binarySimpleArray); - Assert.AreEqual(OSDType.Array, llsdSimpleArray.Type); + Assert.Equal(OSDType.Array, llsdSimpleArray.Type); OSDArray llsdArray = (OSDArray)llsdSimpleArray; - Assert.AreEqual(OSDType.Integer, llsdArray[0].Type); - Assert.AreEqual(0, llsdArray[0].AsInteger()); + Assert.Equal(OSDType.Integer, llsdArray[0].Type); + Assert.Equal(0, llsdArray[0].AsInteger()); OSD llsdSimpleArrayTwo = OSDParser.DeserializeLLSDBinary(binarySimpleArrayTwo); - Assert.AreEqual(OSDType.Array, llsdSimpleArrayTwo.Type); + Assert.Equal(OSDType.Array, llsdSimpleArrayTwo.Type); OSDArray llsdArrayTwo = (OSDArray)llsdSimpleArrayTwo; - Assert.AreEqual(2, llsdArrayTwo.Count); + Assert.Equal(2, llsdArrayTwo.Count); - Assert.AreEqual(OSDType.Integer, llsdArrayTwo[0].Type); - Assert.AreEqual(0, llsdArrayTwo[0].AsInteger()); - Assert.AreEqual(OSDType.Integer, llsdArrayTwo[1].Type); - Assert.AreEqual(0, llsdArrayTwo[1].AsInteger()); + Assert.Equal(OSDType.Integer, llsdArrayTwo[0].Type); + Assert.Equal(0, llsdArrayTwo[0].AsInteger()); + Assert.Equal(OSDType.Integer, llsdArrayTwo[1].Type); + Assert.Equal(0, llsdArrayTwo[1].AsInteger()); } - [Test()] + [Fact] public void SerializeArray() { OSDArray llsdEmptyArray = new OSDArray(); byte[] binaryEmptyArraySerialized = OSDParser.SerializeLLSDBinary(llsdEmptyArray); - Assert.AreEqual(binaryEmptyArray, binaryEmptyArraySerialized); + Assert.Equal(binaryEmptyArray, binaryEmptyArraySerialized); binaryEmptyArraySerialized = OSDParser.SerializeLLSDBinary(llsdEmptyArray, false); - Assert.AreEqual(binaryEmptyArrayValue, binaryEmptyArraySerialized); + Assert.Equal(binaryEmptyArrayValue, binaryEmptyArraySerialized); OSDArray llsdSimpleArray = new OSDArray(); llsdSimpleArray.Add(OSD.FromInteger(0)); byte[] binarySimpleArraySerialized = OSDParser.SerializeLLSDBinary(llsdSimpleArray); - Assert.AreEqual(binarySimpleArray, binarySimpleArraySerialized); + Assert.Equal(binarySimpleArray, binarySimpleArraySerialized); binarySimpleArraySerialized = OSDParser.SerializeLLSDBinary(llsdSimpleArray, false); - Assert.AreEqual(binarySimpleArrayValue, binarySimpleArraySerialized); + Assert.Equal(binarySimpleArrayValue, binarySimpleArraySerialized); OSDArray llsdSimpleArrayTwo = new OSDArray(); llsdSimpleArrayTwo.Add(OSD.FromInteger(0)); llsdSimpleArrayTwo.Add(OSD.FromInteger(0)); byte[] binarySimpleArrayTwoSerialized = OSDParser.SerializeLLSDBinary(llsdSimpleArrayTwo); - Assert.AreEqual(binarySimpleArrayTwo, binarySimpleArrayTwoSerialized); + Assert.Equal(binarySimpleArrayTwo, binarySimpleArrayTwoSerialized); binarySimpleArrayTwoSerialized = OSDParser.SerializeLLSDBinary(llsdSimpleArrayTwo, false); - Assert.AreEqual(binarySimpleArrayTwoValue, binarySimpleArrayTwoSerialized); + Assert.Equal(binarySimpleArrayTwoValue, binarySimpleArrayTwoSerialized); } // Data for empty dictionary { } @@ -502,42 +502,42 @@ public void SerializeArray() 0x7d }; private static byte[] binarySimpleMapTwo = (byte[])ConcatenateArrays(binaryHead, binarySimpleMapTwoValue); - [Test()] + [Fact] public void DeserializeDictionary() { OSDMap llsdEmptyMap = (OSDMap)OSDParser.DeserializeLLSDBinary(binaryEmptyMap); - Assert.AreEqual(OSDType.Map, llsdEmptyMap.Type); - Assert.AreEqual(0, llsdEmptyMap.Count); + Assert.Equal(OSDType.Map, llsdEmptyMap.Type); + Assert.Equal(0, llsdEmptyMap.Count); OSDMap llsdSimpleMap = (OSDMap)OSDParser.DeserializeLLSDBinary(binarySimpleMap); - Assert.AreEqual(OSDType.Map, llsdSimpleMap.Type); - Assert.AreEqual(1, llsdSimpleMap.Count); - Assert.AreEqual(OSDType.Integer, llsdSimpleMap["test"].Type); - Assert.AreEqual(0, llsdSimpleMap["test"].AsInteger()); + Assert.Equal(OSDType.Map, llsdSimpleMap.Type); + Assert.Equal(1, llsdSimpleMap.Count); + Assert.Equal(OSDType.Integer, llsdSimpleMap["test"].Type); + Assert.Equal(0, llsdSimpleMap["test"].AsInteger()); OSDMap llsdSimpleMapTwo = (OSDMap)OSDParser.DeserializeLLSDBinary(binarySimpleMapTwo); - Assert.AreEqual(OSDType.Map, llsdSimpleMapTwo.Type); - Assert.AreEqual(3, llsdSimpleMapTwo.Count); - Assert.AreEqual(OSDType.Unknown, llsdSimpleMapTwo["test"].Type); - Assert.AreEqual(OSDType.String, llsdSimpleMapTwo["tes1"].Type); - Assert.AreEqual("aha", llsdSimpleMapTwo["tes1"].AsString()); - Assert.AreEqual(OSDType.Integer, llsdSimpleMapTwo["t0st"].Type); - Assert.AreEqual(241, llsdSimpleMapTwo["t0st"].AsInteger()); + Assert.Equal(OSDType.Map, llsdSimpleMapTwo.Type); + Assert.Equal(3, llsdSimpleMapTwo.Count); + Assert.Equal(OSDType.Unknown, llsdSimpleMapTwo["test"].Type); + Assert.Equal(OSDType.String, llsdSimpleMapTwo["tes1"].Type); + Assert.Equal("aha", llsdSimpleMapTwo["tes1"].AsString()); + Assert.Equal(OSDType.Integer, llsdSimpleMapTwo["t0st"].Type); + Assert.Equal(241, llsdSimpleMapTwo["t0st"].AsInteger()); } - [Test()] + [Fact] public void SerializeDictionary() { OSDMap llsdEmptyMap = new OSDMap(); byte[] binaryEmptyMapSerialized = OSDParser.SerializeLLSDBinary(llsdEmptyMap); - Assert.AreEqual(binaryEmptyMap, binaryEmptyMapSerialized); + Assert.Equal(binaryEmptyMap, binaryEmptyMapSerialized); OSDMap llsdSimpleMap = new OSDMap(); llsdSimpleMap["test"] = OSD.FromInteger(0); byte[] binarySimpleMapSerialized = OSDParser.SerializeLLSDBinary(llsdSimpleMap); - Assert.AreEqual(binarySimpleMap, binarySimpleMapSerialized); + Assert.Equal(binarySimpleMap, binarySimpleMapSerialized); OSDMap llsdSimpleMapTwo = new OSDMap(); llsdSimpleMapTwo["t0st"] = OSD.FromInteger(241); @@ -549,13 +549,13 @@ public void SerializeDictionary() // the original serialized value is not *exactly* the same. Instead we compare to a deserialized // version created by this deserializer. OSDMap llsdSimpleMapDeserialized = (OSDMap)OSDParser.DeserializeLLSDBinary(binarySimpleMapTwoSerialized); - Assert.AreEqual(OSDType.Map, llsdSimpleMapDeserialized.Type); - Assert.AreEqual(3, llsdSimpleMapDeserialized.Count); - Assert.AreEqual(OSDType.Integer, llsdSimpleMapDeserialized["t0st"].Type); - Assert.AreEqual(241, llsdSimpleMapDeserialized["t0st"].AsInteger()); - Assert.AreEqual(OSDType.String, llsdSimpleMapDeserialized["tes1"].Type); - Assert.AreEqual("aha", llsdSimpleMapDeserialized["tes1"].AsString()); - Assert.AreEqual(OSDType.Unknown, llsdSimpleMapDeserialized["test"].Type); + Assert.Equal(OSDType.Map, llsdSimpleMapDeserialized.Type); + Assert.Equal(3, llsdSimpleMapDeserialized.Count); + Assert.Equal(OSDType.Integer, llsdSimpleMapDeserialized["t0st"].Type); + Assert.Equal(241, llsdSimpleMapDeserialized["t0st"].AsInteger()); + Assert.Equal(OSDType.String, llsdSimpleMapDeserialized["tes1"].Type); + Assert.Equal("aha", llsdSimpleMapDeserialized["tes1"].AsString()); + Assert.Equal(OSDType.Unknown, llsdSimpleMapDeserialized["test"].Type); // we also test for a 4byte key character. string xml = "𐄷"; @@ -568,13 +568,13 @@ public void SerializeDictionary() OSDMap llsdSimpleMapThree = new OSDMap(); OSD llsdSimpleValue = OSD.FromString(content); llsdSimpleMapThree[content] = llsdSimpleValue; - Assert.AreEqual(content, llsdSimpleMapThree[content].AsString()); + Assert.Equal(content, llsdSimpleMapThree[content].AsString()); byte[] binarySimpleMapThree = OSDParser.SerializeLLSDBinary(llsdSimpleMapThree); OSDMap llsdSimpleMapThreeDS = (OSDMap)OSDParser.DeserializeLLSDBinary(binarySimpleMapThree); - Assert.AreEqual(OSDType.Map, llsdSimpleMapThreeDS.Type); - Assert.AreEqual(1, llsdSimpleMapThreeDS.Count); - Assert.AreEqual(content, llsdSimpleMapThreeDS[content].AsString()); + Assert.Equal(OSDType.Map, llsdSimpleMapThreeDS.Type); + Assert.Equal(1, llsdSimpleMapThreeDS.Count); + Assert.Equal(content, llsdSimpleMapThreeDS[content].AsString()); } @@ -594,41 +594,41 @@ public void SerializeDictionary() 0x5d }; private static byte[] binaryNested = (byte[])ConcatenateArrays(binaryHead, binaryNestedValue); - [Test()] + [Fact] public void DeserializeNestedComposite() { OSD llsdNested = OSDParser.DeserializeLLSDBinary(binaryNested); - Assert.AreEqual(OSDType.Array, llsdNested.Type); + Assert.Equal(OSDType.Array, llsdNested.Type); OSDArray llsdArray = (OSDArray)llsdNested; - Assert.AreEqual(3, llsdArray.Count); + Assert.Equal(3, llsdArray.Count); OSDMap llsdMap = (OSDMap)llsdArray[0]; - Assert.AreEqual(OSDType.Map, llsdMap.Type); - Assert.AreEqual(2, llsdMap.Count); + Assert.Equal(OSDType.Map, llsdMap.Type); + Assert.Equal(2, llsdMap.Count); OSDArray llsdNestedArray = (OSDArray)llsdMap["t0st"]; - Assert.AreEqual(OSDType.Array, llsdNestedArray.Type); + Assert.Equal(OSDType.Array, llsdNestedArray.Type); OSDInteger llsdNestedIntOne = (OSDInteger)llsdNestedArray[0]; - Assert.AreEqual(OSDType.Integer, llsdNestedIntOne.Type); - Assert.AreEqual(1, llsdNestedIntOne.AsInteger()); + Assert.Equal(OSDType.Integer, llsdNestedIntOne.Type); + Assert.Equal(1, llsdNestedIntOne.AsInteger()); OSDInteger llsdNestedIntTwo = (OSDInteger)llsdNestedArray[1]; - Assert.AreEqual(OSDType.Integer, llsdNestedIntTwo.Type); - Assert.AreEqual(2, llsdNestedIntTwo.AsInteger()); + Assert.Equal(OSDType.Integer, llsdNestedIntTwo.Type); + Assert.Equal(2, llsdNestedIntTwo.AsInteger()); OSDString llsdString = (OSDString)llsdMap["test"]; - Assert.AreEqual(OSDType.String, llsdString.Type); - Assert.AreEqual("what", llsdString.AsString()); + Assert.Equal(OSDType.String, llsdString.Type); + Assert.Equal("what", llsdString.AsString()); OSDInteger llsdIntOne = (OSDInteger)llsdArray[1]; - Assert.AreEqual(OSDType.Integer, llsdIntOne.Type); - Assert.AreEqual(124, llsdIntOne.AsInteger()); + Assert.Equal(OSDType.Integer, llsdIntOne.Type); + Assert.Equal(124, llsdIntOne.AsInteger()); OSDInteger llsdIntTwo = (OSDInteger)llsdArray[2]; - Assert.AreEqual(OSDType.Integer, llsdIntTwo.Type); - Assert.AreEqual(987, llsdIntTwo.AsInteger()); + Assert.Equal(OSDType.Integer, llsdIntTwo.Type); + Assert.Equal(987, llsdIntTwo.AsInteger()); } - [Test()] + [Fact] public void SerializeNestedComposite() { OSDArray llsdNested = new OSDArray(); @@ -645,34 +645,34 @@ public void SerializeNestedComposite() byte[] binaryNestedSerialized = OSDParser.SerializeLLSDBinary(llsdNested); // Because maps don't preserve order, we compare here to a deserialized value. OSDArray llsdNestedDeserialized = (OSDArray)OSDParser.DeserializeLLSDBinary(binaryNestedSerialized); - Assert.AreEqual(OSDType.Array, llsdNestedDeserialized.Type); - Assert.AreEqual(3, llsdNestedDeserialized.Count); + Assert.Equal(OSDType.Array, llsdNestedDeserialized.Type); + Assert.Equal(3, llsdNestedDeserialized.Count); OSDMap llsdMapDeserialized = (OSDMap)llsdNestedDeserialized[0]; - Assert.AreEqual(OSDType.Map, llsdMapDeserialized.Type); - Assert.AreEqual(2, llsdMapDeserialized.Count); - Assert.AreEqual(OSDType.Array, llsdMapDeserialized["t0st"].Type); + Assert.Equal(OSDType.Map, llsdMapDeserialized.Type); + Assert.Equal(2, llsdMapDeserialized.Count); + Assert.Equal(OSDType.Array, llsdMapDeserialized["t0st"].Type); OSDArray llsdNestedArray = (OSDArray)llsdMapDeserialized["t0st"]; - Assert.AreEqual(OSDType.Array, llsdNestedArray.Type); - Assert.AreEqual(2, llsdNestedArray.Count); - Assert.AreEqual(OSDType.Integer, llsdNestedArray[0].Type); - Assert.AreEqual(1, llsdNestedArray[0].AsInteger()); - Assert.AreEqual(OSDType.Integer, llsdNestedArray[1].Type); - Assert.AreEqual(2, llsdNestedArray[1].AsInteger()); + Assert.Equal(OSDType.Array, llsdNestedArray.Type); + Assert.Equal(2, llsdNestedArray.Count); + Assert.Equal(OSDType.Integer, llsdNestedArray[0].Type); + Assert.Equal(1, llsdNestedArray[0].AsInteger()); + Assert.Equal(OSDType.Integer, llsdNestedArray[1].Type); + Assert.Equal(2, llsdNestedArray[1].AsInteger()); - Assert.AreEqual(OSDType.String, llsdMapDeserialized["test"].Type); - Assert.AreEqual("what", llsdMapDeserialized["test"].AsString()); + Assert.Equal(OSDType.String, llsdMapDeserialized["test"].Type); + Assert.Equal("what", llsdMapDeserialized["test"].AsString()); - Assert.AreEqual(OSDType.Integer, llsdNestedDeserialized[1].Type); - Assert.AreEqual(124, llsdNestedDeserialized[1].AsInteger()); + Assert.Equal(OSDType.Integer, llsdNestedDeserialized[1].Type); + Assert.Equal(124, llsdNestedDeserialized[1].AsInteger()); - Assert.AreEqual(OSDType.Integer, llsdNestedDeserialized[2].Type); - Assert.AreEqual(987, llsdNestedDeserialized[2].AsInteger()); + Assert.Equal(OSDType.Integer, llsdNestedDeserialized[2].Type); + Assert.Equal(987, llsdNestedDeserialized[2].AsInteger()); } - [Test()] + [Fact] public void SerializeLongMessage() { // each 80 chars @@ -698,18 +698,18 @@ public void SerializeLongMessage() byte[] binaryData = OSDParser.SerializeLLSDBinary(llsdMap); OSDMap llsdMapDS = (OSDMap)OSDParser.DeserializeLLSDBinary(binaryData); - Assert.AreEqual(OSDType.Map, llsdMapDS.Type); - Assert.AreEqual(10, llsdMapDS.Count); - Assert.AreEqual(sOne, llsdMapDS["testOne"].AsString()); - Assert.AreEqual(sTwo, llsdMapDS["testTwo"].AsString()); - Assert.AreEqual(sOne, llsdMapDS["testThree"].AsString()); - Assert.AreEqual(sTwo, llsdMapDS["testFour"].AsString()); - Assert.AreEqual(sOne, llsdMapDS["testFive"].AsString()); - Assert.AreEqual(sTwo, llsdMapDS["testSix"].AsString()); - Assert.AreEqual(sOne, llsdMapDS["testSeven"].AsString()); - Assert.AreEqual(sTwo, llsdMapDS["testEight"].AsString()); - Assert.AreEqual(sOne, llsdMapDS["testNine"].AsString()); - Assert.AreEqual(sTwo, llsdMapDS["testTen"].AsString()); + Assert.Equal(OSDType.Map, llsdMapDS.Type); + Assert.Equal(10, llsdMapDS.Count); + Assert.Equal(sOne, llsdMapDS["testOne"].AsString()); + Assert.Equal(sTwo, llsdMapDS["testTwo"].AsString()); + Assert.Equal(sOne, llsdMapDS["testThree"].AsString()); + Assert.Equal(sTwo, llsdMapDS["testFour"].AsString()); + Assert.Equal(sOne, llsdMapDS["testFive"].AsString()); + Assert.Equal(sTwo, llsdMapDS["testSix"].AsString()); + Assert.Equal(sOne, llsdMapDS["testSeven"].AsString()); + Assert.Equal(sTwo, llsdMapDS["testEight"].AsString()); + Assert.Equal(sOne, llsdMapDS["testNine"].AsString()); + Assert.Equal(sTwo, llsdMapDS["testTen"].AsString()); } diff --git a/OpenMetaverse.Tests/MessageTests.cs b/OpenMetaverse.Tests/MessageTests.cs index f9dd0eed..83dac3f8 100644 --- a/OpenMetaverse.Tests/MessageTests.cs +++ b/OpenMetaverse.Tests/MessageTests.cs @@ -24,7 +24,9 @@ * POSSIBILITY OF SUCH DAMAGE. */ -using NUnit.Framework; +using Xunit; +using MessagePack; +using MessagePack.Resolvers; using OpenMetaverse.Messages.Linden; using OpenMetaverse.StructuredData; using System; @@ -40,14 +42,17 @@ namespace OpenMetaverse.Tests /// a passed test does not necessarily indicate the formatting is correct in the resulting OSD to be handled /// by the simulator. /// - [TestFixture] - public class MessageTests : Assert + + public class MessageTests { + private static readonly MessagePackSerializerOptions BenchmarkMessagePackOptions = + MessagePackSerializerOptions.Standard.WithResolver(TypelessContractlessStandardResolver.Instance); + private Uri testURI = new Uri("https://sim3187.agni.lindenlab.com:12043/cap/6028fc44-c1e5-80a1-f902-19bde114458b"); private IPAddress testIP = IPAddress.Parse("127.0.0.1"); private ulong testHandle = 1106108697797888; - [Test] + [Fact] public void AgentGroupDataUpdateMessage() { AgentGroupDataUpdateMessage s = new AgentGroupDataUpdateMessage(); @@ -94,25 +99,25 @@ public void AgentGroupDataUpdateMessage() AgentGroupDataUpdateMessage t = new AgentGroupDataUpdateMessage(); t.Deserialize(map); - Assert.AreEqual(s.AgentID, t.AgentID); + Assert.Equal(s.AgentID, t.AgentID); for (int i = 0; i < t.GroupDataBlock.Length; i++) { - Assert.AreEqual(s.GroupDataBlock[i].AcceptNotices, t.GroupDataBlock[i].AcceptNotices); - Assert.AreEqual(s.GroupDataBlock[i].Contribution, t.GroupDataBlock[i].Contribution); - Assert.AreEqual(s.GroupDataBlock[i].GroupID, t.GroupDataBlock[i].GroupID); - Assert.AreEqual(s.GroupDataBlock[i].GroupInsigniaID, t.GroupDataBlock[i].GroupInsigniaID); - Assert.AreEqual(s.GroupDataBlock[i].GroupName, t.GroupDataBlock[i].GroupName); - Assert.AreEqual(s.GroupDataBlock[i].GroupPowers, t.GroupDataBlock[i].GroupPowers); + Assert.Equal(s.GroupDataBlock[i].AcceptNotices, t.GroupDataBlock[i].AcceptNotices); + Assert.Equal(s.GroupDataBlock[i].Contribution, t.GroupDataBlock[i].Contribution); + Assert.Equal(s.GroupDataBlock[i].GroupID, t.GroupDataBlock[i].GroupID); + Assert.Equal(s.GroupDataBlock[i].GroupInsigniaID, t.GroupDataBlock[i].GroupInsigniaID); + Assert.Equal(s.GroupDataBlock[i].GroupName, t.GroupDataBlock[i].GroupName); + Assert.Equal(s.GroupDataBlock[i].GroupPowers, t.GroupDataBlock[i].GroupPowers); } for (int i = 0; i < t.NewGroupDataBlock.Length; i++) { - Assert.AreEqual(s.NewGroupDataBlock[i].ListInProfile, t.NewGroupDataBlock[i].ListInProfile); + Assert.Equal(s.NewGroupDataBlock[i].ListInProfile, t.NewGroupDataBlock[i].ListInProfile); } } - [Test] + [Fact] public void TeleportFinishMessage() { TeleportFinishMessage s = new TeleportFinishMessage(); @@ -130,17 +135,17 @@ public void TeleportFinishMessage() TeleportFinishMessage t = new TeleportFinishMessage(); t.Deserialize(map); - Assert.AreEqual(s.AgentID, t.AgentID); - Assert.AreEqual(s.Flags, t.Flags); - Assert.AreEqual(s.IP, t.IP); - Assert.AreEqual(s.LocationID, t.LocationID); - Assert.AreEqual(s.Port, t.Port); - Assert.AreEqual(s.RegionHandle, t.RegionHandle); - Assert.AreEqual(s.SeedCapability, t.SeedCapability); - Assert.AreEqual(s.SimAccess, t.SimAccess); + Assert.Equal(s.AgentID, t.AgentID); + Assert.Equal(s.Flags, t.Flags); + Assert.Equal(s.IP, t.IP); + Assert.Equal(s.LocationID, t.LocationID); + Assert.Equal(s.Port, t.Port); + Assert.Equal(s.RegionHandle, t.RegionHandle); + Assert.Equal(s.SeedCapability, t.SeedCapability); + Assert.Equal(s.SimAccess, t.SimAccess); } - [Test] + [Fact] public void EstablishAgentCommunicationMessage() { EstablishAgentCommunicationMessage s = new EstablishAgentCommunicationMessage(); @@ -154,13 +159,13 @@ public void EstablishAgentCommunicationMessage() EstablishAgentCommunicationMessage t = new EstablishAgentCommunicationMessage(); t.Deserialize(map); - Assert.AreEqual(s.Address, t.Address); - Assert.AreEqual(s.AgentID, t.AgentID); - Assert.AreEqual(s.Port, t.Port); - Assert.AreEqual(s.SeedCapability, t.SeedCapability); + Assert.Equal(s.Address, t.Address); + Assert.Equal(s.AgentID, t.AgentID); + Assert.Equal(s.Port, t.Port); + Assert.Equal(s.SeedCapability, t.SeedCapability); } - [Test] + [Fact] public void ParcelObjectOwnersMessage() { ParcelObjectOwnersReplyMessage s = new ParcelObjectOwnersReplyMessage(); @@ -189,15 +194,15 @@ public void ParcelObjectOwnersMessage() for (int i = 0; i < t.PrimOwnersBlock.Length; i++) { - Assert.AreEqual(s.PrimOwnersBlock[i].Count, t.PrimOwnersBlock[i].Count); - Assert.AreEqual(s.PrimOwnersBlock[i].IsGroupOwned, t.PrimOwnersBlock[i].IsGroupOwned); - Assert.AreEqual(s.PrimOwnersBlock[i].OnlineStatus, t.PrimOwnersBlock[i].OnlineStatus); - Assert.AreEqual(s.PrimOwnersBlock[i].OwnerID, t.PrimOwnersBlock[i].OwnerID); - Assert.AreEqual(s.PrimOwnersBlock[i].TimeStamp, t.PrimOwnersBlock[i].TimeStamp); + Assert.Equal(s.PrimOwnersBlock[i].Count, t.PrimOwnersBlock[i].Count); + Assert.Equal(s.PrimOwnersBlock[i].IsGroupOwned, t.PrimOwnersBlock[i].IsGroupOwned); + Assert.Equal(s.PrimOwnersBlock[i].OnlineStatus, t.PrimOwnersBlock[i].OnlineStatus); + Assert.Equal(s.PrimOwnersBlock[i].OwnerID, t.PrimOwnersBlock[i].OwnerID); + Assert.Equal(s.PrimOwnersBlock[i].TimeStamp, t.PrimOwnersBlock[i].TimeStamp); } } - [Test] + [Fact] public void ChatterBoxInvitationMessage() { ChatterBoxInvitationMessage s = new ChatterBoxInvitationMessage(); @@ -220,22 +225,22 @@ public void ChatterBoxInvitationMessage() ChatterBoxInvitationMessage t = new ChatterBoxInvitationMessage(); t.Deserialize(map); - Assert.AreEqual(s.BinaryBucket, t.BinaryBucket); - Assert.AreEqual(s.Dialog, t.Dialog); - Assert.AreEqual(s.FromAgentID, t.FromAgentID); - Assert.AreEqual(s.FromAgentName, t.FromAgentName); - Assert.AreEqual(s.GroupIM, t.GroupIM); - Assert.AreEqual(s.IMSessionID, t.IMSessionID); - Assert.AreEqual(s.Message, t.Message); - Assert.AreEqual(s.Offline, t.Offline); - Assert.AreEqual(s.ParentEstateID, t.ParentEstateID); - Assert.AreEqual(s.Position, t.Position); - Assert.AreEqual(s.RegionID, t.RegionID); - Assert.AreEqual(s.Timestamp, t.Timestamp); - Assert.AreEqual(s.ToAgentID, t.ToAgentID); + Assert.Equal(s.BinaryBucket, t.BinaryBucket); + Assert.Equal(s.Dialog, t.Dialog); + Assert.Equal(s.FromAgentID, t.FromAgentID); + Assert.Equal(s.FromAgentName, t.FromAgentName); + Assert.Equal(s.GroupIM, t.GroupIM); + Assert.Equal(s.IMSessionID, t.IMSessionID); + Assert.Equal(s.Message, t.Message); + Assert.Equal(s.Offline, t.Offline); + Assert.Equal(s.ParentEstateID, t.ParentEstateID); + Assert.Equal(s.Position, t.Position); + Assert.Equal(s.RegionID, t.RegionID); + Assert.Equal(s.Timestamp, t.Timestamp); + Assert.Equal(s.ToAgentID, t.ToAgentID); } - [Test] + [Fact] public void ChatterboxSessionEventReplyMessage() { ChatterboxSessionEventReplyMessage s = new ChatterboxSessionEventReplyMessage(); @@ -247,11 +252,11 @@ public void ChatterboxSessionEventReplyMessage() ChatterboxSessionEventReplyMessage t = new ChatterboxSessionEventReplyMessage(); t.Deserialize(map); - Assert.AreEqual(s.SessionID, t.SessionID); - Assert.AreEqual(s.Success, t.Success); + Assert.Equal(s.SessionID, t.SessionID); + Assert.Equal(s.Success, t.Success); } - [Test] + [Fact] public void ChatterBoxSessionStartReplyMessage() { ChatterBoxSessionStartReplyMessage s = new ChatterBoxSessionStartReplyMessage(); @@ -268,16 +273,16 @@ public void ChatterBoxSessionStartReplyMessage() ChatterBoxSessionStartReplyMessage t = new ChatterBoxSessionStartReplyMessage(); t.Deserialize(map); - Assert.AreEqual(s.ModeratedVoice, t.ModeratedVoice); - Assert.AreEqual(s.SessionID, t.SessionID); - Assert.AreEqual(s.SessionName, t.SessionName); - Assert.AreEqual(s.Success, t.Success); - Assert.AreEqual(s.TempSessionID, t.TempSessionID); - Assert.AreEqual(s.Type, t.Type); - Assert.AreEqual(s.VoiceEnabled, t.VoiceEnabled); + Assert.Equal(s.ModeratedVoice, t.ModeratedVoice); + Assert.Equal(s.SessionID, t.SessionID); + Assert.Equal(s.SessionName, t.SessionName); + Assert.Equal(s.Success, t.Success); + Assert.Equal(s.TempSessionID, t.TempSessionID); + Assert.Equal(s.Type, t.Type); + Assert.Equal(s.VoiceEnabled, t.VoiceEnabled); } - [Test] + [Fact] public void ChatterBoxSessionAgentListUpdatesMessage() { ChatterBoxSessionAgentListUpdatesMessage s = new ChatterBoxSessionAgentListUpdatesMessage(); @@ -308,19 +313,19 @@ public void ChatterBoxSessionAgentListUpdatesMessage() ChatterBoxSessionAgentListUpdatesMessage t = new ChatterBoxSessionAgentListUpdatesMessage(); t.Deserialize(map); - Assert.AreEqual(s.SessionID, t.SessionID); + Assert.Equal(s.SessionID, t.SessionID); for (int i = 0; i < t.Updates.Length; i++) { - Assert.AreEqual(s.Updates[i].AgentID, t.Updates[i].AgentID); - Assert.AreEqual(s.Updates[i].CanVoiceChat, t.Updates[i].CanVoiceChat); - Assert.AreEqual(s.Updates[i].IsModerator, t.Updates[i].IsModerator); - Assert.AreEqual(s.Updates[i].MuteText, t.Updates[i].MuteText); - Assert.AreEqual(s.Updates[i].MuteVoice, t.Updates[i].MuteVoice); - Assert.AreEqual(s.Updates[i].Transition, t.Updates[i].Transition); + Assert.Equal(s.Updates[i].AgentID, t.Updates[i].AgentID); + Assert.Equal(s.Updates[i].CanVoiceChat, t.Updates[i].CanVoiceChat); + Assert.Equal(s.Updates[i].IsModerator, t.Updates[i].IsModerator); + Assert.Equal(s.Updates[i].MuteText, t.Updates[i].MuteText); + Assert.Equal(s.Updates[i].MuteVoice, t.Updates[i].MuteVoice); + Assert.Equal(s.Updates[i].Transition, t.Updates[i].Transition); } } - [Test] + [Fact] public void ViewerStatsMessage() { ViewerStatsMessage s = new ViewerStatsMessage(); @@ -371,52 +376,52 @@ public void ViewerStatsMessage() ViewerStatsMessage t = new ViewerStatsMessage(); t.Deserialize(map); - Assert.AreEqual(s.AgentFPS, t.AgentFPS); - Assert.AreEqual(s.AgentsInView, t.AgentsInView); - Assert.AreEqual(s.SystemCPU, t.SystemCPU); - Assert.AreEqual(s.StatsDropped, t.StatsDropped); - Assert.AreEqual(s.StatsFailedResends, t.StatsFailedResends); - Assert.AreEqual(s.SystemGPU, t.SystemGPU); - Assert.AreEqual(s.SystemGPUClass, t.SystemGPUClass); - Assert.AreEqual(s.SystemGPUVendor, t.SystemGPUVendor); - Assert.AreEqual(s.SystemGPUVersion, t.SystemGPUVersion); - Assert.AreEqual(s.InCompressedPackets, t.InCompressedPackets); - Assert.AreEqual(s.InKbytes, t.InKbytes); - Assert.AreEqual(s.InPackets, t.InPackets); - Assert.AreEqual(s.InSavings, t.InSavings); - Assert.AreEqual(s.MiscInt1, t.MiscInt1); - Assert.AreEqual(s.MiscInt2, t.MiscInt2); - Assert.AreEqual(s.FailuresInvalid, t.FailuresInvalid); - Assert.AreEqual(s.AgentLanguage, t.AgentLanguage); - Assert.AreEqual(s.AgentMemoryUsed, t.AgentMemoryUsed); - Assert.AreEqual(s.MetersTraveled, t.MetersTraveled); - Assert.AreEqual(s.object_kbytes, t.object_kbytes); - Assert.AreEqual(s.FailuresOffCircuit, t.FailuresOffCircuit); - Assert.AreEqual(s.SystemOS, t.SystemOS); - Assert.AreEqual(s.OutCompressedPackets, t.OutCompressedPackets); - Assert.AreEqual(s.OutKbytes, t.OutKbytes); - Assert.AreEqual(s.OutPackets, t.OutPackets); - Assert.AreEqual(s.OutSavings, t.OutSavings); - Assert.AreEqual(s.AgentPing, t.AgentPing); - Assert.AreEqual(s.SystemInstalledRam, t.SystemInstalledRam); - Assert.AreEqual(s.RegionsVisited, t.RegionsVisited); - Assert.AreEqual(s.FailuresResent, t.FailuresResent); - Assert.AreEqual(s.AgentRuntime, t.AgentRuntime); - Assert.AreEqual(s.FailuresSendPacket, t.FailuresSendPacket); - Assert.AreEqual(s.SessionID, t.SessionID); - Assert.AreEqual(s.SimulatorFPS, t.SimulatorFPS); - Assert.AreEqual(s.AgentStartTime, t.AgentStartTime); - Assert.AreEqual(s.MiscString1, t.MiscString1); - Assert.AreEqual(s.texture_kbytes, t.texture_kbytes); - Assert.AreEqual(s.AgentVersion, t.AgentVersion); - Assert.AreEqual(s.MiscVersion, t.MiscVersion); - Assert.AreEqual(s.VertexBuffersEnabled, t.VertexBuffersEnabled); - Assert.AreEqual(s.world_kbytes, t.world_kbytes); + Assert.Equal(s.AgentFPS, t.AgentFPS); + Assert.Equal(s.AgentsInView, t.AgentsInView); + Assert.Equal(s.SystemCPU, t.SystemCPU); + Assert.Equal(s.StatsDropped, t.StatsDropped); + Assert.Equal(s.StatsFailedResends, t.StatsFailedResends); + Assert.Equal(s.SystemGPU, t.SystemGPU); + Assert.Equal(s.SystemGPUClass, t.SystemGPUClass); + Assert.Equal(s.SystemGPUVendor, t.SystemGPUVendor); + Assert.Equal(s.SystemGPUVersion, t.SystemGPUVersion); + Assert.Equal(s.InCompressedPackets, t.InCompressedPackets); + Assert.Equal(s.InKbytes, t.InKbytes); + Assert.Equal(s.InPackets, t.InPackets); + Assert.Equal(s.InSavings, t.InSavings); + Assert.Equal(s.MiscInt1, t.MiscInt1); + Assert.Equal(s.MiscInt2, t.MiscInt2); + Assert.Equal(s.FailuresInvalid, t.FailuresInvalid); + Assert.Equal(s.AgentLanguage, t.AgentLanguage); + Assert.Equal(s.AgentMemoryUsed, t.AgentMemoryUsed); + Assert.Equal(s.MetersTraveled, t.MetersTraveled); + Assert.Equal(s.object_kbytes, t.object_kbytes); + Assert.Equal(s.FailuresOffCircuit, t.FailuresOffCircuit); + Assert.Equal(s.SystemOS, t.SystemOS); + Assert.Equal(s.OutCompressedPackets, t.OutCompressedPackets); + Assert.Equal(s.OutKbytes, t.OutKbytes); + Assert.Equal(s.OutPackets, t.OutPackets); + Assert.Equal(s.OutSavings, t.OutSavings); + Assert.Equal(s.AgentPing, t.AgentPing); + Assert.Equal(s.SystemInstalledRam, t.SystemInstalledRam); + Assert.Equal(s.RegionsVisited, t.RegionsVisited); + Assert.Equal(s.FailuresResent, t.FailuresResent); + Assert.Equal(s.AgentRuntime, t.AgentRuntime); + Assert.Equal(s.FailuresSendPacket, t.FailuresSendPacket); + Assert.Equal(s.SessionID, t.SessionID); + Assert.Equal(s.SimulatorFPS, t.SimulatorFPS); + Assert.Equal(s.AgentStartTime, t.AgentStartTime); + Assert.Equal(s.MiscString1, t.MiscString1); + Assert.Equal(s.texture_kbytes, t.texture_kbytes); + Assert.Equal(s.AgentVersion, t.AgentVersion); + Assert.Equal(s.MiscVersion, t.MiscVersion); + Assert.Equal(s.VertexBuffersEnabled, t.VertexBuffersEnabled); + Assert.Equal(s.world_kbytes, t.world_kbytes); } - [Test] + [Fact] public void ParcelVoiceInfoRequestMessage() { ParcelVoiceInfoRequestMessage s = new ParcelVoiceInfoRequestMessage(); @@ -429,12 +434,12 @@ public void ParcelVoiceInfoRequestMessage() ParcelVoiceInfoRequestMessage t = new ParcelVoiceInfoRequestMessage(); t.Deserialize(map); - Assert.AreEqual(s.SipChannelUri, t.SipChannelUri); - Assert.AreEqual(s.ParcelID, t.ParcelID); - Assert.AreEqual(s.RegionName, t.RegionName); + Assert.Equal(s.SipChannelUri, t.SipChannelUri); + Assert.Equal(s.ParcelID, t.ParcelID); + Assert.Equal(s.RegionName, t.RegionName); } - [Test] + [Fact] public void ScriptRunningReplyMessage() { ScriptRunningReplyMessage s = new ScriptRunningReplyMessage(); @@ -448,14 +453,14 @@ public void ScriptRunningReplyMessage() ScriptRunningReplyMessage t = new ScriptRunningReplyMessage(); t.Deserialize(map); - Assert.AreEqual(s.ItemID, t.ItemID); - Assert.AreEqual(s.Mono, t.Mono); - Assert.AreEqual(s.ObjectID, t.ObjectID); - Assert.AreEqual(s.Running, t.Running); + Assert.Equal(s.ItemID, t.ItemID); + Assert.Equal(s.Mono, t.Mono); + Assert.Equal(s.ObjectID, t.ObjectID); + Assert.Equal(s.Running, t.Running); } - [Test] + [Fact] public void MapLayerMessage() { @@ -491,20 +496,20 @@ public void MapLayerMessage() t.Deserialize(map); - Assert.AreEqual(s.Flags, t.Flags); + Assert.Equal(s.Flags, t.Flags); for (int i = 0; i < s.LayerDataBlocks.Length; i++) { - Assert.AreEqual(s.LayerDataBlocks[i].ImageID, t.LayerDataBlocks[i].ImageID); - Assert.AreEqual(s.LayerDataBlocks[i].Top, t.LayerDataBlocks[i].Top); - Assert.AreEqual(s.LayerDataBlocks[i].Left, t.LayerDataBlocks[i].Left); - Assert.AreEqual(s.LayerDataBlocks[i].Right, t.LayerDataBlocks[i].Right); - Assert.AreEqual(s.LayerDataBlocks[i].Bottom, t.LayerDataBlocks[i].Bottom); + Assert.Equal(s.LayerDataBlocks[i].ImageID, t.LayerDataBlocks[i].ImageID); + Assert.Equal(s.LayerDataBlocks[i].Top, t.LayerDataBlocks[i].Top); + Assert.Equal(s.LayerDataBlocks[i].Left, t.LayerDataBlocks[i].Left); + Assert.Equal(s.LayerDataBlocks[i].Right, t.LayerDataBlocks[i].Right); + Assert.Equal(s.LayerDataBlocks[i].Bottom, t.LayerDataBlocks[i].Bottom); } } - [Test] // VARIANT A + [Fact] // VARIANT A public void ChatSessionRequestStartConference() { ChatSessionRequestStartConference s = new ChatSessionRequestStartConference(); @@ -518,15 +523,15 @@ public void ChatSessionRequestStartConference() ChatSessionRequestStartConference t = new ChatSessionRequestStartConference(); t.Deserialize(map); - Assert.AreEqual(s.SessionID, t.SessionID); - Assert.AreEqual(s.Method, t.Method); + Assert.Equal(s.SessionID, t.SessionID); + Assert.Equal(s.Method, t.Method); for (int i = 0; i < t.AgentsBlock.Length; i++) { - Assert.AreEqual(s.AgentsBlock[i], t.AgentsBlock[i]); + Assert.Equal(s.AgentsBlock[i], t.AgentsBlock[i]); } } - [Test] + [Fact] public void ChatSessionRequestMuteUpdate() { ChatSessionRequestMuteUpdate s = new ChatSessionRequestMuteUpdate(); @@ -540,14 +545,14 @@ public void ChatSessionRequestMuteUpdate() ChatSessionRequestMuteUpdate t = new ChatSessionRequestMuteUpdate(); t.Deserialize(map); - Assert.AreEqual(s.AgentID, t.AgentID); - Assert.AreEqual(s.Method, t.Method); - Assert.AreEqual(s.RequestKey, t.RequestKey); - Assert.AreEqual(s.RequestValue, t.RequestValue); - Assert.AreEqual(s.SessionID, t.SessionID); + Assert.Equal(s.AgentID, t.AgentID); + Assert.Equal(s.Method, t.Method); + Assert.Equal(s.RequestKey, t.RequestKey); + Assert.Equal(s.RequestValue, t.RequestValue); + Assert.Equal(s.SessionID, t.SessionID); } - [Test] + [Fact] public void ChatSessionAcceptInvitation() { ChatSessionAcceptInvitation s = new ChatSessionAcceptInvitation(); @@ -558,11 +563,11 @@ public void ChatSessionAcceptInvitation() ChatSessionAcceptInvitation t = new ChatSessionAcceptInvitation(); t.Deserialize(map); - Assert.AreEqual(s.Method, t.Method); - Assert.AreEqual(s.SessionID, t.SessionID); + Assert.Equal(s.Method, t.Method); + Assert.Equal(s.SessionID, t.SessionID); } - [Test] + [Fact] public void RequiredVoiceVersionMessage() { RequiredVoiceVersionMessage s = new RequiredVoiceVersionMessage(); @@ -575,12 +580,12 @@ public void RequiredVoiceVersionMessage() RequiredVoiceVersionMessage t = new RequiredVoiceVersionMessage(); t.Deserialize(map); - Assert.AreEqual(s.MajorVersion, t.MajorVersion); - Assert.AreEqual(s.MinorVersion, t.MinorVersion); - Assert.AreEqual(s.RegionName, t.RegionName); + Assert.Equal(s.MajorVersion, t.MajorVersion); + Assert.Equal(s.MinorVersion, t.MinorVersion); + Assert.Equal(s.RegionName, t.RegionName); } - [Test] + [Fact] public void CopyInventoryFromNotecardMessage() { CopyInventoryFromNotecardMessage s = new CopyInventoryFromNotecardMessage(); @@ -595,14 +600,14 @@ public void CopyInventoryFromNotecardMessage() CopyInventoryFromNotecardMessage t = new CopyInventoryFromNotecardMessage(); t.Deserialize(map); - Assert.AreEqual(s.CallbackID, t.CallbackID); - Assert.AreEqual(s.FolderID, t.FolderID); - Assert.AreEqual(s.ItemID, t.ItemID); - Assert.AreEqual(s.NotecardID, t.NotecardID); - Assert.AreEqual(s.ObjectID, t.ObjectID); + Assert.Equal(s.CallbackID, t.CallbackID); + Assert.Equal(s.FolderID, t.FolderID); + Assert.Equal(s.ItemID, t.ItemID); + Assert.Equal(s.NotecardID, t.NotecardID); + Assert.Equal(s.ObjectID, t.ObjectID); } - [Test] + [Fact] public void ProvisionVoiceAccountRequestMessage() { ProvisionVoiceAccountRequestMessage s = new ProvisionVoiceAccountRequestMessage(); @@ -614,11 +619,11 @@ public void ProvisionVoiceAccountRequestMessage() ProvisionVoiceAccountRequestMessage t = new ProvisionVoiceAccountRequestMessage(); t.Deserialize(map); - Assert.AreEqual(s.Password, t.Password); - Assert.AreEqual(s.Username, t.Username); + Assert.Equal(s.Password, t.Password); + Assert.Equal(s.Username, t.Username); } - [Test] + [Fact] public void UpdateAgentLanguageMessage() { UpdateAgentLanguageMessage s = new UpdateAgentLanguageMessage(); @@ -630,12 +635,12 @@ public void UpdateAgentLanguageMessage() UpdateAgentLanguageMessage t = new UpdateAgentLanguageMessage(); t.Deserialize(map); - Assert.AreEqual(s.Language, t.Language); - Assert.AreEqual(s.LanguagePublic, t.LanguagePublic); + Assert.Equal(s.Language, t.Language); + Assert.Equal(s.LanguagePublic, t.LanguagePublic); } - [Test] + [Fact] public void ParcelPropertiesMessage() { ParcelPropertiesMessage s = new ParcelPropertiesMessage(); @@ -700,64 +705,64 @@ public void ParcelPropertiesMessage() t.Deserialize(map); - Assert.AreEqual(s.AABBMax, t.AABBMax); - Assert.AreEqual(s.AABBMin, t.AABBMin); - Assert.AreEqual(s.Area, t.Area); - Assert.AreEqual(s.AuctionID, t.AuctionID); - Assert.AreEqual(s.AuthBuyerID, t.AuthBuyerID); - Assert.AreEqual(s.Bitmap, t.Bitmap); - Assert.AreEqual(s.Category, t.Category); - Assert.AreEqual(s.ClaimDate, t.ClaimDate); - Assert.AreEqual(s.ClaimPrice, t.ClaimPrice); - Assert.AreEqual(s.Desc, t.Desc); - Assert.AreEqual(s.GroupID, t.GroupID); - Assert.AreEqual(s.GroupPrims, t.GroupPrims); - Assert.AreEqual(s.IsGroupOwned, t.IsGroupOwned); - Assert.AreEqual(s.LandingType, t.LandingType); - Assert.AreEqual(s.LocalID, t.LocalID); - Assert.AreEqual(s.MaxPrims, t.MaxPrims); - Assert.AreEqual(s.MediaAutoScale, t.MediaAutoScale); - Assert.AreEqual(s.MediaDesc, t.MediaDesc); - Assert.AreEqual(s.MediaHeight, t.MediaHeight); - Assert.AreEqual(s.MediaID, t.MediaID); - Assert.AreEqual(s.MediaLoop, t.MediaLoop); - Assert.AreEqual(s.MediaType, t.MediaType); - Assert.AreEqual(s.MediaURL, t.MediaURL); - Assert.AreEqual(s.MediaWidth, t.MediaWidth); - Assert.AreEqual(s.MusicURL, t.MusicURL); - Assert.AreEqual(s.Name, t.Name); - Assert.AreEqual(s.ObscureMedia, t.ObscureMedia); - Assert.AreEqual(s.ObscureMusic, t.ObscureMusic); - Assert.AreEqual(s.OtherCleanTime, t.OtherCleanTime); - Assert.AreEqual(s.OtherCount, t.OtherCount); - Assert.AreEqual(s.OtherPrims, t.OtherPrims); - Assert.AreEqual(s.OwnerID, t.OwnerID); - Assert.AreEqual(s.OwnerPrims, t.OwnerPrims); - Assert.AreEqual(s.ParcelFlags, t.ParcelFlags); - Assert.AreEqual(s.ParcelPrimBonus, t.ParcelPrimBonus); - Assert.AreEqual(s.PassHours, t.PassHours); - Assert.AreEqual(s.PassPrice, t.PassPrice); - Assert.AreEqual(s.PublicCount, t.PublicCount); - Assert.AreEqual(s.RegionDenyAgeUnverified, t.RegionDenyAgeUnverified); - Assert.AreEqual(s.RegionDenyAnonymous, t.RegionDenyAnonymous); - Assert.AreEqual(s.RegionPushOverride, t.RegionPushOverride); - Assert.AreEqual(s.RentPrice, t.RentPrice); - Assert.AreEqual(s.RequestResult, t.RequestResult); - Assert.AreEqual(s.SalePrice, t.SalePrice); - Assert.AreEqual(s.SelectedPrims, t.SelectedPrims); - Assert.AreEqual(s.SelfCount, t.SelfCount); - Assert.AreEqual(s.SequenceID, t.SequenceID); - Assert.AreEqual(s.SimWideMaxPrims, t.SimWideMaxPrims); - Assert.AreEqual(s.SimWideTotalPrims, t.SimWideTotalPrims); - Assert.AreEqual(s.SnapSelection, t.SnapSelection); - Assert.AreEqual(s.SnapshotID, t.SnapshotID); - Assert.AreEqual(s.Status, t.Status); - Assert.AreEqual(s.TotalPrims, t.TotalPrims); - Assert.AreEqual(s.UserLocation, t.UserLocation); - Assert.AreEqual(s.UserLookAt, t.UserLookAt); + Assert.Equal(s.AABBMax, t.AABBMax); + Assert.Equal(s.AABBMin, t.AABBMin); + Assert.Equal(s.Area, t.Area); + Assert.Equal(s.AuctionID, t.AuctionID); + Assert.Equal(s.AuthBuyerID, t.AuthBuyerID); + Assert.Equal(s.Bitmap, t.Bitmap); + Assert.Equal(s.Category, t.Category); + Assert.Equal(s.ClaimDate, t.ClaimDate); + Assert.Equal(s.ClaimPrice, t.ClaimPrice); + Assert.Equal(s.Desc, t.Desc); + Assert.Equal(s.GroupID, t.GroupID); + Assert.Equal(s.GroupPrims, t.GroupPrims); + Assert.Equal(s.IsGroupOwned, t.IsGroupOwned); + Assert.Equal(s.LandingType, t.LandingType); + Assert.Equal(s.LocalID, t.LocalID); + Assert.Equal(s.MaxPrims, t.MaxPrims); + Assert.Equal(s.MediaAutoScale, t.MediaAutoScale); + Assert.Equal(s.MediaDesc, t.MediaDesc); + Assert.Equal(s.MediaHeight, t.MediaHeight); + Assert.Equal(s.MediaID, t.MediaID); + Assert.Equal(s.MediaLoop, t.MediaLoop); + Assert.Equal(s.MediaType, t.MediaType); + Assert.Equal(s.MediaURL, t.MediaURL); + Assert.Equal(s.MediaWidth, t.MediaWidth); + Assert.Equal(s.MusicURL, t.MusicURL); + Assert.Equal(s.Name, t.Name); + Assert.Equal(s.ObscureMedia, t.ObscureMedia); + Assert.Equal(s.ObscureMusic, t.ObscureMusic); + Assert.Equal(s.OtherCleanTime, t.OtherCleanTime); + Assert.Equal(s.OtherCount, t.OtherCount); + Assert.Equal(s.OtherPrims, t.OtherPrims); + Assert.Equal(s.OwnerID, t.OwnerID); + Assert.Equal(s.OwnerPrims, t.OwnerPrims); + Assert.Equal(s.ParcelFlags, t.ParcelFlags); + Assert.Equal(s.ParcelPrimBonus, t.ParcelPrimBonus); + Assert.Equal(s.PassHours, t.PassHours); + Assert.Equal(s.PassPrice, t.PassPrice); + Assert.Equal(s.PublicCount, t.PublicCount); + Assert.Equal(s.RegionDenyAgeUnverified, t.RegionDenyAgeUnverified); + Assert.Equal(s.RegionDenyAnonymous, t.RegionDenyAnonymous); + Assert.Equal(s.RegionPushOverride, t.RegionPushOverride); + Assert.Equal(s.RentPrice, t.RentPrice); + Assert.Equal(s.RequestResult, t.RequestResult); + Assert.Equal(s.SalePrice, t.SalePrice); + Assert.Equal(s.SelectedPrims, t.SelectedPrims); + Assert.Equal(s.SelfCount, t.SelfCount); + Assert.Equal(s.SequenceID, t.SequenceID); + Assert.Equal(s.SimWideMaxPrims, t.SimWideMaxPrims); + Assert.Equal(s.SimWideTotalPrims, t.SimWideTotalPrims); + Assert.Equal(s.SnapSelection, t.SnapSelection); + Assert.Equal(s.SnapshotID, t.SnapshotID); + Assert.Equal(s.Status, t.Status); + Assert.Equal(s.TotalPrims, t.TotalPrims); + Assert.Equal(s.UserLocation, t.UserLocation); + Assert.Equal(s.UserLookAt, t.UserLookAt); } - [Test] + [Fact] public void ParcelPropertiesUpdateMessage() { ParcelPropertiesUpdateMessage s = new ParcelPropertiesUpdateMessage(); @@ -793,33 +798,33 @@ public void ParcelPropertiesUpdateMessage() t.Deserialize(map); - Assert.AreEqual(s.AuthBuyerID, t.AuthBuyerID); - Assert.AreEqual(s.Category, t.Category); - Assert.AreEqual(s.Desc, t.Desc); - Assert.AreEqual(s.GroupID, t.GroupID); - Assert.AreEqual(s.Landing, t.Landing); - Assert.AreEqual(s.LocalID, t.LocalID); - Assert.AreEqual(s.MediaAutoScale, t.MediaAutoScale); - Assert.AreEqual(s.MediaDesc, t.MediaDesc); - Assert.AreEqual(s.MediaHeight, t.MediaHeight); - Assert.AreEqual(s.MediaID, t.MediaID); - Assert.AreEqual(s.MediaLoop, t.MediaLoop); - Assert.AreEqual(s.MediaType, t.MediaType); - Assert.AreEqual(s.MediaURL, t.MediaURL); - Assert.AreEqual(s.MediaWidth, t.MediaWidth); - Assert.AreEqual(s.MusicURL, t.MusicURL); - Assert.AreEqual(s.Name, t.Name); - Assert.AreEqual(s.ObscureMedia, t.ObscureMedia); - Assert.AreEqual(s.ObscureMusic, t.ObscureMusic); - Assert.AreEqual(s.ParcelFlags, t.ParcelFlags); - Assert.AreEqual(s.PassHours, t.PassHours); - Assert.AreEqual(s.PassPrice, t.PassPrice); - Assert.AreEqual(s.SalePrice, t.SalePrice); - Assert.AreEqual(s.SnapshotID, t.SnapshotID); - Assert.AreEqual(s.UserLocation, t.UserLocation); - Assert.AreEqual(s.UserLookAt, t.UserLookAt); + Assert.Equal(s.AuthBuyerID, t.AuthBuyerID); + Assert.Equal(s.Category, t.Category); + Assert.Equal(s.Desc, t.Desc); + Assert.Equal(s.GroupID, t.GroupID); + Assert.Equal(s.Landing, t.Landing); + Assert.Equal(s.LocalID, t.LocalID); + Assert.Equal(s.MediaAutoScale, t.MediaAutoScale); + Assert.Equal(s.MediaDesc, t.MediaDesc); + Assert.Equal(s.MediaHeight, t.MediaHeight); + Assert.Equal(s.MediaID, t.MediaID); + Assert.Equal(s.MediaLoop, t.MediaLoop); + Assert.Equal(s.MediaType, t.MediaType); + Assert.Equal(s.MediaURL, t.MediaURL); + Assert.Equal(s.MediaWidth, t.MediaWidth); + Assert.Equal(s.MusicURL, t.MusicURL); + Assert.Equal(s.Name, t.Name); + Assert.Equal(s.ObscureMedia, t.ObscureMedia); + Assert.Equal(s.ObscureMusic, t.ObscureMusic); + Assert.Equal(s.ParcelFlags, t.ParcelFlags); + Assert.Equal(s.PassHours, t.PassHours); + Assert.Equal(s.PassPrice, t.PassPrice); + Assert.Equal(s.SalePrice, t.SalePrice); + Assert.Equal(s.SnapshotID, t.SnapshotID); + Assert.Equal(s.UserLocation, t.UserLocation); + Assert.Equal(s.UserLookAt, t.UserLookAt); } - [Test] + [Fact] public void EnableSimulatorMessage() { EnableSimulatorMessage s = new EnableSimulatorMessage(); @@ -844,13 +849,13 @@ public void EnableSimulatorMessage() for (int i = 0; i < t.Simulators.Length; i++) { - Assert.AreEqual(s.Simulators[i].IP, t.Simulators[i].IP); - Assert.AreEqual(s.Simulators[i].Port, t.Simulators[i].Port); - Assert.AreEqual(s.Simulators[i].RegionHandle, t.Simulators[i].RegionHandle); + Assert.Equal(s.Simulators[i].IP, t.Simulators[i].IP); + Assert.Equal(s.Simulators[i].Port, t.Simulators[i].Port); + Assert.Equal(s.Simulators[i].RegionHandle, t.Simulators[i].RegionHandle); } } - [Test] + [Fact] public void RemoteParcelRequestReply() { RemoteParcelRequestReply s = new RemoteParcelRequestReply(); @@ -860,10 +865,10 @@ public void RemoteParcelRequestReply() RemoteParcelRequestReply t = new RemoteParcelRequestReply(); t.Deserialize(map); - Assert.AreEqual(s.ParcelID, t.ParcelID); + Assert.Equal(s.ParcelID, t.ParcelID); } - [Test] + [Fact] public void UpdateScriptTaskMessage() { UpdateScriptTaskUpdateMessage s = new UpdateScriptTaskUpdateMessage(); @@ -876,13 +881,13 @@ public void UpdateScriptTaskMessage() UpdateScriptTaskUpdateMessage t = new UpdateScriptTaskUpdateMessage(); t.Deserialize(map); - Assert.AreEqual(s.ItemID, t.ItemID); - Assert.AreEqual(s.ScriptRunning, t.ScriptRunning); - Assert.AreEqual(s.Target, t.Target); - Assert.AreEqual(s.TaskID, t.TaskID); + Assert.Equal(s.ItemID, t.ItemID); + Assert.Equal(s.ScriptRunning, t.ScriptRunning); + Assert.Equal(s.Target, t.Target); + Assert.Equal(s.TaskID, t.TaskID); } - [Test] + [Fact] public void UpdateScriptAgentMessage() { UpdateScriptAgentRequestMessage s = new UpdateScriptAgentRequestMessage(); @@ -894,11 +899,11 @@ public void UpdateScriptAgentMessage() UpdateScriptAgentRequestMessage t = new UpdateScriptAgentRequestMessage(); t.Deserialize(map); - Assert.AreEqual(s.ItemID, t.ItemID); - Assert.AreEqual(s.Target, t.Target); + Assert.Equal(s.ItemID, t.ItemID); + Assert.Equal(s.Target, t.Target); } - [Test] + [Fact] public void SendPostcardMessage() { SendPostcardMessage s = new SendPostcardMessage(); @@ -914,15 +919,15 @@ public void SendPostcardMessage() SendPostcardMessage t = new SendPostcardMessage(); t.Deserialize(map); - Assert.AreEqual(s.FromEmail, t.FromEmail); - Assert.AreEqual(s.FromName, t.FromName); - Assert.AreEqual(s.GlobalPosition, t.GlobalPosition); - Assert.AreEqual(s.Message, t.Message); - Assert.AreEqual(s.Subject, t.Subject); - Assert.AreEqual(s.ToEmail, t.ToEmail); + Assert.Equal(s.FromEmail, t.FromEmail); + Assert.Equal(s.FromName, t.FromName); + Assert.Equal(s.GlobalPosition, t.GlobalPosition); + Assert.Equal(s.Message, t.Message); + Assert.Equal(s.Subject, t.Subject); + Assert.Equal(s.ToEmail, t.ToEmail); } - [Test] + [Fact] public void UpdateNotecardAgentInventoryMessage() { UpdateAgentInventoryRequestMessage s = new UpdateAgentInventoryRequestMessage(); @@ -933,10 +938,10 @@ public void UpdateNotecardAgentInventoryMessage() UpdateAgentInventoryRequestMessage t = new UpdateAgentInventoryRequestMessage(); t.Deserialize(map); - Assert.AreEqual(s.ItemID, t.ItemID); + Assert.Equal(s.ItemID, t.ItemID); } - [Test] + [Fact] public void LandStatReplyMessage() { LandStatReplyMessage s = new LandStatReplyMessage(); @@ -972,24 +977,24 @@ public void LandStatReplyMessage() LandStatReplyMessage t = new LandStatReplyMessage(); t.Deserialize(map); - Assert.AreEqual(s.ReportType, t.ReportType); - Assert.AreEqual(s.RequestFlags, t.RequestFlags); - Assert.AreEqual(s.TotalObjectCount, t.TotalObjectCount); + Assert.Equal(s.ReportType, t.ReportType); + Assert.Equal(s.RequestFlags, t.RequestFlags); + Assert.Equal(s.TotalObjectCount, t.TotalObjectCount); for (int i = 0; i < t.ReportDataBlocks.Length; i++) { - Assert.AreEqual(s.ReportDataBlocks[i].Location, t.ReportDataBlocks[i].Location); - Assert.AreEqual(s.ReportDataBlocks[i].MonoScore, t.ReportDataBlocks[i].MonoScore); - Assert.AreEqual(s.ReportDataBlocks[i].OwnerName, t.ReportDataBlocks[i].OwnerName); - Assert.AreEqual(s.ReportDataBlocks[i].Score, t.ReportDataBlocks[i].Score); - Assert.AreEqual(s.ReportDataBlocks[i].TaskID, t.ReportDataBlocks[i].TaskID); - Assert.AreEqual(s.ReportDataBlocks[i].TaskLocalID, t.ReportDataBlocks[i].TaskLocalID); - Assert.AreEqual(s.ReportDataBlocks[i].TaskName, t.ReportDataBlocks[i].TaskName); - Assert.AreEqual(s.ReportDataBlocks[i].TimeStamp, t.ReportDataBlocks[i].TimeStamp); + Assert.Equal(s.ReportDataBlocks[i].Location, t.ReportDataBlocks[i].Location); + Assert.Equal(s.ReportDataBlocks[i].MonoScore, t.ReportDataBlocks[i].MonoScore); + Assert.Equal(s.ReportDataBlocks[i].OwnerName, t.ReportDataBlocks[i].OwnerName); + Assert.Equal(s.ReportDataBlocks[i].Score, t.ReportDataBlocks[i].Score); + Assert.Equal(s.ReportDataBlocks[i].TaskID, t.ReportDataBlocks[i].TaskID); + Assert.Equal(s.ReportDataBlocks[i].TaskLocalID, t.ReportDataBlocks[i].TaskLocalID); + Assert.Equal(s.ReportDataBlocks[i].TaskName, t.ReportDataBlocks[i].TaskName); + Assert.Equal(s.ReportDataBlocks[i].TimeStamp, t.ReportDataBlocks[i].TimeStamp); } } - [Test] + [Fact] public void TelportFailedMessage() { TeleportFailedMessage s = new TeleportFailedMessage(); @@ -1003,14 +1008,14 @@ public void TelportFailedMessage() TeleportFailedMessage t = new TeleportFailedMessage(); t.Deserialize(map); - Assert.AreEqual(s.AgentID, t.AgentID); - Assert.AreEqual(s.ExtraParams, t.ExtraParams); - Assert.AreEqual(s.MessageKey, t.MessageKey); - Assert.AreEqual(s.Reason, t.Reason); + Assert.Equal(s.AgentID, t.AgentID); + Assert.Equal(s.ExtraParams, t.ExtraParams); + Assert.Equal(s.MessageKey, t.MessageKey); + Assert.Equal(s.Reason, t.Reason); } - [Test] + [Fact] public void UpdateAgentInformationMessage() { UpdateAgentInformationMessage s = new UpdateAgentInformationMessage(); @@ -1020,10 +1025,10 @@ public void UpdateAgentInformationMessage() UpdateAgentInformationMessage t = new UpdateAgentInformationMessage(); t.Deserialize(map); - Assert.AreEqual(s.MaxAccess, t.MaxAccess); + Assert.Equal(s.MaxAccess, t.MaxAccess); } - [Test] + [Fact] public void PlacesReplyMessage() { PlacesReplyMessage s = new PlacesReplyMessage(); @@ -1073,30 +1078,30 @@ public void PlacesReplyMessage() PlacesReplyMessage t = new PlacesReplyMessage(); t.Deserialize(map); - Assert.AreEqual(s.AgentID, t.AgentID); - Assert.AreEqual(s.TransactionID, t.TransactionID); - Assert.AreEqual(s.QueryID, t.QueryID); + Assert.Equal(s.AgentID, t.AgentID); + Assert.Equal(s.TransactionID, t.TransactionID); + Assert.Equal(s.QueryID, t.QueryID); for (int i = 0; i < s.QueryDataBlocks.Length; i++) { - Assert.AreEqual(s.QueryDataBlocks[i].ActualArea, t.QueryDataBlocks[i].ActualArea); - Assert.AreEqual(s.QueryDataBlocks[i].BillableArea, t.QueryDataBlocks[i].BillableArea); - Assert.AreEqual(s.QueryDataBlocks[i].Description, t.QueryDataBlocks[i].Description); - Assert.AreEqual(s.QueryDataBlocks[i].Dwell, t.QueryDataBlocks[i].Dwell); - Assert.AreEqual(s.QueryDataBlocks[i].Flags, t.QueryDataBlocks[i].Flags); - Assert.AreEqual(s.QueryDataBlocks[i].GlobalX, t.QueryDataBlocks[i].GlobalX); - Assert.AreEqual(s.QueryDataBlocks[i].GlobalY, t.QueryDataBlocks[i].GlobalY); - Assert.AreEqual(s.QueryDataBlocks[i].GlobalZ, t.QueryDataBlocks[i].GlobalZ); - Assert.AreEqual(s.QueryDataBlocks[i].Name, t.QueryDataBlocks[i].Name); - Assert.AreEqual(s.QueryDataBlocks[i].OwnerID, t.QueryDataBlocks[i].OwnerID); - Assert.AreEqual(s.QueryDataBlocks[i].Price, t.QueryDataBlocks[i].Price); - Assert.AreEqual(s.QueryDataBlocks[i].ProductSku, t.QueryDataBlocks[i].ProductSku); - Assert.AreEqual(s.QueryDataBlocks[i].SimName, t.QueryDataBlocks[i].SimName); - Assert.AreEqual(s.QueryDataBlocks[i].SnapShotID, t.QueryDataBlocks[i].SnapShotID); + Assert.Equal(s.QueryDataBlocks[i].ActualArea, t.QueryDataBlocks[i].ActualArea); + Assert.Equal(s.QueryDataBlocks[i].BillableArea, t.QueryDataBlocks[i].BillableArea); + Assert.Equal(s.QueryDataBlocks[i].Description, t.QueryDataBlocks[i].Description); + Assert.Equal(s.QueryDataBlocks[i].Dwell, t.QueryDataBlocks[i].Dwell); + Assert.Equal(s.QueryDataBlocks[i].Flags, t.QueryDataBlocks[i].Flags); + Assert.Equal(s.QueryDataBlocks[i].GlobalX, t.QueryDataBlocks[i].GlobalX); + Assert.Equal(s.QueryDataBlocks[i].GlobalY, t.QueryDataBlocks[i].GlobalY); + Assert.Equal(s.QueryDataBlocks[i].GlobalZ, t.QueryDataBlocks[i].GlobalZ); + Assert.Equal(s.QueryDataBlocks[i].Name, t.QueryDataBlocks[i].Name); + Assert.Equal(s.QueryDataBlocks[i].OwnerID, t.QueryDataBlocks[i].OwnerID); + Assert.Equal(s.QueryDataBlocks[i].Price, t.QueryDataBlocks[i].Price); + Assert.Equal(s.QueryDataBlocks[i].ProductSku, t.QueryDataBlocks[i].ProductSku); + Assert.Equal(s.QueryDataBlocks[i].SimName, t.QueryDataBlocks[i].SimName); + Assert.Equal(s.QueryDataBlocks[i].SnapShotID, t.QueryDataBlocks[i].SnapShotID); } } - [Test] + [Fact] public void DirLandReplyMessage() { DirLandReplyMessage s = new DirLandReplyMessage(); @@ -1131,26 +1136,26 @@ public void DirLandReplyMessage() DirLandReplyMessage t = new DirLandReplyMessage(); t.Deserialize(map); - Assert.AreEqual(s.AgentID, t.AgentID); - Assert.AreEqual(s.QueryID, t.QueryID); + Assert.Equal(s.AgentID, t.AgentID); + Assert.Equal(s.QueryID, t.QueryID); for (int i = 0; i < s.QueryReplies.Length; i++) { - Assert.AreEqual(s.QueryReplies[i].ActualArea, t.QueryReplies[i].ActualArea); - Assert.AreEqual(s.QueryReplies[i].Auction, t.QueryReplies[i].Auction); - Assert.AreEqual(s.QueryReplies[i].ForSale, t.QueryReplies[i].ForSale); - Assert.AreEqual(s.QueryReplies[i].Name, t.QueryReplies[i].Name); - Assert.AreEqual(s.QueryReplies[i].ProductSku, t.QueryReplies[i].ProductSku); - Assert.AreEqual(s.QueryReplies[i].ParcelID, t.QueryReplies[i].ParcelID); - Assert.AreEqual(s.QueryReplies[i].SalePrice, t.QueryReplies[i].SalePrice); + Assert.Equal(s.QueryReplies[i].ActualArea, t.QueryReplies[i].ActualArea); + Assert.Equal(s.QueryReplies[i].Auction, t.QueryReplies[i].Auction); + Assert.Equal(s.QueryReplies[i].ForSale, t.QueryReplies[i].ForSale); + Assert.Equal(s.QueryReplies[i].Name, t.QueryReplies[i].Name); + Assert.Equal(s.QueryReplies[i].ProductSku, t.QueryReplies[i].ProductSku); + Assert.Equal(s.QueryReplies[i].ParcelID, t.QueryReplies[i].ParcelID); + Assert.Equal(s.QueryReplies[i].SalePrice, t.QueryReplies[i].SalePrice); } } #region Performance Testing private const int TEST_ITER = 100000; - [Test] - [Category("Benchmark")] + [Fact] + [Trait("Category", "Benchmark")] public void ReflectionPerformanceRemoteParcelResponse() { DateTime messageTestTime = DateTime.UtcNow; @@ -1163,7 +1168,7 @@ public void ReflectionPerformanceRemoteParcelResponse() RemoteParcelRequestReply t = new RemoteParcelRequestReply(); t.Deserialize(map); - Assert.AreEqual(s.ParcelID, t.ParcelID); + Assert.Equal(s.ParcelID, t.ParcelID); } TimeSpan duration = DateTime.UtcNow - messageTestTime; Console.WriteLine("RemoteParcelRequestReply: OMV Message System Serialization/Deserialization Passes: {0} Total time: {1}", TEST_ITER, duration); @@ -1176,24 +1181,26 @@ public void ReflectionPerformanceRemoteParcelResponse() s.ParcelID = UUID.Random(); MemoryStream stream = new MemoryStream(); + byte[] llsdPayload = OSDParser.SerializeLLSDBinary(s.Serialize(), false); - ZeroFormatter.ZeroFormatterSerializer.Serialize(stream, s); + MessagePackSerializer.Serialize(stream, llsdPayload, BenchmarkMessagePackOptions); //formatter.Serialize(stream, s); stream.Seek(0, SeekOrigin.Begin); //RemoteParcelRequestReply t = (RemoteParcelRequestReply)formatter.Deserialize(stream); - RemoteParcelRequestReply t = - ZeroFormatter.ZeroFormatterSerializer.Deserialize(stream); + byte[] unpackedLlsd = MessagePackSerializer.Deserialize(stream, BenchmarkMessagePackOptions); + RemoteParcelRequestReply t = new RemoteParcelRequestReply(); + t.Deserialize((OSDMap)OSDParser.DeserializeLLSDBinary(unpackedLlsd)); - Assert.AreEqual(s.ParcelID, t.ParcelID); + Assert.Equal(s.ParcelID, t.ParcelID); } TimeSpan durationxml = DateTime.UtcNow - xmlTestTime; - Console.WriteLine("RemoteParcelRequestReply: .NET BinarySerialization/Deserialization Passes: {0} Total time: {1}", TEST_ITER, durationxml); + Console.WriteLine("RemoteParcelRequestReply: MessagePack(LLSD binary payload) Serialization/Deserialization Passes: {0} Total time: {1}", TEST_ITER, durationxml); } - [Test] - [Category("Benchmark")] + [Fact] + [Trait("Category", "Benchmark")] public void ReflectionPerformanceDirLandReply() { @@ -1231,18 +1238,18 @@ public void ReflectionPerformanceDirLandReply() DirLandReplyMessage t = new DirLandReplyMessage(); t.Deserialize(map); - Assert.AreEqual(s.AgentID, t.AgentID); - Assert.AreEqual(s.QueryID, t.QueryID); + Assert.Equal(s.AgentID, t.AgentID); + Assert.Equal(s.QueryID, t.QueryID); for (int i = 0; i < s.QueryReplies.Length; i++) { - Assert.AreEqual(s.QueryReplies[i].ActualArea, t.QueryReplies[i].ActualArea); - Assert.AreEqual(s.QueryReplies[i].Auction, t.QueryReplies[i].Auction); - Assert.AreEqual(s.QueryReplies[i].ForSale, t.QueryReplies[i].ForSale); - Assert.AreEqual(s.QueryReplies[i].Name, t.QueryReplies[i].Name); - Assert.AreEqual(s.QueryReplies[i].ProductSku, t.QueryReplies[i].ProductSku); - Assert.AreEqual(s.QueryReplies[i].ParcelID, t.QueryReplies[i].ParcelID); - Assert.AreEqual(s.QueryReplies[i].SalePrice, t.QueryReplies[i].SalePrice); + Assert.Equal(s.QueryReplies[i].ActualArea, t.QueryReplies[i].ActualArea); + Assert.Equal(s.QueryReplies[i].Auction, t.QueryReplies[i].Auction); + Assert.Equal(s.QueryReplies[i].ForSale, t.QueryReplies[i].ForSale); + Assert.Equal(s.QueryReplies[i].Name, t.QueryReplies[i].Name); + Assert.Equal(s.QueryReplies[i].ProductSku, t.QueryReplies[i].ProductSku); + Assert.Equal(s.QueryReplies[i].ParcelID, t.QueryReplies[i].ParcelID); + Assert.Equal(s.QueryReplies[i].SalePrice, t.QueryReplies[i].SalePrice); } } TimeSpan duration = DateTime.UtcNow - messageTestTime; @@ -1279,34 +1286,37 @@ public void ReflectionPerformanceDirLandReply() s.QueryReplies[1] = q2; MemoryStream stream = new MemoryStream(); + byte[] llsdPayload = OSDParser.SerializeLLSDBinary(s.Serialize(), false); //formatter.Serialize(stream, s); - ZeroFormatter.ZeroFormatterSerializer.Serialize(stream, s); + MessagePackSerializer.Serialize(stream, llsdPayload, BenchmarkMessagePackOptions); stream.Seek(0, SeekOrigin.Begin); //DirLandReplyMessage t = (DirLandReplyMessage)formatter.Deserialize(stream); - DirLandReplyMessage t = ZeroFormatter.ZeroFormatterSerializer.Deserialize(stream); + byte[] unpackedLlsd = MessagePackSerializer.Deserialize(stream, BenchmarkMessagePackOptions); + DirLandReplyMessage t = new DirLandReplyMessage(); + t.Deserialize((OSDMap)OSDParser.DeserializeLLSDBinary(unpackedLlsd)); - Assert.AreEqual(s.AgentID, t.AgentID); - Assert.AreEqual(s.QueryID, t.QueryID); + Assert.Equal(s.AgentID, t.AgentID); + Assert.Equal(s.QueryID, t.QueryID); for (int i = 0; i < s.QueryReplies.Length; i++) { - Assert.AreEqual(s.QueryReplies[i].ActualArea, t.QueryReplies[i].ActualArea); - Assert.AreEqual(s.QueryReplies[i].Auction, t.QueryReplies[i].Auction); - Assert.AreEqual(s.QueryReplies[i].ForSale, t.QueryReplies[i].ForSale); - Assert.AreEqual(s.QueryReplies[i].Name, t.QueryReplies[i].Name); - Assert.AreEqual(s.QueryReplies[i].ProductSku, t.QueryReplies[i].ProductSku); - Assert.AreEqual(s.QueryReplies[i].ParcelID, t.QueryReplies[i].ParcelID); - Assert.AreEqual(s.QueryReplies[i].SalePrice, t.QueryReplies[i].SalePrice); + Assert.Equal(s.QueryReplies[i].ActualArea, t.QueryReplies[i].ActualArea); + Assert.Equal(s.QueryReplies[i].Auction, t.QueryReplies[i].Auction); + Assert.Equal(s.QueryReplies[i].ForSale, t.QueryReplies[i].ForSale); + Assert.Equal(s.QueryReplies[i].Name, t.QueryReplies[i].Name); + Assert.Equal(s.QueryReplies[i].ProductSku, t.QueryReplies[i].ProductSku); + Assert.Equal(s.QueryReplies[i].ParcelID, t.QueryReplies[i].ParcelID); + Assert.Equal(s.QueryReplies[i].SalePrice, t.QueryReplies[i].SalePrice); } } TimeSpan durationxml = DateTime.UtcNow - xmlTestTime; - Console.WriteLine("DirLandReplyMessage: .NET BinarySerialization/Deserialization Passes: {0} Total time: {1}", TEST_ITER, durationxml); + Console.WriteLine("DirLandReplyMessage: MessagePack(LLSD binary payload) Serialization/Deserialization Passes: {0} Total time: {1}", TEST_ITER, durationxml); } - [Test] - [Category("Benchmark")] + [Fact] + [Trait("Category", "Benchmark")] public void ReflectionPerformanceDirLandReply2() { XmlSerializer xmlSerializer = new XmlSerializer(typeof(DirLandReplyMessage)); @@ -1365,8 +1375,8 @@ public void ReflectionPerformanceDirLandReply2() Console.WriteLine(".NET BinarySerialization/Deserialization Passes: {0} Total time: {1}", TEST_ITER, timer.Elapsed.TotalSeconds); } - [Test] - [Category("Benchmark")] + [Fact] + [Trait("Category", "Benchmark")] public void ReflectionPerformanceParcelProperties() { DateTime messageTestTime = DateTime.UtcNow; @@ -1434,61 +1444,61 @@ public void ReflectionPerformanceParcelProperties() t.Deserialize(map); - Assert.AreEqual(s.AABBMax, t.AABBMax); - Assert.AreEqual(s.AABBMin, t.AABBMin); - Assert.AreEqual(s.Area, t.Area); - Assert.AreEqual(s.AuctionID, t.AuctionID); - Assert.AreEqual(s.AuthBuyerID, t.AuthBuyerID); - Assert.AreEqual(s.Bitmap, t.Bitmap); - Assert.AreEqual(s.Category, t.Category); - Assert.AreEqual(s.ClaimDate, t.ClaimDate); - Assert.AreEqual(s.ClaimPrice, t.ClaimPrice); - Assert.AreEqual(s.Desc, t.Desc); - Assert.AreEqual(s.GroupID, t.GroupID); - Assert.AreEqual(s.GroupPrims, t.GroupPrims); - Assert.AreEqual(s.IsGroupOwned, t.IsGroupOwned); - Assert.AreEqual(s.LandingType, t.LandingType); - Assert.AreEqual(s.LocalID, t.LocalID); - Assert.AreEqual(s.MaxPrims, t.MaxPrims); - Assert.AreEqual(s.MediaAutoScale, t.MediaAutoScale); - Assert.AreEqual(s.MediaDesc, t.MediaDesc); - Assert.AreEqual(s.MediaHeight, t.MediaHeight); - Assert.AreEqual(s.MediaID, t.MediaID); - Assert.AreEqual(s.MediaLoop, t.MediaLoop); - Assert.AreEqual(s.MediaType, t.MediaType); - Assert.AreEqual(s.MediaURL, t.MediaURL); - Assert.AreEqual(s.MediaWidth, t.MediaWidth); - Assert.AreEqual(s.MusicURL, t.MusicURL); - Assert.AreEqual(s.Name, t.Name); - Assert.AreEqual(s.ObscureMedia, t.ObscureMedia); - Assert.AreEqual(s.ObscureMusic, t.ObscureMusic); - Assert.AreEqual(s.OtherCleanTime, t.OtherCleanTime); - Assert.AreEqual(s.OtherCount, t.OtherCount); - Assert.AreEqual(s.OtherPrims, t.OtherPrims); - Assert.AreEqual(s.OwnerID, t.OwnerID); - Assert.AreEqual(s.OwnerPrims, t.OwnerPrims); - Assert.AreEqual(s.ParcelFlags, t.ParcelFlags); - Assert.AreEqual(s.ParcelPrimBonus, t.ParcelPrimBonus); - Assert.AreEqual(s.PassHours, t.PassHours); - Assert.AreEqual(s.PassPrice, t.PassPrice); - Assert.AreEqual(s.PublicCount, t.PublicCount); - Assert.AreEqual(s.RegionDenyAgeUnverified, t.RegionDenyAgeUnverified); - Assert.AreEqual(s.RegionDenyAnonymous, t.RegionDenyAnonymous); - Assert.AreEqual(s.RegionPushOverride, t.RegionPushOverride); - Assert.AreEqual(s.RentPrice, t.RentPrice); - Assert.AreEqual(s.RequestResult, t.RequestResult); - Assert.AreEqual(s.SalePrice, t.SalePrice); - Assert.AreEqual(s.SelectedPrims, t.SelectedPrims); - Assert.AreEqual(s.SelfCount, t.SelfCount); - Assert.AreEqual(s.SequenceID, t.SequenceID); - Assert.AreEqual(s.SimWideMaxPrims, t.SimWideMaxPrims); - Assert.AreEqual(s.SimWideTotalPrims, t.SimWideTotalPrims); - Assert.AreEqual(s.SnapSelection, t.SnapSelection); - Assert.AreEqual(s.SnapshotID, t.SnapshotID); - Assert.AreEqual(s.Status, t.Status); - Assert.AreEqual(s.TotalPrims, t.TotalPrims); - Assert.AreEqual(s.UserLocation, t.UserLocation); - Assert.AreEqual(s.UserLookAt, t.UserLookAt); + Assert.Equal(s.AABBMax, t.AABBMax); + Assert.Equal(s.AABBMin, t.AABBMin); + Assert.Equal(s.Area, t.Area); + Assert.Equal(s.AuctionID, t.AuctionID); + Assert.Equal(s.AuthBuyerID, t.AuthBuyerID); + Assert.Equal(s.Bitmap, t.Bitmap); + Assert.Equal(s.Category, t.Category); + Assert.Equal(s.ClaimDate, t.ClaimDate); + Assert.Equal(s.ClaimPrice, t.ClaimPrice); + Assert.Equal(s.Desc, t.Desc); + Assert.Equal(s.GroupID, t.GroupID); + Assert.Equal(s.GroupPrims, t.GroupPrims); + Assert.Equal(s.IsGroupOwned, t.IsGroupOwned); + Assert.Equal(s.LandingType, t.LandingType); + Assert.Equal(s.LocalID, t.LocalID); + Assert.Equal(s.MaxPrims, t.MaxPrims); + Assert.Equal(s.MediaAutoScale, t.MediaAutoScale); + Assert.Equal(s.MediaDesc, t.MediaDesc); + Assert.Equal(s.MediaHeight, t.MediaHeight); + Assert.Equal(s.MediaID, t.MediaID); + Assert.Equal(s.MediaLoop, t.MediaLoop); + Assert.Equal(s.MediaType, t.MediaType); + Assert.Equal(s.MediaURL, t.MediaURL); + Assert.Equal(s.MediaWidth, t.MediaWidth); + Assert.Equal(s.MusicURL, t.MusicURL); + Assert.Equal(s.Name, t.Name); + Assert.Equal(s.ObscureMedia, t.ObscureMedia); + Assert.Equal(s.ObscureMusic, t.ObscureMusic); + Assert.Equal(s.OtherCleanTime, t.OtherCleanTime); + Assert.Equal(s.OtherCount, t.OtherCount); + Assert.Equal(s.OtherPrims, t.OtherPrims); + Assert.Equal(s.OwnerID, t.OwnerID); + Assert.Equal(s.OwnerPrims, t.OwnerPrims); + Assert.Equal(s.ParcelFlags, t.ParcelFlags); + Assert.Equal(s.ParcelPrimBonus, t.ParcelPrimBonus); + Assert.Equal(s.PassHours, t.PassHours); + Assert.Equal(s.PassPrice, t.PassPrice); + Assert.Equal(s.PublicCount, t.PublicCount); + Assert.Equal(s.RegionDenyAgeUnverified, t.RegionDenyAgeUnverified); + Assert.Equal(s.RegionDenyAnonymous, t.RegionDenyAnonymous); + Assert.Equal(s.RegionPushOverride, t.RegionPushOverride); + Assert.Equal(s.RentPrice, t.RentPrice); + Assert.Equal(s.RequestResult, t.RequestResult); + Assert.Equal(s.SalePrice, t.SalePrice); + Assert.Equal(s.SelectedPrims, t.SelectedPrims); + Assert.Equal(s.SelfCount, t.SelfCount); + Assert.Equal(s.SequenceID, t.SequenceID); + Assert.Equal(s.SimWideMaxPrims, t.SimWideMaxPrims); + Assert.Equal(s.SimWideTotalPrims, t.SimWideTotalPrims); + Assert.Equal(s.SnapSelection, t.SnapSelection); + Assert.Equal(s.SnapshotID, t.SnapshotID); + Assert.Equal(s.Status, t.Status); + Assert.Equal(s.TotalPrims, t.TotalPrims); + Assert.Equal(s.UserLocation, t.UserLocation); + Assert.Equal(s.UserLookAt, t.UserLookAt); } TimeSpan duration = DateTime.UtcNow - messageTestTime; Console.WriteLine("ParcelPropertiesMessage: OMV Message System Serialization/Deserialization Passes: {0} Total time: {1}", TEST_ITER, duration); @@ -1555,73 +1565,76 @@ public void ReflectionPerformanceParcelProperties() s.UserLookAt = Vector3.Parse("<5,4,3>"); MemoryStream stream = new MemoryStream(); + byte[] llsdPayload = OSDParser.SerializeLLSDBinary(s.Serialize(), false); //formatter.Serialize(stream, s); - ZeroFormatter.ZeroFormatterSerializer.Serialize(stream, s); + MessagePackSerializer.Serialize(stream, llsdPayload, BenchmarkMessagePackOptions); stream.Seek(0, SeekOrigin.Begin); //ParcelPropertiesMessage t = (ParcelPropertiesMessage)formatter.Deserialize(stream); - ParcelPropertiesMessage t = ZeroFormatter.ZeroFormatterSerializer.Deserialize(stream); - - Assert.AreEqual(s.AABBMax, t.AABBMax); - Assert.AreEqual(s.AABBMin, t.AABBMin); - Assert.AreEqual(s.Area, t.Area); - Assert.AreEqual(s.AuctionID, t.AuctionID); - Assert.AreEqual(s.AuthBuyerID, t.AuthBuyerID); - Assert.AreEqual(s.Bitmap, t.Bitmap); - Assert.AreEqual(s.Category, t.Category); - Assert.AreEqual(s.ClaimDate, t.ClaimDate); - Assert.AreEqual(s.ClaimPrice, t.ClaimPrice); - Assert.AreEqual(s.Desc, t.Desc); - Assert.AreEqual(s.GroupID, t.GroupID); - Assert.AreEqual(s.GroupPrims, t.GroupPrims); - Assert.AreEqual(s.IsGroupOwned, t.IsGroupOwned); - Assert.AreEqual(s.LandingType, t.LandingType); - Assert.AreEqual(s.LocalID, t.LocalID); - Assert.AreEqual(s.MaxPrims, t.MaxPrims); - Assert.AreEqual(s.MediaAutoScale, t.MediaAutoScale); - Assert.AreEqual(s.MediaDesc, t.MediaDesc); - Assert.AreEqual(s.MediaHeight, t.MediaHeight); - Assert.AreEqual(s.MediaID, t.MediaID); - Assert.AreEqual(s.MediaLoop, t.MediaLoop); - Assert.AreEqual(s.MediaType, t.MediaType); - Assert.AreEqual(s.MediaURL, t.MediaURL); - Assert.AreEqual(s.MediaWidth, t.MediaWidth); - Assert.AreEqual(s.MusicURL, t.MusicURL); - Assert.AreEqual(s.Name, t.Name); - Assert.AreEqual(s.ObscureMedia, t.ObscureMedia); - Assert.AreEqual(s.ObscureMusic, t.ObscureMusic); - Assert.AreEqual(s.OtherCleanTime, t.OtherCleanTime); - Assert.AreEqual(s.OtherCount, t.OtherCount); - Assert.AreEqual(s.OtherPrims, t.OtherPrims); - Assert.AreEqual(s.OwnerID, t.OwnerID); - Assert.AreEqual(s.OwnerPrims, t.OwnerPrims); - Assert.AreEqual(s.ParcelFlags, t.ParcelFlags); - Assert.AreEqual(s.ParcelPrimBonus, t.ParcelPrimBonus); - Assert.AreEqual(s.PassHours, t.PassHours); - Assert.AreEqual(s.PassPrice, t.PassPrice); - Assert.AreEqual(s.PublicCount, t.PublicCount); - Assert.AreEqual(s.RegionDenyAgeUnverified, t.RegionDenyAgeUnverified); - Assert.AreEqual(s.RegionDenyAnonymous, t.RegionDenyAnonymous); - Assert.AreEqual(s.RegionPushOverride, t.RegionPushOverride); - Assert.AreEqual(s.RentPrice, t.RentPrice); - Assert.AreEqual(s.RequestResult, t.RequestResult); - Assert.AreEqual(s.SalePrice, t.SalePrice); - Assert.AreEqual(s.SelectedPrims, t.SelectedPrims); - Assert.AreEqual(s.SelfCount, t.SelfCount); - Assert.AreEqual(s.SequenceID, t.SequenceID); - Assert.AreEqual(s.SimWideMaxPrims, t.SimWideMaxPrims); - Assert.AreEqual(s.SimWideTotalPrims, t.SimWideTotalPrims); - Assert.AreEqual(s.SnapSelection, t.SnapSelection); - Assert.AreEqual(s.SnapshotID, t.SnapshotID); - Assert.AreEqual(s.Status, t.Status); - Assert.AreEqual(s.TotalPrims, t.TotalPrims); - Assert.AreEqual(s.UserLocation, t.UserLocation); - Assert.AreEqual(s.UserLookAt, t.UserLookAt); + byte[] unpackedLlsd = MessagePackSerializer.Deserialize(stream, BenchmarkMessagePackOptions); + ParcelPropertiesMessage t = new ParcelPropertiesMessage(); + t.Deserialize((OSDMap)OSDParser.DeserializeLLSDBinary(unpackedLlsd)); + + Assert.Equal(s.AABBMax, t.AABBMax); + Assert.Equal(s.AABBMin, t.AABBMin); + Assert.Equal(s.Area, t.Area); + Assert.Equal(s.AuctionID, t.AuctionID); + Assert.Equal(s.AuthBuyerID, t.AuthBuyerID); + Assert.Equal(s.Bitmap, t.Bitmap); + Assert.Equal(s.Category, t.Category); + Assert.Equal(s.ClaimDate, t.ClaimDate); + Assert.Equal(s.ClaimPrice, t.ClaimPrice); + Assert.Equal(s.Desc, t.Desc); + Assert.Equal(s.GroupID, t.GroupID); + Assert.Equal(s.GroupPrims, t.GroupPrims); + Assert.Equal(s.IsGroupOwned, t.IsGroupOwned); + Assert.Equal(s.LandingType, t.LandingType); + Assert.Equal(s.LocalID, t.LocalID); + Assert.Equal(s.MaxPrims, t.MaxPrims); + Assert.Equal(s.MediaAutoScale, t.MediaAutoScale); + Assert.Equal(s.MediaDesc, t.MediaDesc); + Assert.Equal(s.MediaHeight, t.MediaHeight); + Assert.Equal(s.MediaID, t.MediaID); + Assert.Equal(s.MediaLoop, t.MediaLoop); + Assert.Equal(s.MediaType, t.MediaType); + Assert.Equal(s.MediaURL, t.MediaURL); + Assert.Equal(s.MediaWidth, t.MediaWidth); + Assert.Equal(s.MusicURL, t.MusicURL); + Assert.Equal(s.Name, t.Name); + Assert.Equal(s.ObscureMedia, t.ObscureMedia); + Assert.Equal(s.ObscureMusic, t.ObscureMusic); + Assert.Equal(s.OtherCleanTime, t.OtherCleanTime); + Assert.Equal(s.OtherCount, t.OtherCount); + Assert.Equal(s.OtherPrims, t.OtherPrims); + Assert.Equal(s.OwnerID, t.OwnerID); + Assert.Equal(s.OwnerPrims, t.OwnerPrims); + Assert.Equal(s.ParcelFlags, t.ParcelFlags); + Assert.Equal(s.ParcelPrimBonus, t.ParcelPrimBonus); + Assert.Equal(s.PassHours, t.PassHours); + Assert.Equal(s.PassPrice, t.PassPrice); + Assert.Equal(s.PublicCount, t.PublicCount); + Assert.Equal(s.RegionDenyAgeUnverified, t.RegionDenyAgeUnverified); + Assert.Equal(s.RegionDenyAnonymous, t.RegionDenyAnonymous); + Assert.Equal(s.RegionPushOverride, t.RegionPushOverride); + Assert.Equal(s.RentPrice, t.RentPrice); + Assert.Equal(s.RequestResult, t.RequestResult); + Assert.Equal(s.SalePrice, t.SalePrice); + Assert.Equal(s.SelectedPrims, t.SelectedPrims); + Assert.Equal(s.SelfCount, t.SelfCount); + Assert.Equal(s.SequenceID, t.SequenceID); + Assert.Equal(s.SimWideMaxPrims, t.SimWideMaxPrims); + Assert.Equal(s.SimWideTotalPrims, t.SimWideTotalPrims); + Assert.Equal(s.SnapSelection, t.SnapSelection); + Assert.Equal(s.SnapshotID, t.SnapshotID); + Assert.Equal(s.Status, t.Status); + Assert.Equal(s.TotalPrims, t.TotalPrims); + Assert.Equal(s.UserLocation, t.UserLocation); + Assert.Equal(s.UserLookAt, t.UserLookAt); } TimeSpan durationxml = DateTime.UtcNow - xmlTestTime; - Console.WriteLine("ParcelPropertiesMessage: .NET BinarySerialization/Deserialization Passes: {0} Total time: {1}", TEST_ITER, durationxml); + Console.WriteLine("ParcelPropertiesMessage: MessagePack(LLSD binary payload) Serialization/Deserialization Passes: {0} Total time: {1}", TEST_ITER, durationxml); } #endregion diff --git a/OpenMetaverse.Tests/NetworkTests.cs b/OpenMetaverse.Tests/NetworkTests.cs index 39239e8d..ecdcf755 100644 --- a/OpenMetaverse.Tests/NetworkTests.cs +++ b/OpenMetaverse.Tests/NetworkTests.cs @@ -24,15 +24,15 @@ * POSSIBILITY OF SUCH DAMAGE. */ -using NUnit.Framework; +using Xunit; using OpenMetaverse.Packets; using System; namespace OpenMetaverse.Tests { - [TestFixture] - [Category("Network")] - public class NetworkTests : Assert + + [Trait("Category", "Network")] + public class NetworkTests : IDisposable { GridClient Client; @@ -50,27 +50,23 @@ public NetworkTests() // Register callbacks Client.Network.RegisterCallback(PacketType.ObjectUpdate, ObjectUpdateHandler); //Client.Self.OnTeleport += new MainAvatar.TeleportCallback(OnTeleportHandler) - } - [SetUp] - public void Init() - { Console.Write("Logging in Testing Anvil..."); // Connect to the grid string startLoc = NetworkManager.StartLocation("Hooper", 179, 18, 32); - Assert.IsTrue(Client.Network.Login("Testing", "Anvil", "testinganvil", "Unit Test Framework", startLoc, + Assert.True(Client.Network.Login("Testing", "Anvil", "testinganvil", "Unit Test Framework", startLoc, "contact@openmetaverse.co"), "Client failed to login, reason: " + Client.Network.LoginMessage); Console.WriteLine("Done"); - Assert.IsTrue(Client.Network.Connected, "Client is not connected to the grid"); + Assert.True(Client.Network.Connected, "Client is not connected to the grid"); //int start = Environment.TickCount; - Assert.AreEqual("hooper", Client.Network.CurrentSim.Name.ToLower(), "Logged in to sim " + - Client.Network.CurrentSim.Name + " instead of hooper"); + Assert.True(Client.Network.CurrentSim.Name.Equals("hooper", StringComparison.OrdinalIgnoreCase), + "Logged in to sim " + Client.Network.CurrentSim.Name + " instead of hooper"); } - [Test] + [Fact] public void DetectObjects() { int start = Environment.TickCount; @@ -78,13 +74,13 @@ public void DetectObjects() { if (Environment.TickCount - start > 20000) { - Assert.Fail("Timeout waiting for an ObjectUpdate packet"); + throw new Xunit.Sdk.XunitException("Timeout waiting for an ObjectUpdate packet"); } } } /* - [Test] + [Fact] public void U64Receive() { int start = Environment.TickCount; @@ -92,51 +88,51 @@ public void U64Receive() { if (Environment.TickCount - start > 10000) { - Assert.Fail("Timeout waiting for an ObjectUpdate packet"); + throw new Xunit.Sdk.XunitException("Timeout waiting for an ObjectUpdate packet"); } } - Assert.IsTrue(CurrentRegionHandle == HooperRegionHandle, "Current region is " + + Assert.True(CurrentRegionHandle == HooperRegionHandle, "Current region is " + CurrentRegionHandle + " (" + Client.Network.CurrentSim.Name + ")" + " when we were expecting " + HooperRegionHandle + " (Dore), possible endian issue"); } */ - /*[Test] + /*[Fact] public void Teleport() { // test in-sim teleports - Assert.IsTrue(CapsQueueRunning(), "CAPS Event queue is not running in " + Client.Network.CurrentSim.Name); + Assert.True(CapsQueueRunning(), "CAPS Event queue is not running in " + Client.Network.CurrentSim.Name); string localSimName = Client.Network.CurrentSim.Name; - Assert.IsTrue(Client.Self.Teleport(Client.Network.CurrentSim.Handle, new Vector3(121, 13, 41)), + Assert.True(Client.Self.Teleport(Client.Network.CurrentSim.Handle, new Vector3(121, 13, 41)), "Teleport In-Sim Failed " + Client.Network.CurrentSim.Name); // Assert that we really did make it to our scheduled destination - Assert.AreEqual(localSimName, Client.Network.CurrentSim.Name, + Assert.Equal(localSimName, Client.Network.CurrentSim.Name, "Expected to teleport to " + localSimName + ", ended up in " + Client.Network.CurrentSim.Name + ". Possibly region full or offline?"); - Assert.IsTrue(CapsQueueRunning(), "CAPS Event queue is not running in " + Client.Network.CurrentSim.Name); - Assert.IsTrue(Client.Self.Teleport(DoreRegionHandle, new Vector3(128, 128, 32)), + Assert.True(CapsQueueRunning(), "CAPS Event queue is not running in " + Client.Network.CurrentSim.Name); + Assert.True(Client.Self.Teleport(DoreRegionHandle, new Vector3(128, 128, 32)), "Teleport to Dore failed"); // Assert that we really did make it to our scheduled destination - Assert.AreEqual("dore", Client.Network.CurrentSim.Name.ToLower(), + Assert.Equal("dore", Client.Network.CurrentSim.Name.ToLower(), "Expected to teleport to Dore, ended up in " + Client.Network.CurrentSim.Name + ". Possibly region full or offline?"); - Assert.IsTrue(CapsQueueRunning(), "CAPS Event queue is not running in " + Client.Network.CurrentSim.Name); - Assert.IsTrue(Client.Self.Teleport(HooperRegionHandle, new Vector3(179, 18, 32)), + Assert.True(CapsQueueRunning(), "CAPS Event queue is not running in " + Client.Network.CurrentSim.Name); + Assert.True(Client.Self.Teleport(HooperRegionHandle, new Vector3(179, 18, 32)), "Teleport to Hooper failed"); // Assert that we really did make it to our scheduled destination - Assert.AreEqual("hooper", Client.Network.CurrentSim.Name.ToLower(), + Assert.Equal("hooper", Client.Network.CurrentSim.Name.ToLower(), "Expected to teleport to Hooper, ended up in " + Client.Network.CurrentSim.Name + ". Possibly region full or offline?"); }*/ - [Test] + [Fact] public void CapsQueue() { - Assert.IsTrue(CapsQueueRunning(), "CAPS Event Queue is not running and failed to start"); + Assert.True(CapsQueueRunning(), "CAPS Event Queue is not running and failed to start"); } public bool CapsQueueRunning() @@ -160,7 +156,7 @@ public bool CapsQueueRunning() else { Success = false; - Assert.Fail("Timeout waiting for event Queue to startup"); + throw new Xunit.Sdk.XunitException("Timeout waiting for event Queue to startup"); } Client.Network.EventQueueRunning -= capsRunning; return Success; @@ -174,8 +170,7 @@ private void ObjectUpdateHandler(object sender, PacketReceivedEventArgs e) //CurrentRegionHandle = update.RegionData.RegionHandle; } - [TearDown] - public void Shutdown() + public void Dispose() { Console.Write("Logging out..."); Client.Network.Logout(); diff --git a/OpenMetaverse.Tests/NotationLLSDTests.cs b/OpenMetaverse.Tests/NotationLLSDTests.cs index e7fddf28..a399a49d 100644 --- a/OpenMetaverse.Tests/NotationLLSDTests.cs +++ b/OpenMetaverse.Tests/NotationLLSDTests.cs @@ -36,7 +36,7 @@ * */ -using NUnit.Framework; +using Xunit; using OpenMetaverse.StructuredData; using System; using System.IO; @@ -46,265 +46,265 @@ namespace OpenMetaverse.Tests { - [TestFixture()] + public class NotationSDTests { - [Test()] + [Fact] public void HelperFunctions() { StringReader reader = new StringReader("test1tast2test3"); char[] charsOne = { 't', 'e', 's', 't' }; int resultOne = OSDParser.BufferCharactersEqual(reader, charsOne, 0); - Assert.AreEqual(charsOne.Length, resultOne); + Assert.Equal(charsOne.Length, resultOne); char[] charsTwo = { '1', 't', 'e' }; int resultTwo = OSDParser.BufferCharactersEqual(reader, charsTwo, 0); - Assert.AreEqual(2, resultTwo); + Assert.Equal(2, resultTwo); char[] charsThree = { 'a', 's', 't', '2', 't', 'e', 's' }; int resultThree = OSDParser.BufferCharactersEqual(reader, charsThree, 1); - Assert.AreEqual(1, resultThree); + Assert.Equal(1, resultThree); int resultFour = OSDParser.BufferCharactersEqual(reader, charsThree, 0); - Assert.AreEqual(charsThree.Length, resultFour); + Assert.Equal(charsThree.Length, resultFour); char[] charsFive = { 't', '3', 'a', 'a' }; int resultFive = OSDParser.BufferCharactersEqual(reader, charsFive, 0); - Assert.AreEqual(2, resultFive); + Assert.Equal(2, resultFive); } - [Test()] + [Fact] public void DeserializeUndef() { String s = "!"; OSD llsd = OSDParser.DeserializeLLSDNotation(s); - Assert.AreEqual(OSDType.Unknown, llsd.Type); + Assert.Equal(OSDType.Unknown, llsd.Type); } - [Test()] + [Fact] public void SerializeUndef() { OSD llsd = new OSD(); string s = OSDParser.SerializeLLSDNotation(llsd); OSD llsdDS = OSDParser.DeserializeLLSDNotation(s); - Assert.AreEqual(OSDType.Unknown, llsdDS.Type); + Assert.Equal(OSDType.Unknown, llsdDS.Type); } - [Test()] + [Fact] public void DeserializeBoolean() { String t = "true"; OSD llsdT = OSDParser.DeserializeLLSDNotation(t); - Assert.AreEqual(OSDType.Boolean, llsdT.Type); - Assert.AreEqual(true, llsdT.AsBoolean()); + Assert.Equal(OSDType.Boolean, llsdT.Type); + Assert.Equal(true, llsdT.AsBoolean()); String tTwo = "t"; OSD llsdTTwo = OSDParser.DeserializeLLSDNotation(tTwo); - Assert.AreEqual(OSDType.Boolean, llsdTTwo.Type); - Assert.AreEqual(true, llsdTTwo.AsBoolean()); + Assert.Equal(OSDType.Boolean, llsdTTwo.Type); + Assert.Equal(true, llsdTTwo.AsBoolean()); String tThree = "TRUE"; OSD llsdTThree = OSDParser.DeserializeLLSDNotation(tThree); - Assert.AreEqual(OSDType.Boolean, llsdTThree.Type); - Assert.AreEqual(true, llsdTThree.AsBoolean()); + Assert.Equal(OSDType.Boolean, llsdTThree.Type); + Assert.Equal(true, llsdTThree.AsBoolean()); String tFour = "T"; OSD llsdTFour = OSDParser.DeserializeLLSDNotation(tFour); - Assert.AreEqual(OSDType.Boolean, llsdTFour.Type); - Assert.AreEqual(true, llsdTFour.AsBoolean()); + Assert.Equal(OSDType.Boolean, llsdTFour.Type); + Assert.Equal(true, llsdTFour.AsBoolean()); String tFive = "1"; OSD llsdTFive = OSDParser.DeserializeLLSDNotation(tFive); - Assert.AreEqual(OSDType.Boolean, llsdTFive.Type); - Assert.AreEqual(true, llsdTFive.AsBoolean()); + Assert.Equal(OSDType.Boolean, llsdTFive.Type); + Assert.Equal(true, llsdTFive.AsBoolean()); String f = "false"; OSD llsdF = OSDParser.DeserializeLLSDNotation(f); - Assert.AreEqual(OSDType.Boolean, llsdF.Type); - Assert.AreEqual(false, llsdF.AsBoolean()); + Assert.Equal(OSDType.Boolean, llsdF.Type); + Assert.Equal(false, llsdF.AsBoolean()); String fTwo = "f"; OSD llsdFTwo = OSDParser.DeserializeLLSDNotation(fTwo); - Assert.AreEqual(OSDType.Boolean, llsdFTwo.Type); - Assert.AreEqual(false, llsdFTwo.AsBoolean()); + Assert.Equal(OSDType.Boolean, llsdFTwo.Type); + Assert.Equal(false, llsdFTwo.AsBoolean()); String fThree = "FALSE"; OSD llsdFThree = OSDParser.DeserializeLLSDNotation(fThree); - Assert.AreEqual(OSDType.Boolean, llsdFThree.Type); - Assert.AreEqual(false, llsdFThree.AsBoolean()); + Assert.Equal(OSDType.Boolean, llsdFThree.Type); + Assert.Equal(false, llsdFThree.AsBoolean()); String fFour = "F"; OSD llsdFFour = OSDParser.DeserializeLLSDNotation(fFour); - Assert.AreEqual(OSDType.Boolean, llsdFFour.Type); - Assert.AreEqual(false, llsdFFour.AsBoolean()); + Assert.Equal(OSDType.Boolean, llsdFFour.Type); + Assert.Equal(false, llsdFFour.AsBoolean()); String fFive = "0"; OSD llsdFFive = OSDParser.DeserializeLLSDNotation(fFive); - Assert.AreEqual(OSDType.Boolean, llsdFFive.Type); - Assert.AreEqual(false, llsdFFive.AsBoolean()); + Assert.Equal(OSDType.Boolean, llsdFFive.Type); + Assert.Equal(false, llsdFFive.AsBoolean()); } - [Test()] + [Fact] public void SerializeBoolean() { OSD llsdTrue = OSD.FromBoolean(true); string sTrue = OSDParser.SerializeLLSDNotation(llsdTrue); OSD llsdTrueDS = OSDParser.DeserializeLLSDNotation(sTrue); - Assert.AreEqual(OSDType.Boolean, llsdTrueDS.Type); - Assert.AreEqual(true, llsdTrueDS.AsBoolean()); + Assert.Equal(OSDType.Boolean, llsdTrueDS.Type); + Assert.Equal(true, llsdTrueDS.AsBoolean()); OSD llsdFalse = OSD.FromBoolean(false); string sFalse = OSDParser.SerializeLLSDNotation(llsdFalse); OSD llsdFalseDS = OSDParser.DeserializeLLSDNotation(sFalse); - Assert.AreEqual(OSDType.Boolean, llsdFalseDS.Type); - Assert.AreEqual(false, llsdFalseDS.AsBoolean()); + Assert.Equal(OSDType.Boolean, llsdFalseDS.Type); + Assert.Equal(false, llsdFalseDS.AsBoolean()); } - [Test()] + [Fact] public void DeserializeInteger() { string integerOne = "i12319423"; OSD llsdOne = OSDParser.DeserializeLLSDNotation(integerOne); - Assert.AreEqual(OSDType.Integer, llsdOne.Type); - Assert.AreEqual(12319423, llsdOne.AsInteger()); + Assert.Equal(OSDType.Integer, llsdOne.Type); + Assert.Equal(12319423, llsdOne.AsInteger()); string integerTwo = "i-489234"; OSD llsdTwo = OSDParser.DeserializeLLSDNotation(integerTwo); - Assert.AreEqual(OSDType.Integer, llsdTwo.Type); - Assert.AreEqual(-489234, llsdTwo.AsInteger()); + Assert.Equal(OSDType.Integer, llsdTwo.Type); + Assert.Equal(-489234, llsdTwo.AsInteger()); } - [Test()] + [Fact] public void SerializeInteger() { OSD llsdOne = OSD.FromInteger(12319423); string sOne = OSDParser.SerializeLLSDNotation(llsdOne); OSD llsdOneDS = OSDParser.DeserializeLLSDNotation(sOne); - Assert.AreEqual(OSDType.Integer, llsdOneDS.Type); - Assert.AreEqual(12319423, llsdOne.AsInteger()); + Assert.Equal(OSDType.Integer, llsdOneDS.Type); + Assert.Equal(12319423, llsdOne.AsInteger()); OSD llsdTwo = OSD.FromInteger(-71892034); string sTwo = OSDParser.SerializeLLSDNotation(llsdTwo); OSD llsdTwoDS = OSDParser.DeserializeLLSDNotation(sTwo); - Assert.AreEqual(OSDType.Integer, llsdTwoDS.Type); - Assert.AreEqual(-71892034, llsdTwoDS.AsInteger()); + Assert.Equal(OSDType.Integer, llsdTwoDS.Type); + Assert.Equal(-71892034, llsdTwoDS.AsInteger()); } - [Test()] + [Fact] public void DeserializeReal() { String realOne = "r1123412345.465711"; OSD llsdOne = OSDParser.DeserializeLLSDNotation(realOne); - Assert.AreEqual(OSDType.Real, llsdOne.Type); - Assert.AreEqual(1123412345.465711d, llsdOne.AsReal()); + Assert.Equal(OSDType.Real, llsdOne.Type); + Assert.Equal(1123412345.465711d, llsdOne.AsReal()); String realTwo = "r-11234684.923411"; OSD llsdTwo = OSDParser.DeserializeLLSDNotation(realTwo); - Assert.AreEqual(OSDType.Real, llsdTwo.Type); - Assert.AreEqual(-11234684.923411d, llsdTwo.AsReal()); + Assert.Equal(OSDType.Real, llsdTwo.Type); + Assert.Equal(-11234684.923411d, llsdTwo.AsReal()); String realThree = "r1"; OSD llsdThree = OSDParser.DeserializeLLSDNotation(realThree); - Assert.AreEqual(OSDType.Real, llsdThree.Type); - Assert.AreEqual(1d, llsdThree.AsReal()); + Assert.Equal(OSDType.Real, llsdThree.Type); + Assert.Equal(1d, llsdThree.AsReal()); String realFour = "r2.0193899999999998204e-06"; OSD llsdFour = OSDParser.DeserializeLLSDNotation(realFour); - Assert.AreEqual(OSDType.Real, llsdFour.Type); - Assert.AreEqual(2.0193899999999998204e-06d, llsdFour.AsReal()); + Assert.Equal(OSDType.Real, llsdFour.Type); + Assert.Equal(2.0193899999999998204e-06d, llsdFour.AsReal()); String realFive = "r0"; OSD llsdFive = OSDParser.DeserializeLLSDNotation(realFive); - Assert.AreEqual(OSDType.Real, llsdFive.Type); - Assert.AreEqual(0d, llsdFive.AsReal()); + Assert.Equal(OSDType.Real, llsdFive.Type); + Assert.Equal(0d, llsdFive.AsReal()); } - [Test()] + [Fact] public void SerializeReal() { OSD llsdOne = OSD.FromReal(12987234.723847d); string sOne = OSDParser.SerializeLLSDNotation(llsdOne); OSD llsdOneDS = OSDParser.DeserializeLLSDNotation(sOne); - Assert.AreEqual(OSDType.Real, llsdOneDS.Type); - Assert.AreEqual(12987234.723847d, llsdOneDS.AsReal()); + Assert.Equal(OSDType.Real, llsdOneDS.Type); + Assert.Equal(12987234.723847d, llsdOneDS.AsReal()); OSD llsdTwo = OSD.FromReal(-32347892.234234d); string sTwo = OSDParser.SerializeLLSDNotation(llsdTwo); OSD llsdTwoDS = OSDParser.DeserializeLLSDNotation(sTwo); - Assert.AreEqual(OSDType.Real, llsdTwoDS.Type); - Assert.AreEqual(-32347892.234234d, llsdTwoDS.AsReal()); + Assert.Equal(OSDType.Real, llsdTwoDS.Type); + Assert.Equal(-32347892.234234d, llsdTwoDS.AsReal()); OSD llsdThree = OSD.FromReal(Double.MaxValue); string sThree = OSDParser.SerializeLLSDNotation(llsdThree); OSD llsdThreeDS = OSDParser.DeserializeLLSDNotation(sThree); - Assert.AreEqual(OSDType.Real, llsdThreeDS.Type); - Assert.AreEqual(Double.MaxValue, llsdThreeDS.AsReal()); + Assert.Equal(OSDType.Real, llsdThreeDS.Type); + Assert.Equal(Double.MaxValue, llsdThreeDS.AsReal()); OSD llsdFour = OSD.FromReal(Double.MinValue); string sFour = OSDParser.SerializeLLSDNotation(llsdFour); OSD llsdFourDS = OSDParser.DeserializeLLSDNotation(sFour); - Assert.AreEqual(OSDType.Real, llsdFourDS.Type); - Assert.AreEqual(Double.MinValue, llsdFourDS.AsReal()); + Assert.Equal(OSDType.Real, llsdFourDS.Type); + Assert.Equal(Double.MinValue, llsdFourDS.AsReal()); OSD llsdFive = OSD.FromReal(-1.1123123E+50d); string sFive = OSDParser.SerializeLLSDNotation(llsdFive); OSD llsdFiveDS = OSDParser.DeserializeLLSDNotation(sFive); - Assert.AreEqual(OSDType.Real, llsdFiveDS.Type); - Assert.AreEqual(-1.1123123E+50d, llsdFiveDS.AsReal()); + Assert.Equal(OSDType.Real, llsdFiveDS.Type); + Assert.Equal(-1.1123123E+50d, llsdFiveDS.AsReal()); OSD llsdSix = OSD.FromReal(2.0193899999999998204e-06); string sSix = OSDParser.SerializeLLSDNotation(llsdSix); OSD llsdSixDS = OSDParser.DeserializeLLSDNotation(sSix); - Assert.AreEqual(OSDType.Real, llsdSixDS.Type); - Assert.AreEqual(2.0193899999999998204e-06, llsdSixDS.AsReal()); + Assert.Equal(OSDType.Real, llsdSixDS.Type); + Assert.Equal(2.0193899999999998204e-06, llsdSixDS.AsReal()); } - [Test()] + [Fact] public void DeserializeUUID() { String uuidOne = "u97f4aeca-88a1-42a1-b385-b97b18abb255"; OSD llsdOne = OSDParser.DeserializeLLSDNotation(uuidOne); - Assert.AreEqual(OSDType.UUID, llsdOne.Type); - Assert.AreEqual("97f4aeca-88a1-42a1-b385-b97b18abb255", llsdOne.AsString()); + Assert.Equal(OSDType.UUID, llsdOne.Type); + Assert.Equal("97f4aeca-88a1-42a1-b385-b97b18abb255", llsdOne.AsString()); String uuidTwo = "u00000000-0000-0000-0000-000000000000"; OSD llsdTwo = OSDParser.DeserializeLLSDNotation(uuidTwo); - Assert.AreEqual(OSDType.UUID, llsdTwo.Type); - Assert.AreEqual("00000000-0000-0000-0000-000000000000", llsdTwo.AsString()); + Assert.Equal(OSDType.UUID, llsdTwo.Type); + Assert.Equal("00000000-0000-0000-0000-000000000000", llsdTwo.AsString()); } - [Test()] + [Fact] public void SerializeUUID() { OSD llsdOne = OSD.FromUUID(new UUID("97f4aeca-88a1-42a1-b385-b97b18abb255")); string sOne = OSDParser.SerializeLLSDNotation(llsdOne); OSD llsdOneDS = OSDParser.DeserializeLLSDNotation(sOne); - Assert.AreEqual(OSDType.UUID, llsdOneDS.Type); - Assert.AreEqual("97f4aeca-88a1-42a1-b385-b97b18abb255", llsdOneDS.AsString()); + Assert.Equal(OSDType.UUID, llsdOneDS.Type); + Assert.Equal("97f4aeca-88a1-42a1-b385-b97b18abb255", llsdOneDS.AsString()); OSD llsdTwo = OSD.FromUUID(new UUID("00000000-0000-0000-0000-000000000000")); string sTwo = OSDParser.SerializeLLSDNotation(llsdTwo); OSD llsdTwoDS = OSDParser.DeserializeLLSDNotation(sTwo); - Assert.AreEqual(OSDType.UUID, llsdTwoDS.Type); - Assert.AreEqual("00000000-0000-0000-0000-000000000000", llsdTwoDS.AsString()); + Assert.Equal(OSDType.UUID, llsdTwoDS.Type); + Assert.Equal("00000000-0000-0000-0000-000000000000", llsdTwoDS.AsString()); } public void DeserializeString() { string sOne = "''"; OSD llsdOne = OSDParser.DeserializeLLSDNotation(sOne); - Assert.AreEqual(OSDType.String, llsdOne.Type); - Assert.AreEqual("", llsdOne.AsString()); + Assert.Equal(OSDType.String, llsdOne.Type); + Assert.Equal("", llsdOne.AsString()); // This is double escaping. Once for the encoding, and once for csharp. string sTwo = "'test\\'\"test'"; OSD llsdTwo = OSDParser.DeserializeLLSDNotation(sTwo); - Assert.AreEqual(OSDType.String, llsdTwo.Type); - Assert.AreEqual("test'\"test", llsdTwo.AsString()); + Assert.Equal(OSDType.String, llsdTwo.Type); + Assert.Equal("test'\"test", llsdTwo.AsString()); // "test \\lest" char[] cThree = { (char)0x27, (char)0x74, (char)0x65, (char)0x73, (char)0x74, (char)0x20, (char)0x5c, @@ -312,35 +312,35 @@ public void DeserializeString() string sThree = new string(cThree); OSD llsdThree = OSDParser.DeserializeLLSDNotation(sThree); - Assert.AreEqual(OSDType.String, llsdThree.Type); - Assert.AreEqual("test \\lest", llsdThree.AsString()); + Assert.Equal(OSDType.String, llsdThree.Type); + Assert.Equal("test \\lest", llsdThree.AsString()); string sFour = "'aa\t la'"; OSD llsdFour = OSDParser.DeserializeLLSDNotation(sFour); - Assert.AreEqual(OSDType.String, llsdFour.Type); - Assert.AreEqual("aa\t la", llsdFour.AsString()); + Assert.Equal(OSDType.String, llsdFour.Type); + Assert.Equal("aa\t la", llsdFour.AsString()); char[] cFive = { (char)0x27, (char)0x5c, (char)0x5c, (char)0x27 }; string sFive = new String(cFive); OSD llsdFive = OSDParser.DeserializeLLSDNotation(sFive); - Assert.AreEqual(OSDType.String, llsdFive.Type); - Assert.AreEqual("\\", llsdFive.AsString()); + Assert.Equal(OSDType.String, llsdFive.Type); + Assert.Equal("\\", llsdFive.AsString()); string sSix = "s(10)\"1234567890\""; OSD llsdSix = OSDParser.DeserializeLLSDNotation(sSix); - Assert.AreEqual(OSDType.String, llsdSix.Type); - Assert.AreEqual("1234567890", llsdSix.AsString()); + Assert.Equal(OSDType.String, llsdSix.Type); + Assert.Equal("1234567890", llsdSix.AsString()); string sSeven = "s(5)\"\\\\\\\\\\\""; OSD llsdSeven = OSDParser.DeserializeLLSDNotation(sSeven); - Assert.AreEqual(OSDType.String, llsdSeven.Type); - Assert.AreEqual("\\\\\\\\\\", llsdSeven.AsString()); + Assert.Equal(OSDType.String, llsdSeven.Type); + Assert.Equal("\\\\\\\\\\", llsdSeven.AsString()); string sEight = "\"aouAOUhsdjklfghskldjfghqeiurtzwieortzaslxfjkgh\""; OSD llsdEight = OSDParser.DeserializeLLSDNotation(sEight); - Assert.AreEqual(OSDType.String, llsdEight.Type); - Assert.AreEqual("aouAOUhsdjklfghskldjfghqeiurtzwieortzaslxfjkgh", llsdEight.AsString()); + Assert.Equal(OSDType.String, llsdEight.Type); + Assert.Equal("aouAOUhsdjklfghskldjfghqeiurtzwieortzaslxfjkgh", llsdEight.AsString()); @@ -351,12 +351,12 @@ public void DoSomeStringSerializingActionsAndAsserts(string s) OSD llsdOne = OSD.FromString(s); string sOne = OSDParser.SerializeLLSDNotation(llsdOne); OSD llsdOneDS = OSDParser.DeserializeLLSDNotation(sOne); - Assert.AreEqual(OSDType.String, llsdOne.Type); - Assert.AreEqual(s, llsdOneDS.AsString()); + Assert.Equal(OSDType.String, llsdOne.Type); + Assert.Equal(s, llsdOneDS.AsString()); } - [Test()] + [Fact] public void SerializeString() { DoSomeStringSerializingActionsAndAsserts(""); @@ -390,78 +390,78 @@ public void SerializeString() } - [Test()] + [Fact] public void DeserializeURI() { string sUriOne = "l\"http://test.com/test test>\\\"/&yes\""; OSD llsdOne = OSDParser.DeserializeLLSDNotation(sUriOne); - Assert.AreEqual(OSDType.URI, llsdOne.Type); - Assert.AreEqual("http://test.com/test%20test%3E%22/&yes", llsdOne.AsString()); + Assert.Equal(OSDType.URI, llsdOne.Type); + Assert.Equal("http://test.com/test%20test%3E%22/&yes", llsdOne.AsString()); string sUriTwo = "l\"test/test/test?test=1&toast=2\""; OSD llsdTwo = OSDParser.DeserializeLLSDNotation(sUriTwo); - Assert.AreEqual(OSDType.URI, llsdTwo.Type); - Assert.AreEqual("test/test/test?test=1&toast=2", llsdTwo.AsString()); + Assert.Equal(OSDType.URI, llsdTwo.Type); + Assert.Equal("test/test/test?test=1&toast=2", llsdTwo.AsString()); } - [Test()] + [Fact] public void SerializeURI() { Uri uriOne = new Uri("http://test.org/test test>\\\"/&yes\"", UriKind.RelativeOrAbsolute); OSD llsdOne = OSD.FromUri(uriOne); string sUriOne = OSDParser.SerializeLLSDNotation(llsdOne); OSD llsdOneDS = OSDParser.DeserializeLLSDNotation(sUriOne); - Assert.AreEqual(OSDType.URI, llsdOneDS.Type); - Assert.AreEqual(uriOne, llsdOneDS.AsUri()); + Assert.Equal(OSDType.URI, llsdOneDS.Type); + Assert.Equal(uriOne, llsdOneDS.AsUri()); Uri uriTwo = new Uri("test/test/near/the/end?test=1", UriKind.RelativeOrAbsolute); OSD llsdTwo = OSD.FromUri(uriTwo); string sUriTwo = OSDParser.SerializeLLSDNotation(llsdTwo); OSD llsdTwoDS = OSDParser.DeserializeLLSDNotation(sUriTwo); - Assert.AreEqual(OSDType.URI, llsdTwoDS.Type); - Assert.AreEqual(uriTwo, llsdTwoDS.AsUri()); + Assert.Equal(OSDType.URI, llsdTwoDS.Type); + Assert.Equal(uriTwo, llsdTwoDS.AsUri()); } - [Test()] + [Fact] public void DeserializeDate() { string sDateOne = "d\"2007-12-31T20:49:10Z\""; OSD llsdOne = OSDParser.DeserializeLLSDNotation(sDateOne); - Assert.AreEqual(OSDType.Date, llsdOne.Type); + Assert.Equal(OSDType.Date, llsdOne.Type); DateTime dt = new DateTime(2007, 12, 31, 20, 49, 10, 0, DateTimeKind.Utc); DateTime dtDS = llsdOne.AsDate(); - Assert.AreEqual(dt, dtDS.ToUniversalTime()); + Assert.Equal(dt, dtDS.ToUniversalTime()); } - [Test()] + [Fact] public void SerializeDate() { DateTime dtOne = new DateTime(2005, 8, 10, 11, 23, 4, DateTimeKind.Utc); OSD llsdOne = OSD.FromDate(dtOne); string sDtOne = OSDParser.SerializeLLSDNotation(llsdOne); OSD llsdOneDS = OSDParser.DeserializeLLSDNotation(sDtOne); - Assert.AreEqual(OSDType.Date, llsdOneDS.Type); + Assert.Equal(OSDType.Date, llsdOneDS.Type); DateTime dtOneDS = llsdOneDS.AsDate(); - Assert.AreEqual(dtOne, dtOneDS.ToUniversalTime()); + Assert.Equal(dtOne, dtOneDS.ToUniversalTime()); DateTime dtTwo = new DateTime(2010, 10, 11, 23, 00, 10, 100, DateTimeKind.Utc); OSD llsdTwo = OSD.FromDate(dtTwo); string sDtTwo = OSDParser.SerializeLLSDNotation(llsdTwo); OSD llsdTwoDS = OSDParser.DeserializeLLSDNotation(sDtTwo); - Assert.AreEqual(OSDType.Date, llsdTwoDS.Type); + Assert.Equal(OSDType.Date, llsdTwoDS.Type); DateTime dtTwoDS = llsdTwoDS.AsDate(); - Assert.AreEqual(dtTwo, dtTwoDS.ToUniversalTime()); + Assert.Equal(dtTwo, dtTwoDS.ToUniversalTime()); // check if a *local* time can be serialized and deserialized DateTime dtThree = new DateTime(2009, 12, 30, 8, 25, 10, DateTimeKind.Local); OSD llsdDateThree = OSD.FromDate(dtThree); string sDateThreeSerialized = OSDParser.SerializeLLSDNotation(llsdDateThree); OSD llsdDateThreeDS = OSDParser.DeserializeLLSDNotation(sDateThreeSerialized); - Assert.AreEqual(OSDType.Date, llsdDateThreeDS.Type); - Assert.AreEqual(dtThree, llsdDateThreeDS.AsDate()); + Assert.Equal(OSDType.Date, llsdDateThreeDS.Type); + Assert.Equal(dtThree, llsdDateThreeDS.AsDate()); } - [Test()] + [Fact] public void SerializeBinary() { byte[] binary = { 0x0, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0b, @@ -470,61 +470,61 @@ public void SerializeBinary() OSD llsdBinary = OSD.FromBinary(binary); string sBinarySerialized = OSDParser.SerializeLLSDNotation(llsdBinary); OSD llsdBinaryDS = OSDParser.DeserializeLLSDNotation(sBinarySerialized); - Assert.AreEqual(OSDType.Binary, llsdBinaryDS.Type); - Assert.AreEqual(binary, llsdBinaryDS.AsBinary()); + Assert.Equal(OSDType.Binary, llsdBinaryDS.Type); + Assert.Equal(binary, llsdBinaryDS.AsBinary()); } - [Test()] + [Fact] public void DeserializeArray() { string sArrayOne = "[]"; OSDArray llsdArrayOne = (OSDArray)OSDParser.DeserializeLLSDNotation(sArrayOne); - Assert.AreEqual(OSDType.Array, llsdArrayOne.Type); - Assert.AreEqual(0, llsdArrayOne.Count); + Assert.Equal(OSDType.Array, llsdArrayOne.Type); + Assert.Equal(0, llsdArrayOne.Count); string sArrayTwo = "[ i0 ]"; OSDArray llsdArrayTwo = (OSDArray)OSDParser.DeserializeLLSDNotation(sArrayTwo); - Assert.AreEqual(OSDType.Array, llsdArrayTwo.Type); - Assert.AreEqual(1, llsdArrayTwo.Count); + Assert.Equal(OSDType.Array, llsdArrayTwo.Type); + Assert.Equal(1, llsdArrayTwo.Count); OSDInteger llsdIntOne = (OSDInteger)llsdArrayTwo[0]; - Assert.AreEqual(OSDType.Integer, llsdIntOne.Type); - Assert.AreEqual(0, llsdIntOne.AsInteger()); + Assert.Equal(OSDType.Integer, llsdIntOne.Type); + Assert.Equal(0, llsdIntOne.AsInteger()); string sArrayThree = "[ i0, i1 ]"; OSDArray llsdArrayThree = (OSDArray)OSDParser.DeserializeLLSDNotation(sArrayThree); - Assert.AreEqual(OSDType.Array, llsdArrayThree.Type); - Assert.AreEqual(2, llsdArrayThree.Count); + Assert.Equal(OSDType.Array, llsdArrayThree.Type); + Assert.Equal(2, llsdArrayThree.Count); OSDInteger llsdIntTwo = (OSDInteger)llsdArrayThree[0]; - Assert.AreEqual(OSDType.Integer, llsdIntTwo.Type); - Assert.AreEqual(0, llsdIntTwo.AsInteger()); + Assert.Equal(OSDType.Integer, llsdIntTwo.Type); + Assert.Equal(0, llsdIntTwo.AsInteger()); OSDInteger llsdIntThree = (OSDInteger)llsdArrayThree[1]; - Assert.AreEqual(OSDType.Integer, llsdIntThree.Type); - Assert.AreEqual(1, llsdIntThree.AsInteger()); + Assert.Equal(OSDType.Integer, llsdIntThree.Type); + Assert.Equal(1, llsdIntThree.AsInteger()); string sArrayFour = " [ \"testtest\", \"aha\",t,f,i1, r1.2, [ i1] ] "; OSDArray llsdArrayFour = (OSDArray)OSDParser.DeserializeLLSDNotation(sArrayFour); - Assert.AreEqual(OSDType.Array, llsdArrayFour.Type); - Assert.AreEqual(7, llsdArrayFour.Count); - Assert.AreEqual("testtest", llsdArrayFour[0].AsString()); - Assert.AreEqual("aha", llsdArrayFour[1].AsString()); - Assert.AreEqual(true, llsdArrayFour[2].AsBoolean()); - Assert.AreEqual(false, llsdArrayFour[3].AsBoolean()); - Assert.AreEqual(1, llsdArrayFour[4].AsInteger()); - Assert.AreEqual(1.2d, llsdArrayFour[5].AsReal()); - Assert.AreEqual(OSDType.Array, llsdArrayFour[6].Type); + Assert.Equal(OSDType.Array, llsdArrayFour.Type); + Assert.Equal(7, llsdArrayFour.Count); + Assert.Equal("testtest", llsdArrayFour[0].AsString()); + Assert.Equal("aha", llsdArrayFour[1].AsString()); + Assert.Equal(true, llsdArrayFour[2].AsBoolean()); + Assert.Equal(false, llsdArrayFour[3].AsBoolean()); + Assert.Equal(1, llsdArrayFour[4].AsInteger()); + Assert.Equal(1.2d, llsdArrayFour[5].AsReal()); + Assert.Equal(OSDType.Array, llsdArrayFour[6].Type); OSDArray llsdArrayFive = (OSDArray)llsdArrayFour[6]; - Assert.AreEqual(1, llsdArrayFive[0].AsInteger()); + Assert.Equal(1, llsdArrayFive[0].AsInteger()); } - [Test()] + [Fact] public void SerializeArray() { OSDArray llsdOne = new OSDArray(); string sOne = OSDParser.SerializeLLSDNotation(llsdOne); OSDArray llsdOneDS = (OSDArray)OSDParser.DeserializeLLSDNotation(sOne); - Assert.AreEqual(OSDType.Array, llsdOneDS.Type); - Assert.AreEqual(0, llsdOneDS.Count); + Assert.Equal(OSDType.Array, llsdOneDS.Type); + Assert.Equal(0, llsdOneDS.Count); OSD llsdTwo = OSD.FromInteger(123234); OSD llsdThree = OSD.FromString("asedkfjhaqweiurohzasdf"); @@ -538,71 +538,71 @@ public void SerializeArray() string sFive = OSDParser.SerializeLLSDNotation(llsdOne); OSDArray llsdFive = (OSDArray)OSDParser.DeserializeLLSDNotation(sFive); - Assert.AreEqual(OSDType.Array, llsdFive.Type); - Assert.AreEqual(3, llsdFive.Count); - Assert.AreEqual(OSDType.Integer, llsdFive[0].Type); - Assert.AreEqual(123234, llsdFive[0].AsInteger()); - Assert.AreEqual(OSDType.String, llsdFive[1].Type); - Assert.AreEqual("asedkfjhaqweiurohzasdf", llsdFive[1].AsString()); + Assert.Equal(OSDType.Array, llsdFive.Type); + Assert.Equal(3, llsdFive.Count); + Assert.Equal(OSDType.Integer, llsdFive[0].Type); + Assert.Equal(123234, llsdFive[0].AsInteger()); + Assert.Equal(OSDType.String, llsdFive[1].Type); + Assert.Equal("asedkfjhaqweiurohzasdf", llsdFive[1].AsString()); OSDArray llsdSix = (OSDArray)llsdFive[2]; - Assert.AreEqual(OSDType.Array, llsdSix.Type); - Assert.AreEqual(2, llsdSix.Count); - Assert.AreEqual(OSDType.Integer, llsdSix[0].Type); - Assert.AreEqual(123234, llsdSix[0].AsInteger()); - Assert.AreEqual(OSDType.String, llsdSix[1].Type); - Assert.AreEqual("asedkfjhaqweiurohzasdf", llsdSix[1].AsString()); + Assert.Equal(OSDType.Array, llsdSix.Type); + Assert.Equal(2, llsdSix.Count); + Assert.Equal(OSDType.Integer, llsdSix[0].Type); + Assert.Equal(123234, llsdSix[0].AsInteger()); + Assert.Equal(OSDType.String, llsdSix[1].Type); + Assert.Equal("asedkfjhaqweiurohzasdf", llsdSix[1].AsString()); } - [Test()] + [Fact] public void DeserializeMap() { string sMapOne = " { } "; OSDMap llsdMapOne = (OSDMap)OSDParser.DeserializeLLSDNotation(sMapOne); - Assert.AreEqual(OSDType.Map, llsdMapOne.Type); - Assert.AreEqual(0, llsdMapOne.Count); + Assert.Equal(OSDType.Map, llsdMapOne.Type); + Assert.Equal(0, llsdMapOne.Count); string sMapTwo = " { \"test\":i2 } "; OSDMap llsdMapTwo = (OSDMap)OSDParser.DeserializeLLSDNotation(sMapTwo); - Assert.AreEqual(OSDType.Map, llsdMapTwo.Type); - Assert.AreEqual(1, llsdMapTwo.Count); - Assert.AreEqual(OSDType.Integer, llsdMapTwo["test"].Type); - Assert.AreEqual(2, llsdMapTwo["test"].AsInteger()); + Assert.Equal(OSDType.Map, llsdMapTwo.Type); + Assert.Equal(1, llsdMapTwo.Count); + Assert.Equal(OSDType.Integer, llsdMapTwo["test"].Type); + Assert.Equal(2, llsdMapTwo["test"].AsInteger()); string sMapThree = " { 'test':\"testtesttest\", 'aha':\"muahahaha\" , \"anywhere\":! } "; OSDMap llsdMapThree = (OSDMap)OSDParser.DeserializeLLSDNotation(sMapThree); - Assert.AreEqual(OSDType.Map, llsdMapThree.Type); - Assert.AreEqual(3, llsdMapThree.Count); - Assert.AreEqual(OSDType.String, llsdMapThree["test"].Type); - Assert.AreEqual("testtesttest", llsdMapThree["test"].AsString()); - Assert.AreEqual(OSDType.String, llsdMapThree["test"].Type); - Assert.AreEqual("muahahaha", llsdMapThree["aha"].AsString()); - Assert.AreEqual(OSDType.Unknown, llsdMapThree["self"].Type); + Assert.Equal(OSDType.Map, llsdMapThree.Type); + Assert.Equal(3, llsdMapThree.Count); + Assert.Equal(OSDType.String, llsdMapThree["test"].Type); + Assert.Equal("testtesttest", llsdMapThree["test"].AsString()); + Assert.Equal(OSDType.String, llsdMapThree["test"].Type); + Assert.Equal("muahahaha", llsdMapThree["aha"].AsString()); + Assert.Equal(OSDType.Unknown, llsdMapThree["self"].Type); string sMapFour = " { 'test' : { 'test' : i1, 't0st' : r2.5 }, 'tist' : \"hello world!\", 'tast' : \"last\" } "; OSDMap llsdMapFour = (OSDMap)OSDParser.DeserializeLLSDNotation(sMapFour); - Assert.AreEqual(OSDType.Map, llsdMapFour.Type); - Assert.AreEqual(3, llsdMapFour.Count); - Assert.AreEqual("hello world!", llsdMapFour["tist"].AsString()); - Assert.AreEqual("last", llsdMapFour["tast"].AsString()); + Assert.Equal(OSDType.Map, llsdMapFour.Type); + Assert.Equal(3, llsdMapFour.Count); + Assert.Equal("hello world!", llsdMapFour["tist"].AsString()); + Assert.Equal("last", llsdMapFour["tast"].AsString()); OSDMap llsdMapFive = (OSDMap)llsdMapFour["test"]; - Assert.AreEqual(OSDType.Map, llsdMapFive.Type); - Assert.AreEqual(2, llsdMapFive.Count); - Assert.AreEqual(OSDType.Integer, llsdMapFive["test"].Type); - Assert.AreEqual(1, llsdMapFive["test"].AsInteger()); - Assert.AreEqual(OSDType.Real, llsdMapFive["t0st"].Type); - Assert.AreEqual(2.5d, llsdMapFive["t0st"].AsReal()); + Assert.Equal(OSDType.Map, llsdMapFive.Type); + Assert.Equal(2, llsdMapFive.Count); + Assert.Equal(OSDType.Integer, llsdMapFive["test"].Type); + Assert.Equal(1, llsdMapFive["test"].AsInteger()); + Assert.Equal(OSDType.Real, llsdMapFive["t0st"].Type); + Assert.Equal(2.5d, llsdMapFive["t0st"].AsReal()); } - [Test()] + [Fact] public void SerializeMap() { OSDMap llsdOne = new OSDMap(); string sOne = OSDParser.SerializeLLSDNotation(llsdOne); OSDMap llsdOneDS = (OSDMap)OSDParser.DeserializeLLSDNotation(sOne); - Assert.AreEqual(OSDType.Map, llsdOneDS.Type); - Assert.AreEqual(0, llsdOneDS.Count); + Assert.Equal(OSDType.Map, llsdOneDS.Type); + Assert.Equal(0, llsdOneDS.Count); OSD llsdTwo = OSD.FromInteger(123234); OSD llsdThree = OSD.FromString("asedkfjhaqweiurohzasdf"); @@ -616,20 +616,20 @@ public void SerializeMap() string sFive = OSDParser.SerializeLLSDNotation(llsdOne); OSDMap llsdFive = (OSDMap)OSDParser.DeserializeLLSDNotation(sFive); - Assert.AreEqual(OSDType.Map, llsdFive.Type); - Assert.AreEqual(3, llsdFive.Count); - Assert.AreEqual(OSDType.Integer, llsdFive["test0"].Type); - Assert.AreEqual(123234, llsdFive["test0"].AsInteger()); - Assert.AreEqual(OSDType.String, llsdFive["test1"].Type); - Assert.AreEqual("asedkfjhaqweiurohzasdf", llsdFive["test1"].AsString()); + Assert.Equal(OSDType.Map, llsdFive.Type); + Assert.Equal(3, llsdFive.Count); + Assert.Equal(OSDType.Integer, llsdFive["test0"].Type); + Assert.Equal(123234, llsdFive["test0"].AsInteger()); + Assert.Equal(OSDType.String, llsdFive["test1"].Type); + Assert.Equal("asedkfjhaqweiurohzasdf", llsdFive["test1"].AsString()); OSDMap llsdSix = (OSDMap)llsdFive["test2"]; - Assert.AreEqual(OSDType.Map, llsdSix.Type); - Assert.AreEqual(2, llsdSix.Count); - Assert.AreEqual(OSDType.Integer, llsdSix["test0"].Type); - Assert.AreEqual(123234, llsdSix["test0"].AsInteger()); - Assert.AreEqual(OSDType.String, llsdSix["test1"].Type); - Assert.AreEqual("asedkfjhaqweiurohzasdf", llsdSix["test1"].AsString()); + Assert.Equal(OSDType.Map, llsdSix.Type); + Assert.Equal(2, llsdSix.Count); + Assert.Equal(OSDType.Integer, llsdSix["test0"].Type); + Assert.Equal(123234, llsdSix["test0"].AsInteger()); + Assert.Equal(OSDType.String, llsdSix["test1"].Type); + Assert.Equal("asedkfjhaqweiurohzasdf", llsdSix["test1"].AsString()); // We test here also for 4byte characters as map keys string xml = "𐄷"; @@ -643,12 +643,12 @@ public void SerializeMap() llsdSeven[content] = OSD.FromString(content); string sSeven = OSDParser.SerializeLLSDNotation(llsdSeven); OSDMap llsdSevenDS = (OSDMap)OSDParser.DeserializeLLSDNotation(sSeven); - Assert.AreEqual(OSDType.Map, llsdSevenDS.Type); - Assert.AreEqual(1, llsdSevenDS.Count); - Assert.AreEqual(content, llsdSevenDS[content].AsString()); + Assert.Equal(OSDType.Map, llsdSevenDS.Type); + Assert.Equal(1, llsdSevenDS.Count); + Assert.Equal(content, llsdSevenDS[content].AsString()); } - [Test()] + [Fact] public void DeserializeRealWorldExamples() { string realWorldExample = @" @@ -682,27 +682,27 @@ public void DeserializeRealWorldExamples() // We dont do full testing here. We are fine if a few values are right // and the parser doesnt throw an exception OSDArray llsdArray = (OSDArray)OSDParser.DeserializeLLSDNotation(realWorldExample); - Assert.AreEqual(OSDType.Array, llsdArray.Type); - Assert.AreEqual(3, llsdArray.Count); + Assert.Equal(OSDType.Array, llsdArray.Type); + Assert.Equal(3, llsdArray.Count); OSDMap llsdMapOne = (OSDMap)llsdArray[0]; - Assert.AreEqual(OSDType.Map, llsdMapOne.Type); - Assert.AreEqual("http://secondlife.com", llsdMapOne["destination"].AsString()); + Assert.Equal(OSDType.Map, llsdMapOne.Type); + Assert.Equal("http://secondlife.com", llsdMapOne["destination"].AsString()); OSDMap llsdMapTwo = (OSDMap)llsdArray[1]; - Assert.AreEqual(OSDType.Map, llsdMapTwo.Type); - Assert.AreEqual(OSDType.Integer, llsdMapTwo["version"].Type); - Assert.AreEqual(1, llsdMapTwo["version"].AsInteger()); + Assert.Equal(OSDType.Map, llsdMapTwo.Type); + Assert.Equal(OSDType.Integer, llsdMapTwo["version"].Type); + Assert.Equal(1, llsdMapTwo["version"].AsInteger()); OSDMap llsdMapThree = (OSDMap)llsdArray[2]; - Assert.AreEqual(OSDType.UUID, llsdMapThree["session_id"].Type); - Assert.AreEqual("2c585cec-038c-40b0-b42e-a25ebab4d132", llsdMapThree["session_id"].AsString()); - Assert.AreEqual(OSDType.UUID, llsdMapThree["agent_id"].Type); - Assert.AreEqual("3c115e51-04f4-523c-9fa6-98aff1034730", llsdMapThree["agent_id"].AsString()); + Assert.Equal(OSDType.UUID, llsdMapThree["session_id"].Type); + Assert.Equal("2c585cec-038c-40b0-b42e-a25ebab4d132", llsdMapThree["session_id"].AsString()); + Assert.Equal(OSDType.UUID, llsdMapThree["agent_id"].Type); + Assert.Equal("3c115e51-04f4-523c-9fa6-98aff1034730", llsdMapThree["agent_id"].AsString()); } - [Test()] + [Fact] public void SerializeFormattedTest() { // This is not a real test. Instead look at the console.out tab for how formatted notation looks like. @@ -732,14 +732,14 @@ public void SerializeFormattedTest() // we also try to parse this... and look a little at the results OSDArray llsdSeven = (OSDArray)OSDParser.DeserializeLLSDNotation(sThree); - Assert.AreEqual(OSDType.Array, llsdSeven.Type); - Assert.AreEqual(3, llsdSeven.Count); - Assert.AreEqual(OSDType.Integer, llsdSeven[0].Type); - Assert.AreEqual(1, llsdSeven[0].AsInteger()); - Assert.AreEqual(OSDType.Integer, llsdSeven[1].Type); - Assert.AreEqual(1, llsdSeven[1].AsInteger()); - - Assert.AreEqual(OSDType.Map, llsdSeven[2].Type); + Assert.Equal(OSDType.Array, llsdSeven.Type); + Assert.Equal(3, llsdSeven.Count); + Assert.Equal(OSDType.Integer, llsdSeven[0].Type); + Assert.Equal(1, llsdSeven[0].AsInteger()); + Assert.Equal(OSDType.Integer, llsdSeven[1].Type); + Assert.Equal(1, llsdSeven[1].AsInteger()); + + Assert.Equal(OSDType.Map, llsdSeven[2].Type); // thats enough for now. } } diff --git a/OpenMetaverse.Tests/OpenMetaverse.Tests.csproj b/OpenMetaverse.Tests/OpenMetaverse.Tests.csproj index 7eb39807..f59215b3 100644 --- a/OpenMetaverse.Tests/OpenMetaverse.Tests.csproj +++ b/OpenMetaverse.Tests/OpenMetaverse.Tests.csproj @@ -1,10 +1,14 @@  Local + true + false - - + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/OpenMetaverse.Tests/PacketTests.cs b/OpenMetaverse.Tests/PacketTests.cs index 3f1b340b..907963cf 100644 --- a/OpenMetaverse.Tests/PacketTests.cs +++ b/OpenMetaverse.Tests/PacketTests.cs @@ -24,15 +24,15 @@ * POSSIBILITY OF SUCH DAMAGE. */ -using NUnit.Framework; +using Xunit; using OpenMetaverse.Packets; namespace OpenMetaverse.Tests { - [TestFixture] - public class PacketTests : Assert + + public class PacketTests { - [Test] + [Fact] public void HeaderFlags() { TestMessagePacket packet = new TestMessagePacket(); @@ -42,53 +42,53 @@ public void HeaderFlags() packet.Header.Resent = false; packet.Header.Zerocoded = false; - Assert.IsFalse(packet.Header.AppendedAcks, "AppendedAcks: Failed to initially set the flag to false"); - Assert.IsFalse(packet.Header.Reliable, "Reliable: Failed to initially set the flag to false"); - Assert.IsFalse(packet.Header.Resent, "Resent: Failed to initially set the flag to false"); - Assert.IsFalse(packet.Header.Zerocoded, "Zerocoded: Failed to initially set the flag to false"); + Assert.False(packet.Header.AppendedAcks, "AppendedAcks: Failed to initially set the flag to false"); + Assert.False(packet.Header.Reliable, "Reliable: Failed to initially set the flag to false"); + Assert.False(packet.Header.Resent, "Resent: Failed to initially set the flag to false"); + Assert.False(packet.Header.Zerocoded, "Zerocoded: Failed to initially set the flag to false"); packet.Header.AppendedAcks = false; packet.Header.Reliable = false; packet.Header.Resent = false; packet.Header.Zerocoded = false; - Assert.IsFalse(packet.Header.AppendedAcks, "AppendedAcks: Failed to set the flag to false a second time"); - Assert.IsFalse(packet.Header.Reliable, "Reliable: Failed to set the flag to false a second time"); - Assert.IsFalse(packet.Header.Resent, "Resent: Failed to set the flag to false a second time"); - Assert.IsFalse(packet.Header.Zerocoded, "Zerocoded: Failed to set the flag to false a second time"); + Assert.False(packet.Header.AppendedAcks, "AppendedAcks: Failed to set the flag to false a second time"); + Assert.False(packet.Header.Reliable, "Reliable: Failed to set the flag to false a second time"); + Assert.False(packet.Header.Resent, "Resent: Failed to set the flag to false a second time"); + Assert.False(packet.Header.Zerocoded, "Zerocoded: Failed to set the flag to false a second time"); packet.Header.AppendedAcks = true; packet.Header.Reliable = true; packet.Header.Resent = true; packet.Header.Zerocoded = true; - Assert.IsTrue(packet.Header.AppendedAcks, "AppendedAcks: Failed to set the flag to true"); - Assert.IsTrue(packet.Header.Reliable, "Reliable: Failed to set the flag to true"); - Assert.IsTrue(packet.Header.Resent, "Resent: Failed to set the flag to true"); - Assert.IsTrue(packet.Header.Zerocoded, "Zerocoded: Failed to set the flag to true"); + Assert.True(packet.Header.AppendedAcks, "AppendedAcks: Failed to set the flag to true"); + Assert.True(packet.Header.Reliable, "Reliable: Failed to set the flag to true"); + Assert.True(packet.Header.Resent, "Resent: Failed to set the flag to true"); + Assert.True(packet.Header.Zerocoded, "Zerocoded: Failed to set the flag to true"); packet.Header.AppendedAcks = true; packet.Header.Reliable = true; packet.Header.Resent = true; packet.Header.Zerocoded = true; - Assert.IsTrue(packet.Header.AppendedAcks, "AppendedAcks: Failed to set the flag to true a second time"); - Assert.IsTrue(packet.Header.Reliable, "Reliable: Failed to set the flag to true a second time"); - Assert.IsTrue(packet.Header.Resent, "Resent: Failed to set the flag to true a second time"); - Assert.IsTrue(packet.Header.Zerocoded, "Zerocoded: Failed to set the flag to true a second time"); + Assert.True(packet.Header.AppendedAcks, "AppendedAcks: Failed to set the flag to true a second time"); + Assert.True(packet.Header.Reliable, "Reliable: Failed to set the flag to true a second time"); + Assert.True(packet.Header.Resent, "Resent: Failed to set the flag to true a second time"); + Assert.True(packet.Header.Zerocoded, "Zerocoded: Failed to set the flag to true a second time"); packet.Header.AppendedAcks = false; packet.Header.Reliable = false; packet.Header.Resent = false; packet.Header.Zerocoded = false; - Assert.IsFalse(packet.Header.AppendedAcks, "AppendedAcks: Failed to set the flag back to false"); - Assert.IsFalse(packet.Header.Reliable, "Reliable: Failed to set the flag back to false"); - Assert.IsFalse(packet.Header.Resent, "Resent: Failed to set the flag back to false"); - Assert.IsFalse(packet.Header.Zerocoded, "Zerocoded: Failed to set the flag back to false"); + Assert.False(packet.Header.AppendedAcks, "AppendedAcks: Failed to set the flag back to false"); + Assert.False(packet.Header.Reliable, "Reliable: Failed to set the flag back to false"); + Assert.False(packet.Header.Resent, "Resent: Failed to set the flag back to false"); + Assert.False(packet.Header.Zerocoded, "Zerocoded: Failed to set the flag back to false"); } - [Test] + [Fact] public void ToBytesMultiple() { UUID testID = UUID.Random(); @@ -134,13 +134,13 @@ public void ToBytesMultiple() int len = packetData.Length; DirPlacesReplyPacket packet = (DirPlacesReplyPacket)Packet.BuildPacket(packetData, ref len, packetData); - Assert.IsTrue(packet.AgentData.AgentID == bigPacket.AgentData.AgentID); + Assert.True(packet.AgentData.AgentID == bigPacket.AgentData.AgentID); for (int j = 0; j < packet.QueryReplies.Length; j++) { - Assert.IsTrue(packet.QueryReplies[j].Dwell == (float)(queryRepliesCount + j), + Assert.True(packet.QueryReplies[j].Dwell == (float)(queryRepliesCount + j), "Expected Dwell of " + (float)(queryRepliesCount + j) + " but got " + packet.QueryReplies[j].Dwell); - Assert.IsTrue(packet.QueryReplies[j].ParcelID == testID); + Assert.True(packet.QueryReplies[j].ParcelID == testID); } queryDataCount += packet.QueryData.Length; @@ -148,9 +148,9 @@ public void ToBytesMultiple() statusDataCount += packet.StatusData.Length; } - Assert.IsTrue(queryDataCount == bigPacket.QueryData.Length); - Assert.IsTrue(queryRepliesCount == bigPacket.QueryData.Length); - Assert.IsTrue(statusDataCount == bigPacket.StatusData.Length); + Assert.True(queryDataCount == bigPacket.QueryData.Length); + Assert.True(queryRepliesCount == bigPacket.QueryData.Length); + Assert.True(statusDataCount == bigPacket.StatusData.Length); ScriptDialogPacket scriptDialogPacket = new ScriptDialogPacket(); scriptDialogPacket.Data.ChatChannel = 0; @@ -167,8 +167,8 @@ public void ToBytesMultiple() byte[][] splitPacket = scriptDialogPacket.ToBytesMultiple(); - Assert.IsNotNull(splitPacket); - Assert.IsTrue(splitPacket.Length == 1, "Expected ScriptDialog packet to split into 1 packet but got " + splitPacket.Length); + Assert.NotNull(splitPacket); + Assert.True(splitPacket.Length == 1, "Expected ScriptDialog packet to split into 1 packet but got " + splitPacket.Length); ParcelReturnObjectsPacket proPacket = new ParcelReturnObjectsPacket(); proPacket.AgentData.AgentID = UUID.Zero; @@ -182,8 +182,8 @@ public void ToBytesMultiple() splitPacket = proPacket.ToBytesMultiple(); - Assert.IsNotNull(splitPacket); - Assert.IsTrue(splitPacket.Length == 1, "Expected ParcelReturnObjectsPacket packet to split into 1 packet but got " + splitPacket.Length); + Assert.NotNull(splitPacket); + Assert.True(splitPacket.Length == 1, "Expected ParcelReturnObjectsPacket packet to split into 1 packet but got " + splitPacket.Length); InventoryDescendentsPacket invPacket = new InventoryDescendentsPacket(); invPacket.FolderData = new InventoryDescendentsPacket.FolderDataBlock[1]; @@ -199,15 +199,15 @@ public void ToBytesMultiple() splitPacket = invPacket.ToBytesMultiple(); - Assert.IsNotNull(splitPacket); - Assert.IsTrue(splitPacket.Length == 1, "Split InventoryDescendents packet into " + splitPacket.Length + " instead of 1 packet"); + Assert.NotNull(splitPacket); + Assert.True(splitPacket.Length == 1, "Split InventoryDescendents packet into " + splitPacket.Length + " instead of 1 packet"); int x = 0; int y = splitPacket[0].Length - 1; invPacket.FromBytes(splitPacket[0], ref x, ref y, null); - Assert.IsTrue(invPacket.FolderData.Length == 1, "InventoryDescendents packet came back with " + invPacket.FolderData.Length + " FolderData blocks"); - Assert.IsTrue(invPacket.ItemData.Length == 5, "InventoryDescendents packet came back with " + invPacket.ItemData.Length + " ItemData blocks"); + Assert.True(invPacket.FolderData.Length == 1, "InventoryDescendents packet came back with " + invPacket.FolderData.Length + " FolderData blocks"); + Assert.True(invPacket.ItemData.Length == 5, "InventoryDescendents packet came back with " + invPacket.ItemData.Length + " ItemData blocks"); } } } diff --git a/OpenMetaverse.Tests/PrimObjectTests.cs b/OpenMetaverse.Tests/PrimObjectTests.cs index d8d5a861..81b4fcfe 100644 --- a/OpenMetaverse.Tests/PrimObjectTests.cs +++ b/OpenMetaverse.Tests/PrimObjectTests.cs @@ -24,15 +24,15 @@ * POSSIBILITY OF SUCH DAMAGE. */ -using NUnit.Framework; +using Xunit; using System; namespace OpenMetaverse.Tests { - [TestFixture] - public class PrimObjectTests : Assert + + public class PrimObjectTests { - [Test] + [Fact] public void PathBegin() { for (byte i = 0; i < byte.MaxValue; i++) @@ -40,12 +40,12 @@ public void PathBegin() float floatValue = Primitive.UnpackBeginCut(i); ushort result = Primitive.PackBeginCut(floatValue); - Assert.IsTrue(result == i, "Started with " + i + ", float value was " + floatValue + + Assert.True(result == i, "Started with " + i + ", float value was " + floatValue + ", and ended up with " + result); } } - [Test] + [Fact] public void PathEnd() { for (byte i = 0; i < byte.MaxValue; i++) @@ -53,12 +53,12 @@ public void PathEnd() float floatValue = Primitive.UnpackEndCut(i); ushort result = Primitive.PackEndCut(floatValue); - Assert.IsTrue(result == i, "Started with " + i + ", float value was " + floatValue + + Assert.True(result == i, "Started with " + i + ", float value was " + floatValue + ", and ended up with " + result); } } - [Test] + [Fact] public void PathRevolutions() { for (byte i = 0; i < byte.MaxValue; i++) @@ -66,12 +66,12 @@ public void PathRevolutions() float floatValue = Primitive.UnpackPathRevolutions(i); byte result = Primitive.PackPathRevolutions(floatValue); - Assert.IsTrue(result == i, "Started with " + i + ", float value was " + floatValue + + Assert.True(result == i, "Started with " + i + ", float value was " + floatValue + ", and ended up with " + result); } } - [Test] + [Fact] public void PathScale() { for (byte i = 0; i < byte.MaxValue; i++) @@ -79,12 +79,12 @@ public void PathScale() float floatValue = Primitive.UnpackPathScale(i); byte result = Primitive.PackPathScale(floatValue); - Assert.IsTrue(result == i, "Started with " + i + ", float value was " + floatValue + + Assert.True(result == i, "Started with " + i + ", float value was " + floatValue + ", and ended up with " + result); } } - //[Test] + //[Fact] //public void PathShear() //{ // for (byte i = 0; i < byte.MaxValue; i++) @@ -92,12 +92,12 @@ public void PathScale() // float floatValue = Primitive.UnpackPathShear(i); // byte result = Primitive.PackPathShear(floatValue); - // Assert.IsTrue(result == i, "Started with " + i + ", float value was " + floatValue + + // Assert.True(result == i, "Started with " + i + ", float value was " + floatValue + // ", and ended up with " + result); // } //} - [Test] + [Fact] public void PathTaper() { for (sbyte i = sbyte.MinValue; i < sbyte.MaxValue; i++) @@ -105,12 +105,12 @@ public void PathTaper() float floatValue = Primitive.UnpackPathTaper(i); sbyte result = Primitive.PackPathTaper(floatValue); - Assert.IsTrue(result == i, "Started with " + i + ", float value was " + floatValue + + Assert.True(result == i, "Started with " + i + ", float value was " + floatValue + ", and ended up with " + result); } } - [Test] + [Fact] public void TextureEntryOffsets() { for (float i = -1.0f; i <= 1.0f; i += 0.001f) @@ -121,11 +121,11 @@ public void TextureEntryOffsets() float foffset = Helpers.TEOffsetFloat(BitConverter.GetBytes(offset), 0); foffset = (float)Math.Round(foffset, 3); - Assert.IsTrue(foffset - i < Single.Epsilon, foffset + " is not equal to " + i); + Assert.True(foffset - i < Single.Epsilon, foffset + " is not equal to " + i); } } - [Test] + [Fact] public void TextureEntry() { Primitive.TextureEntry te = new Primitive.TextureEntry(UUID.Random()); @@ -149,11 +149,11 @@ public void TextureEntry() byte[] teBytes2 = te2.GetBytes(); - Assert.IsTrue(teBytes.Length == teBytes2.Length); + Assert.True(teBytes.Length == teBytes2.Length); for (int i = 0; i < teBytes.Length; i++) { - Assert.IsTrue(teBytes[i] == teBytes2[i], "Byte " + i + " is not equal"); + Assert.True(teBytes[i] == teBytes2[i], "Byte " + i + " is not equal"); } } } diff --git a/OpenMetaverse.Tests/TypeTests.cs b/OpenMetaverse.Tests/TypeTests.cs index 1e960713..8e94c27c 100644 --- a/OpenMetaverse.Tests/TypeTests.cs +++ b/OpenMetaverse.Tests/TypeTests.cs @@ -24,24 +24,24 @@ * POSSIBILITY OF SUCH DAMAGE. */ -using NUnit.Framework; +using Xunit; using OpenMetaverse.StructuredData; using System; using System.Collections.Generic; namespace OpenMetaverse.Tests { - [TestFixture] - public class TypeTests : Assert + + public class TypeTests { - [Test] + [Fact] public void UUIDs() { // Creation UUID a = new UUID(); byte[] bytes = a.GetBytes(); for (int i = 0; i < 16; i++) - Assert.IsTrue(bytes[i] == 0x00); + Assert.True(bytes[i] == 0x00); // Comparison a = new UUID(new byte[] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, @@ -49,7 +49,7 @@ public void UUIDs() UUID b = new UUID(new byte[] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F }, 0); - Assert.IsTrue(a == b, "UUID comparison operator failed, " + a.ToString() + " should equal " + + Assert.True(a == b, "UUID comparison operator failed, " + a.ToString() + " should equal " + b.ToString()); // From string @@ -58,45 +58,45 @@ public void UUIDs() string zeroonetwo = "00010203-0405-0607-0809-0a0b0c0d0e0f"; b = new UUID(zeroonetwo); - Assert.IsTrue(a == b, "UUID hyphenated string constructor failed, should have " + a.ToString() + + Assert.True(a == b, "UUID hyphenated string constructor failed, should have " + a.ToString() + " but we got " + b.ToString()); // ToString() - Assert.IsTrue(a == b); - Assert.IsTrue(a == (UUID)zeroonetwo); + Assert.True(a == b); + Assert.True(a == (UUID)zeroonetwo); // TODO: CRC test } - [Test] + [Fact] public void Vector3ApproxEquals() { Vector3 a = new Vector3(1f, 0f, 0f); Vector3 b = new Vector3(0f, 0f, 0f); - Assert.IsFalse(a.ApproxEquals(b, 0.9f), "ApproxEquals failed (1)"); - Assert.IsTrue(a.ApproxEquals(b, 1.0f), "ApproxEquals failed (2)"); + Assert.False(a.ApproxEquals(b, 0.9f), "ApproxEquals failed (1)"); + Assert.True(a.ApproxEquals(b, 1.0f), "ApproxEquals failed (2)"); a = new Vector3(-1f, 0f, 0f); b = new Vector3(1f, 0f, 0f); - Assert.IsFalse(a.ApproxEquals(b, 1.9f), "ApproxEquals failed (3)"); - Assert.IsTrue(a.ApproxEquals(b, 2.0f), "ApproxEquals failed (4)"); + Assert.False(a.ApproxEquals(b, 1.9f), "ApproxEquals failed (3)"); + Assert.True(a.ApproxEquals(b, 2.0f), "ApproxEquals failed (4)"); a = new Vector3(0f, -1f, 0f); b = new Vector3(0f, -1.1f, 0f); - Assert.IsFalse(a.ApproxEquals(b, 0.09f), "ApproxEquals failed (5)"); - Assert.IsTrue(a.ApproxEquals(b, 0.11f), "ApproxEquals failed (6)"); + Assert.False(a.ApproxEquals(b, 0.09f), "ApproxEquals failed (5)"); + Assert.True(a.ApproxEquals(b, 0.11f), "ApproxEquals failed (6)"); a = new Vector3(0f, 0f, 0.00001f); b = new Vector3(0f, 0f, 0f); - Assert.IsFalse(b.ApproxEquals(a, Single.Epsilon), "ApproxEquals failed (6)"); - Assert.IsTrue(b.ApproxEquals(a, 0.0001f), "ApproxEquals failed (7)"); + Assert.False(b.ApproxEquals(a, Single.Epsilon), "ApproxEquals failed (6)"); + Assert.True(b.ApproxEquals(a, 0.0001f), "ApproxEquals failed (7)"); } - [Test] + [Fact] public void VectorCasting() { Dictionary testNumbers; @@ -133,41 +133,41 @@ public void VectorCasting() } else { - Assert.IsFalse(a == b, string.Format( + Assert.False(a == b, string.Format( "Vector casting failed, precision loss should" + " have occurred. " + "{0}: {1}, {2}", kvp.Key, a.X, b.X)); - Assert.IsFalse(b == d, string.Format( + Assert.False(b == d, string.Format( "Vector casting failed, explicit cast of double" + " to float should result in precision loss" + " whichwas should not magically disappear when" + " Vector3 is implicitly cast to Vector3d." + " {0}: {1}, {2}", kvp.Key, b.X, d.X)); } - Assert.IsTrue(a == c, string.Format( + Assert.True(a == c, string.Format( "Vector casting failed, Vector3 compared to" + " explicit cast of Vector3d to Vector3 should" + " result in identical precision loss." + " {0}: {1}, {2}", kvp.Key, a.X, c.X)); - Assert.IsTrue(a == d, string.Format( + Assert.True(a == d, string.Format( "Vector casting failed, implicit cast of Vector3" + " to Vector3d should not result in precision loss." + " {0}: {1}, {2}", kvp.Key, a.X, d.X)); } } - [Test] + [Fact] public void Quaternions() { Quaternion a = new Quaternion(1, 0, 0, 0); Quaternion b = new Quaternion(1, 0, 0, 0); - Assert.IsTrue(a == b, "Quaternion comparison operator failed"); + Assert.True(a == b, "Quaternion comparison operator failed"); Quaternion expected = new Quaternion(0, 0, 0, -1); Quaternion result = a * b; - Assert.IsTrue(result == expected, a.ToString() + " * " + b.ToString() + " produced " + result.ToString() + + Assert.True(result == expected, a.ToString() + " * " + b.ToString() + " produced " + result.ToString() + " instead of " + expected.ToString()); a = new Quaternion(1, 0, 0, 0); @@ -175,7 +175,7 @@ public void Quaternions() expected = new Quaternion(0, 0, 1, 0); result = a * b; - Assert.IsTrue(result == expected, a.ToString() + " * " + b.ToString() + " produced " + result.ToString() + + Assert.True(result == expected, a.ToString() + " * " + b.ToString() + " produced " + result.ToString() + " instead of " + expected.ToString()); a = new Quaternion(0, 0, 1, 0); @@ -183,11 +183,11 @@ public void Quaternions() expected = new Quaternion(-1, 0, 0, 0); result = a * b; - Assert.IsTrue(result == expected, a.ToString() + " * " + b.ToString() + " produced " + result.ToString() + + Assert.True(result == expected, a.ToString() + " * " + b.ToString() + " produced " + result.ToString() + " instead of " + expected.ToString()); } - [Test] + [Fact] public void testMatrix() { Matrix4 matrix = new Matrix4(0, 0, 74, 1, @@ -196,10 +196,10 @@ public void testMatrix() 0, 0, 0, 0); /* determinant of singular matrix returns zero */ - Assert.AreEqual(0d, (double)matrix.Determinant(), 0.001d); + Assert.InRange((double)matrix.Determinant(), -0.001d, 0.001d); /* inverse of identity matrix is the identity matrix */ - Assert.IsTrue(Matrix4.Identity == Matrix4.Inverse(Matrix4.Identity)); + Assert.True(Matrix4.Identity == Matrix4.Inverse(Matrix4.Identity)); /* inverse of non-singular matrix returns True And InverseMatrix */ matrix = new Matrix4(1, 1, 0, 0, @@ -210,10 +210,10 @@ public void testMatrix() 1, -1, 1, 0, -1, 1, 0, 0, 0, 0, 0, 1); - Assert.AreEqual(expectedInverse, Matrix4.Inverse(matrix)); + Assert.Equal(expectedInverse, Matrix4.Inverse(matrix)); } - //[Test] + //[Fact] //public void VectorQuaternionMath() //{ // // Convert a vector to a quaternion and back @@ -222,10 +222,10 @@ public void testMatrix() // Vector3 c; // b.GetEulerAngles(out c.X, out c.Y, out c.Z); - // Assert.IsTrue(a == c, c.ToString() + " does not equal " + a.ToString()); + // Assert.True(a == c, c.ToString() + " does not equal " + a.ToString()); //} - [Test] + [Fact] public void FloatsToTerseStrings() { float f = 1.20f; @@ -233,55 +233,55 @@ public void FloatsToTerseStrings() string b = "1.2"; a = Helpers.FloatToTerseString(f); - Assert.IsTrue(a == b, f.ToString() + " converted to " + a + ", expecting " + b); + Assert.True(a == b, f.ToString() + " converted to " + a + ", expecting " + b); f = 24.00f; b = "24"; a = Helpers.FloatToTerseString(f); - Assert.IsTrue(a == b, f.ToString() + " converted to " + a + ", expecting " + b); + Assert.True(a == b, f.ToString() + " converted to " + a + ", expecting " + b); f = -0.59f; b = "-.59"; a = Helpers.FloatToTerseString(f); - Assert.IsTrue(a == b, f.ToString() + " converted to " + a + ", expecting " + b); + Assert.True(a == b, f.ToString() + " converted to " + a + ", expecting " + b); f = 0.59f; b = ".59"; a = Helpers.FloatToTerseString(f); - Assert.IsTrue(a == b, f.ToString() + " converted to " + a + ", expecting " + b); + Assert.True(a == b, f.ToString() + " converted to " + a + ", expecting " + b); } - [Test] + [Fact] public void BitUnpacking() { byte[] data = new byte[] { 0x80, 0x00, 0x0F, 0x50, 0x83, 0x7D }; BitPack bitpacker = new BitPack(data, 0); int b = bitpacker.UnpackBits(1); - Assert.IsTrue(b == 1, "Unpacked " + b + " instead of 1"); + Assert.True(b == 1, "Unpacked " + b + " instead of 1"); b = bitpacker.UnpackBits(1); - Assert.IsTrue(b == 0, "Unpacked " + b + " instead of 0"); + Assert.True(b == 0, "Unpacked " + b + " instead of 0"); bitpacker = new BitPack(data, 2); b = bitpacker.UnpackBits(4); - Assert.IsTrue(b == 0, "Unpacked " + b + " instead of 0"); + Assert.True(b == 0, "Unpacked " + b + " instead of 0"); b = bitpacker.UnpackBits(8); - Assert.IsTrue(b == 0xF5, "Unpacked " + b + " instead of 0xF5"); + Assert.True(b == 0xF5, "Unpacked " + b + " instead of 0xF5"); b = bitpacker.UnpackBits(4); - Assert.IsTrue(b == 0, "Unpacked " + b + " instead of 0"); + Assert.True(b == 0, "Unpacked " + b + " instead of 0"); b = bitpacker.UnpackBits(10); - Assert.IsTrue(b == 0x0183, "Unpacked " + b + " instead of 0x0183"); + Assert.True(b == 0x0183, "Unpacked " + b + " instead of 0x0183"); } - [Test] + [Fact] public void BitPacking() { byte[] packedBytes = new byte[12]; @@ -295,16 +295,16 @@ public void BitPacking() bitpacker = new BitPack(packedBytes, 0); int b = bitpacker.UnpackBits(32); - Assert.IsTrue(b == 0x0ABBCCDD, "Unpacked " + b + " instead of 2864434397"); + Assert.True(b == 0x0ABBCCDD, "Unpacked " + b + " instead of 2864434397"); b = bitpacker.UnpackBits(5); - Assert.IsTrue(b == 25, "Unpacked " + b + " instead of 25"); + Assert.True(b == 25, "Unpacked " + b + " instead of 25"); float f = bitpacker.UnpackFloat(); - Assert.IsTrue(f == 123.321f, "Unpacked " + f + " instead of 123.321"); + Assert.True(f == 123.321f, "Unpacked " + f + " instead of 123.321"); b = bitpacker.UnpackBits(16); - Assert.IsTrue(b == 1000, "Unpacked " + b + " instead of 1000"); + Assert.True(b == 1000, "Unpacked " + b + " instead of 1000"); packedBytes = new byte[1]; bitpacker = new BitPack(packedBytes, 0); @@ -312,7 +312,7 @@ public void BitPacking() bitpacker = new BitPack(packedBytes, 0); b = bitpacker.UnpackBits(1); - Assert.IsTrue(b == 1, "Unpacked " + b + " instead of 1"); + Assert.True(b == 1, "Unpacked " + b + " instead of 1"); packedBytes = new byte[1]{255}; bitpacker = new BitPack(packedBytes, 0, 0); // tell to append @@ -320,10 +320,10 @@ public void BitPacking() bitpacker = new BitPack(packedBytes, 0); b = bitpacker.UnpackBits(1); - Assert.IsTrue(b == 0, "Unpacked " + b + " instead of 0"); + Assert.True(b == 0, "Unpacked " + b + " instead of 0"); } - [Test] + [Fact] public void LLSDTerseParsing() { string testOne = "[r0.99967899999999998428,r-0.025334599999999998787,r0]"; @@ -331,35 +331,35 @@ public void LLSDTerseParsing() string testThree = "{'region_handle':[r255232, r256512], 'position':[r33.6, r33.71, r43.13], 'look_at':[r34.6, r33.71, r43.13]}"; OSD obj = OSDParser.DeserializeLLSDNotation(testOne); - Assert.IsInstanceOf(typeof(OSDArray), obj, "Expected SDArray, got " + obj.GetType().ToString()); + Assert.True(obj is OSDArray, "Expected SDArray, got " + obj.GetType().ToString()); OSDArray array = (OSDArray)obj; - Assert.IsTrue(array.Count == 3, "Expected three contained objects, got " + array.Count); - Assert.IsTrue(array[0].AsReal() > 0.9d && array[0].AsReal() < 1.0d, "Unexpected value for first real " + array[0].AsReal()); - Assert.IsTrue(array[1].AsReal() < 0.0d && array[1].AsReal() > -0.03d, "Unexpected value for second real " + array[1].AsReal()); - Assert.IsTrue(array[2].AsReal() == 0.0d, "Unexpected value for third real " + array[2].AsReal()); + Assert.True(array.Count == 3, "Expected three contained objects, got " + array.Count); + Assert.True(array[0].AsReal() > 0.9d && array[0].AsReal() < 1.0d, "Unexpected value for first real " + array[0].AsReal()); + Assert.True(array[1].AsReal() < 0.0d && array[1].AsReal() > -0.03d, "Unexpected value for second real " + array[1].AsReal()); + Assert.True(array[2].AsReal() == 0.0d, "Unexpected value for third real " + array[2].AsReal()); obj = OSDParser.DeserializeLLSDNotation(testTwo); - Assert.IsInstanceOf(typeof(OSDArray), obj, "Expected SDArray, got " + obj.GetType().ToString()); + Assert.True(obj is OSDArray, "Expected SDArray, got " + obj.GetType().ToString()); array = (OSDArray)obj; - Assert.IsTrue(array.Count == 2, "Expected two contained objects, got " + array.Count); - Assert.IsTrue(array[1].AsReal() == 0.0d, "Unexpected value for real " + array[1].AsReal()); + Assert.True(array.Count == 2, "Expected two contained objects, got " + array.Count); + Assert.True(array[1].AsReal() == 0.0d, "Unexpected value for real " + array[1].AsReal()); obj = array[0]; - Assert.IsInstanceOf(typeof(OSDArray), obj, "Expected ArrayList, got " + obj.GetType().ToString()); + Assert.True(obj is OSDArray, "Expected ArrayList, got " + obj.GetType().ToString()); array = (OSDArray)obj; - Assert.IsTrue(array[0].AsReal() == 1.0d && array[1].AsReal() == 1.0d && array[2].AsReal() == 1.0d, + Assert.True(array[0].AsReal() == 1.0d && array[1].AsReal() == 1.0d && array[2].AsReal() == 1.0d, "Unexpected value(s) for nested array: " + array[0].AsReal() + ", " + array[1].AsReal() + ", " + array[2].AsReal()); obj = OSDParser.DeserializeLLSDNotation(testThree); - Assert.IsInstanceOf(typeof(OSDMap), obj, "Expected LLSDMap, got " + obj.GetType().ToString()); + Assert.True(obj is OSDMap, "Expected LLSDMap, got " + obj.GetType().ToString()); OSDMap hashtable = (OSDMap)obj; - Assert.IsTrue(hashtable.Count == 3, "Expected three contained objects, got " + hashtable.Count); - Assert.IsInstanceOf(typeof(OSDArray), hashtable["region_handle"]); - Assert.IsTrue(((OSDArray)hashtable["region_handle"]).Count == 2); - Assert.IsInstanceOf(typeof(OSDArray), hashtable["position"]); - Assert.IsTrue(((OSDArray)hashtable["position"]).Count == 3); - Assert.IsInstanceOf(typeof(OSDArray), hashtable["look_at"]); - Assert.IsTrue(((OSDArray)hashtable["look_at"]).Count == 3); + Assert.True(hashtable.Count == 3, "Expected three contained objects, got " + hashtable.Count); + Assert.IsType(hashtable["region_handle"]); + Assert.True(((OSDArray)hashtable["region_handle"]).Count == 2); + Assert.IsType(hashtable["position"]); + Assert.True(((OSDArray)hashtable["position"]).Count == 3); + Assert.IsType(hashtable["look_at"]); + Assert.True(((OSDArray)hashtable["look_at"]).Count == 3); } } } diff --git a/OpenMetaverse.Tests/XmlLLSDTests.cs b/OpenMetaverse.Tests/XmlLLSDTests.cs index cc3a7bbe..81242099 100644 --- a/OpenMetaverse.Tests/XmlLLSDTests.cs +++ b/OpenMetaverse.Tests/XmlLLSDTests.cs @@ -24,7 +24,7 @@ * POSSIBILITY OF SUCH DAMAGE. */ -using NUnit.Framework; +using Xunit; using OpenMetaverse.StructuredData; using System; using System.Text; @@ -35,7 +35,7 @@ namespace OpenMetaverse.Tests /// XmlSDTests is a suite of tests for libsl implementation of the SD XML format. /// /// - [TestFixture] + public class XmlSDTests { /// @@ -43,7 +43,7 @@ public class XmlSDTests /// The LLSD string in the test is a pared down version of the sample on the blog. /// http://wiki.secondlife.com/wiki/LLSD /// - [Test] + [Fact] public void DeserializeLLSDSample() { OSD theSD = null; @@ -83,80 +83,80 @@ public void DeserializeLLSDSample() theSD = OSDParser.DeserializeLLSDXml(bytes); //Confirm the contents - Assert.IsNotNull(theSD); - Assert.IsTrue(theSD is OSDMap); - Assert.IsTrue(theSD.Type == OSDType.Map); + Assert.NotNull(theSD); + Assert.True(theSD is OSDMap); + Assert.True(theSD.Type == OSDType.Map); map = (OSDMap)theSD; tempSD = map["region_id"]; - Assert.IsNotNull(tempSD); - Assert.IsTrue(tempSD is OSDUUID); - Assert.IsTrue(tempSD.Type == OSDType.UUID); + Assert.NotNull(tempSD); + Assert.True(tempSD is OSDUUID); + Assert.True(tempSD.Type == OSDType.UUID); tempUUID = (OSDUUID)tempSD; - Assert.AreEqual(new UUID("67153d5b-3659-afb4-8510-adda2c034649"), tempUUID.AsUUID()); + Assert.Equal(new UUID("67153d5b-3659-afb4-8510-adda2c034649"), tempUUID.AsUUID()); tempSD = map["scale"]; - Assert.IsNotNull(tempSD); - Assert.IsTrue(tempSD is OSDString); - Assert.IsTrue(tempSD.Type == OSDType.String); + Assert.NotNull(tempSD); + Assert.True(tempSD is OSDString); + Assert.True(tempSD.Type == OSDType.String); tempStr = (OSDString)tempSD; - Assert.AreEqual("one minute", tempStr.AsString()); + Assert.Equal("one minute", tempStr.AsString()); tempSD = map["simulator statistics"]; - Assert.IsNotNull(tempSD); - Assert.IsTrue(tempSD is OSDMap); - Assert.IsTrue(tempSD.Type == OSDType.Map); + Assert.NotNull(tempSD); + Assert.True(tempSD is OSDMap); + Assert.True(tempSD.Type == OSDType.Map); map = (OSDMap)tempSD; tempSD = map["time dilation"]; - Assert.IsNotNull(tempSD); - Assert.IsTrue(tempSD is OSDReal); - Assert.IsTrue(tempSD.Type == OSDType.Real); + Assert.NotNull(tempSD); + Assert.True(tempSD is OSDReal); + Assert.True(tempSD.Type == OSDType.Real); tempReal = (OSDReal)tempSD; - Assert.AreEqual(0.9878624d, tempReal.AsReal()); + Assert.Equal(0.9878624d, tempReal.AsReal()); //TODO - figure out any relevant rounding variability for 64 bit reals tempSD = map["sim fps"]; - Assert.IsNotNull(tempSD); - Assert.IsTrue(tempSD is OSDReal); - Assert.IsTrue(tempSD.Type == OSDType.Real); + Assert.NotNull(tempSD); + Assert.True(tempSD is OSDReal); + Assert.True(tempSD.Type == OSDType.Real); tempReal = (OSDReal)tempSD; - Assert.AreEqual(44.38898d, tempReal.AsReal()); + Assert.Equal(44.38898d, tempReal.AsReal()); tempSD = map["agent updates per second"]; - Assert.IsNotNull(tempSD); - Assert.IsTrue(tempSD is OSDReal); - Assert.IsTrue(tempSD.Type == OSDType.Real); + Assert.NotNull(tempSD); + Assert.True(tempSD is OSDReal); + Assert.True(tempSD.Type == OSDType.Real); tempReal = (OSDReal)tempSD; - Assert.AreEqual(Double.NaN, tempSD.AsReal()); + Assert.Equal(Double.NaN, tempSD.AsReal()); tempSD = map["total task count"]; - Assert.IsNotNull(tempSD); - Assert.IsTrue(tempSD is OSDReal); - Assert.IsTrue(tempSD.Type == OSDType.Real); + Assert.NotNull(tempSD); + Assert.True(tempSD is OSDReal); + Assert.True(tempSD.Type == OSDType.Real); tempReal = (OSDReal)tempSD; - Assert.AreEqual(4.0d, tempReal.AsReal()); + Assert.Equal(4.0d, tempReal.AsReal()); tempSD = map["active task count"]; - Assert.IsNotNull(tempSD); - Assert.IsTrue(tempSD is OSDReal); - Assert.IsTrue(tempSD.Type == OSDType.Real); + Assert.NotNull(tempSD); + Assert.True(tempSD is OSDReal); + Assert.True(tempSD.Type == OSDType.Real); tempReal = (OSDReal)tempSD; - Assert.AreEqual(0.0d, tempReal.AsReal()); + Assert.Equal(0.0d, tempReal.AsReal()); tempSD = map["pending uploads"]; - Assert.IsNotNull(tempSD); - Assert.IsTrue(tempSD is OSDReal); - Assert.IsTrue(tempSD.Type == OSDType.Real); + Assert.NotNull(tempSD); + Assert.True(tempSD is OSDReal); + Assert.True(tempSD.Type == OSDType.Real); tempReal = (OSDReal)tempSD; - Assert.AreEqual(0.0001096525d, tempReal.AsReal()); + Assert.Equal(0.0001096525d, tempReal.AsReal()); } /// /// Test that various Real representations are parsed correctly. /// - [Test] + [Fact] public void DeserializeReals() { OSD theSD = null; @@ -177,34 +177,34 @@ public void DeserializeReals() byte[] bytes = Encoding.UTF8.GetBytes(testSD); theSD = OSDParser.DeserializeLLSDXml(bytes); - Assert.IsTrue(theSD is OSDArray); + Assert.True(theSD is OSDArray); array = (OSDArray)theSD; - Assert.AreEqual(OSDType.Real, array[0].Type); + Assert.Equal(OSDType.Real, array[0].Type); tempReal = (OSDReal)array[0]; - Assert.AreEqual(44.38898d, tempReal.AsReal()); + Assert.Equal(44.38898d, tempReal.AsReal()); - Assert.AreEqual(OSDType.Real, array[1].Type); + Assert.Equal(OSDType.Real, array[1].Type); tempReal = (OSDReal)array[1]; - Assert.AreEqual(Double.NaN, tempReal.AsReal()); + Assert.Equal(Double.NaN, tempReal.AsReal()); - Assert.AreEqual(OSDType.Real, array[2].Type); + Assert.Equal(OSDType.Real, array[2].Type); tempReal = (OSDReal)array[2]; - Assert.AreEqual(4.0d, tempReal.AsReal()); + Assert.Equal(4.0d, tempReal.AsReal()); - Assert.AreEqual(OSDType.Real, array[3].Type); + Assert.Equal(OSDType.Real, array[3].Type); tempReal = (OSDReal)array[3]; - Assert.AreEqual(-13.333d, tempReal.AsReal()); + Assert.Equal(-13.333d, tempReal.AsReal()); - Assert.AreEqual(OSDType.Real, array[4].Type); + Assert.Equal(OSDType.Real, array[4].Type); tempReal = (OSDReal)array[4]; - Assert.AreEqual(0d, tempReal.AsReal()); + Assert.Equal(0d, tempReal.AsReal()); } /// /// Test that various String representations are parsed correctly. /// - [Test] + [Fact] public void DeserializeStrings() { OSD theSD = null; @@ -224,24 +224,24 @@ public void DeserializeStrings() byte[] bytes = Encoding.UTF8.GetBytes(testSD); theSD = OSDParser.DeserializeLLSDXml(bytes); - Assert.IsTrue(theSD is OSDArray); + Assert.True(theSD is OSDArray); array = (OSDArray)theSD; - Assert.AreEqual(OSDType.String, array[0].Type); + Assert.Equal(OSDType.String, array[0].Type); tempStr = (OSDString)array[0]; - Assert.AreEqual("Kissling", tempStr.AsString()); + Assert.Equal("Kissling", tempStr.AsString()); - Assert.AreEqual(OSDType.String, array[1].Type); + Assert.Equal(OSDType.String, array[1].Type); tempStr = (OSDString)array[1]; - Assert.AreEqual("Attack ships on fire off the shoulder of Orion", tempStr.AsString()); + Assert.Equal("Attack ships on fire off the shoulder of Orion", tempStr.AsString()); - Assert.AreEqual(OSDType.String, array[2].Type); + Assert.Equal(OSDType.String, array[2].Type); tempStr = (OSDString)array[2]; - Assert.AreEqual("< > & \' \"", tempStr.AsString()); + Assert.Equal("< > & \' \"", tempStr.AsString()); - Assert.AreEqual(OSDType.String, array[3].Type); + Assert.Equal(OSDType.String, array[3].Type); tempStr = (OSDString)array[3]; - Assert.AreEqual("", tempStr.AsString()); + Assert.Equal("", tempStr.AsString()); } @@ -253,7 +253,7 @@ public void DeserializeStrings() /// implemented using int, a.k.a. Int32. Not testing Int64 range until /// it's understood if there was a design reason for the Int32. /// - [Test] + [Fact] public void DeserializeIntegers() { OSD theSD = null; @@ -274,34 +274,34 @@ public void DeserializeIntegers() byte[] bytes = Encoding.UTF8.GetBytes(testSD); theSD = OSDParser.DeserializeLLSDXml(bytes); - Assert.IsTrue(theSD is OSDArray); + Assert.True(theSD is OSDArray); array = (OSDArray)theSD; - Assert.AreEqual(OSDType.Integer, array[0].Type); + Assert.Equal(OSDType.Integer, array[0].Type); tempInt = (OSDInteger)array[0]; - Assert.AreEqual(2147483647, tempInt.AsInteger()); + Assert.Equal(2147483647, tempInt.AsInteger()); - Assert.AreEqual(OSDType.Integer, array[1].Type); + Assert.Equal(OSDType.Integer, array[1].Type); tempInt = (OSDInteger)array[1]; - Assert.AreEqual(-2147483648, tempInt.AsInteger()); + Assert.Equal(-2147483648, tempInt.AsInteger()); - Assert.AreEqual(OSDType.Integer, array[2].Type); + Assert.Equal(OSDType.Integer, array[2].Type); tempInt = (OSDInteger)array[2]; - Assert.AreEqual(0, tempInt.AsInteger()); + Assert.Equal(0, tempInt.AsInteger()); - Assert.AreEqual(OSDType.Integer, array[3].Type); + Assert.Equal(OSDType.Integer, array[3].Type); tempInt = (OSDInteger)array[3]; - Assert.AreEqual(13, tempInt.AsInteger()); + Assert.Equal(13, tempInt.AsInteger()); - Assert.AreEqual(OSDType.Integer, array[4].Type); + Assert.Equal(OSDType.Integer, array[4].Type); tempInt = (OSDInteger)array[4]; - Assert.AreEqual(0, tempInt.AsInteger()); + Assert.Equal(0, tempInt.AsInteger()); } /// /// Test that various UUID representations are parsed correctly. /// - [Test] + [Fact] public void DeserializeUUID() { OSD theSD = null; @@ -319,22 +319,22 @@ public void DeserializeUUID() byte[] bytes = Encoding.UTF8.GetBytes(testSD); theSD = OSDParser.DeserializeLLSDXml(bytes); - Assert.IsTrue(theSD is OSDArray); + Assert.True(theSD is OSDArray); array = (OSDArray)theSD; - Assert.AreEqual(OSDType.UUID, array[0].Type); + Assert.Equal(OSDType.UUID, array[0].Type); tempUUID = (OSDUUID)array[0]; - Assert.AreEqual(new UUID("d7f4aeca-88f1-42a1-b385-b9db18abb255"), tempUUID.AsUUID()); + Assert.Equal(new UUID("d7f4aeca-88f1-42a1-b385-b9db18abb255"), tempUUID.AsUUID()); - Assert.AreEqual(OSDType.UUID, array[1].Type); + Assert.Equal(OSDType.UUID, array[1].Type); tempUUID = (OSDUUID)array[1]; - Assert.AreEqual(UUID.Zero, tempUUID.AsUUID()); + Assert.Equal(UUID.Zero, tempUUID.AsUUID()); } /// /// Test that various date representations are parsed correctly. /// - [Test] + [Fact] public void DeserializeDates() { OSD theSD = null; @@ -354,28 +354,28 @@ public void DeserializeDates() byte[] bytes = Encoding.UTF8.GetBytes(testSD); theSD = OSDParser.DeserializeLLSDXml(bytes); - Assert.IsTrue(theSD is OSDArray); + Assert.True(theSD is OSDArray); array = (OSDArray)theSD; - Assert.AreEqual(OSDType.Date, array[0].Type); + Assert.Equal(OSDType.Date, array[0].Type); tempDate = (OSDDate)array[0]; DateTime.TryParse("2006-02-01T14:29:53Z", out testDate); - Assert.AreEqual(testDate, tempDate.AsDate()); + Assert.Equal(testDate, tempDate.AsDate()); - Assert.AreEqual(OSDType.Date, array[1].Type); + Assert.Equal(OSDType.Date, array[1].Type); tempDate = (OSDDate)array[1]; DateTime.TryParse("1999-01-01T00:00:00Z", out testDate); - Assert.AreEqual(testDate, tempDate.AsDate()); + Assert.Equal(testDate, tempDate.AsDate()); - Assert.AreEqual(OSDType.Date, array[2].Type); + Assert.Equal(OSDType.Date, array[2].Type); tempDate = (OSDDate)array[2]; - Assert.AreEqual(Utils.Epoch, tempDate.AsDate()); + Assert.Equal(Utils.Epoch, tempDate.AsDate()); } /// /// Test that various Boolean representations are parsed correctly. /// - [Test] + [Fact] public void DeserializeBoolean() { OSD theSD = null; @@ -396,34 +396,34 @@ public void DeserializeBoolean() byte[] bytes = Encoding.UTF8.GetBytes(testSD); theSD = OSDParser.DeserializeLLSDXml(bytes); - Assert.IsTrue(theSD is OSDArray); + Assert.True(theSD is OSDArray); array = (OSDArray)theSD; - Assert.AreEqual(OSDType.Boolean, array[0].Type); + Assert.Equal(OSDType.Boolean, array[0].Type); tempBool = (OSDBoolean)array[0]; - Assert.AreEqual(true, tempBool.AsBoolean()); + Assert.Equal(true, tempBool.AsBoolean()); - Assert.AreEqual(OSDType.Boolean, array[1].Type); + Assert.Equal(OSDType.Boolean, array[1].Type); tempBool = (OSDBoolean)array[1]; - Assert.AreEqual(true, tempBool.AsBoolean()); + Assert.Equal(true, tempBool.AsBoolean()); - Assert.AreEqual(OSDType.Boolean, array[2].Type); + Assert.Equal(OSDType.Boolean, array[2].Type); tempBool = (OSDBoolean)array[2]; - Assert.AreEqual(false, tempBool.AsBoolean()); + Assert.Equal(false, tempBool.AsBoolean()); - Assert.AreEqual(OSDType.Boolean, array[3].Type); + Assert.Equal(OSDType.Boolean, array[3].Type); tempBool = (OSDBoolean)array[3]; - Assert.AreEqual(false, tempBool.AsBoolean()); + Assert.Equal(false, tempBool.AsBoolean()); - Assert.AreEqual(OSDType.Boolean, array[4].Type); + Assert.Equal(OSDType.Boolean, array[4].Type); tempBool = (OSDBoolean)array[4]; - Assert.AreEqual(false, tempBool.AsBoolean()); + Assert.Equal(false, tempBool.AsBoolean()); } /// /// Test that binary elements are parsed correctly. /// - [Test] + [Fact] public void DeserializeBinary() { OSD theSD = null; @@ -443,23 +443,23 @@ public void DeserializeBinary() byte[] bytes = Encoding.UTF8.GetBytes(testSD); theSD = OSDParser.DeserializeLLSDXml(bytes); - Assert.IsTrue(theSD is OSDArray); + Assert.True(theSD is OSDArray); array = (OSDArray)theSD; - Assert.AreEqual(OSDType.Binary, array[0].Type); + Assert.Equal(OSDType.Binary, array[0].Type); tempBinary = (OSDBinary)array[0]; byte[] testData1 = { 114, 97, 110, 100, 111, 109 }; TestHelper.TestBinary(tempBinary, testData1); - Assert.AreEqual(OSDType.Binary, array[1].Type); + Assert.Equal(OSDType.Binary, array[1].Type); tempBinary = (OSDBinary)array[1]; byte[] testData2 = {116, 104, 101, 32, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120}; TestHelper.TestBinary(tempBinary, testData2); - Assert.AreEqual(OSDType.Binary, array[1].Type); + Assert.Equal(OSDType.Binary, array[1].Type); tempBinary = (OSDBinary)array[2]; - Assert.AreEqual(0, tempBinary.AsBinary().Length); + Assert.Equal(0, tempBinary.AsBinary().Length); } /// @@ -468,7 +468,7 @@ public void DeserializeBinary() /// value and there is no SD child class for Undefined elements - the /// current implementation generates an instance of SD /// - [Test] + [Fact] public void DeserializeUndef() { OSD theSD = null; @@ -481,13 +481,13 @@ public void DeserializeUndef() byte[] bytes = Encoding.UTF8.GetBytes(testSD); theSD = OSDParser.DeserializeLLSDXml(bytes); - Assert.IsTrue(theSD is OSD); + Assert.True(theSD is OSD); } /// /// Test that various URI representations are parsed correctly. /// - [Test] + [Fact] public void DeserializeURI() { OSD theSD = null; @@ -505,24 +505,24 @@ public void DeserializeURI() byte[] bytes = Encoding.UTF8.GetBytes(testSD); theSD = OSDParser.DeserializeLLSDXml(bytes); - Assert.IsTrue(theSD is OSDArray); + Assert.True(theSD is OSDArray); array = (OSDArray)theSD; - Assert.AreEqual(OSDType.URI, array[0].Type); + Assert.Equal(OSDType.URI, array[0].Type); tempURI = (OSDUri)array[0]; Uri testURI = new Uri(@"http://sim956.agni.lindenlab.com:12035/runtime/agents"); - Assert.AreEqual(testURI, tempURI.AsUri()); + Assert.Equal(testURI, tempURI.AsUri()); - Assert.AreEqual(OSDType.URI, array[1].Type); + Assert.Equal(OSDType.URI, array[1].Type); tempURI = (OSDUri)array[1]; - Assert.AreEqual("", tempURI.AsUri().ToString()); + Assert.Equal("", tempURI.AsUri().ToString()); } /// /// Test some nested containers. This is not a very deep or complicated SD graph /// but it should reveal basic nesting issues. /// - [Test] + [Fact] public void DeserializeNestedContainers() { OSD theSD = null; @@ -558,36 +558,36 @@ public void DeserializeNestedContainers() byte[] bytes = Encoding.UTF8.GetBytes(testSD); theSD = OSDParser.DeserializeLLSDXml(bytes); - Assert.IsTrue(theSD is OSDArray); + Assert.True(theSD is OSDArray); array = (OSDArray)theSD; - Assert.AreEqual(2, array.Count); + Assert.Equal(2, array.Count); //The first element of top level array, a map - Assert.AreEqual(OSDType.Map, array[0].Type); + Assert.Equal(OSDType.Map, array[0].Type); map = (OSDMap)array[0]; //First nested map tempSD = map["Map One"]; - Assert.IsNotNull(tempSD); - Assert.AreEqual(OSDType.Map, tempSD.Type); + Assert.NotNull(tempSD); + Assert.Equal(OSDType.Map, tempSD.Type); map = (OSDMap)tempSD; //First nested array tempSD = map["Array One"]; - Assert.IsNotNull(tempSD); - Assert.AreEqual(OSDType.Array, tempSD.Type); + Assert.NotNull(tempSD); + Assert.Equal(OSDType.Array, tempSD.Type); array = (OSDArray)tempSD; - Assert.AreEqual(2, array.Count); + Assert.Equal(2, array.Count); array = (OSDArray)theSD; //Second element of top level array, an array tempSD = array[1]; - Assert.AreEqual(OSDType.Array, tempSD.Type); + Assert.Equal(OSDType.Array, tempSD.Type); array = (OSDArray)tempSD; - Assert.AreEqual(3, array.Count); + Assert.Equal(3, array.Count); //Nested array tempSD = array[2]; - Assert.AreEqual(OSDType.Array, tempSD.Type); + Assert.Equal(OSDType.Array, tempSD.Type); array = (OSDArray)tempSD; - Assert.AreEqual(3, array.Count); + Assert.Equal(3, array.Count); } } @@ -602,12 +602,12 @@ internal static class TestHelper internal static void TestBinary(OSDBinary inBinary, byte[] inExpected) { byte[] binary = inBinary.AsBinary(); - Assert.AreEqual(inExpected.Length, binary.Length); + Assert.Equal(inExpected.Length, binary.Length); for (int i = 0; i < inExpected.Length; i++) { if (inExpected[i] != binary[i]) { - Assert.Fail("Expected " + inExpected[i].ToString() + " at position " + i.ToString() + + throw new Xunit.Sdk.XunitException("Expected " + inExpected[i].ToString() + " at position " + i.ToString() + " but saw " + binary[i].ToString()); } } From b22101c5b2b28b77fb48288fc152b7c33564b02f Mon Sep 17 00:00:00 2001 From: Mike Dickson Date: Fri, 15 May 2026 13:14:02 -0400 Subject: [PATCH 149/149] Remove historical (hysterical) cruft from the use of prebuild. --- OpenMetaverse.Utilities/OpenMetaverse.Utilities.csproj | 6 ------ 1 file changed, 6 deletions(-) diff --git a/OpenMetaverse.Utilities/OpenMetaverse.Utilities.csproj b/OpenMetaverse.Utilities/OpenMetaverse.Utilities.csproj index 1a33d24f..27f5c0b9 100644 --- a/OpenMetaverse.Utilities/OpenMetaverse.Utilities.csproj +++ b/OpenMetaverse.Utilities/OpenMetaverse.Utilities.csproj @@ -6,12 +6,6 @@ OpenMetaverse.Utilities True - - - - - OpenMetaverse.Utilities.XML -
Returns the number of bits, referred to as the "range bits", + /// corresponding to the nominal range of the data in the specified + /// component. If this number is b then for unsigned data the + /// nominal range is between 0 and 2^b-1, and for signed data it is between + /// -2^(b-1) and 2^(b-1)-1. For floating point data this value is not + /// applicable. + /// + ///

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