From 214cf5d60b76b2c91bc32e1198164e5ff3f11d65 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Fri, 15 May 2020 14:41:38 +0100 Subject: [PATCH] llsdXml: do direct base64 encode --- OpenSim/Framework/LLSDxmlEncode.cs | 132 ++++++++++++++++++++++++++++- 1 file changed, 129 insertions(+), 3 deletions(-) diff --git a/OpenSim/Framework/LLSDxmlEncode.cs b/OpenSim/Framework/LLSDxmlEncode.cs index b84a16505a..31d5ccc06c 100644 --- a/OpenSim/Framework/LLSDxmlEncode.cs +++ b/OpenSim/Framework/LLSDxmlEncode.cs @@ -148,7 +148,22 @@ namespace OpenSim.Framework else { sb.Append(""); // encode64 is default - sb.Append(Convert.ToBase64String(e,Base64FormattingOptions.None)); + base64Encode(e, sb); + sb.Append(""); + } + } + + public static void AddElem(byte[] e, int start, int lenght, StringBuilder sb) + { + if (start + lenght >= e.Length) + lenght = e.Length - start; + + if (e == null || e.Length == 0 || lenght <= 0) + sb.Append("binary />"); + else + { + sb.Append(""); // encode64 is default + base64Encode(e, start, lenght, sb); sb.Append(""); } } @@ -451,12 +466,31 @@ namespace OpenSim.Framework sb.Append(name); sb.Append(""); - if(e == null || e.Length == 0) + if (e == null || e.Length == 0) sb.Append("binary />"); else { sb.Append(""); // encode64 is default - sb.Append(Convert.ToBase64String(e,Base64FormattingOptions.None)); + base64Encode(e, sb); + sb.Append(""); + } + } + + public static void AddElem(string name, byte[] e, int start, int lenght, StringBuilder sb) + { + sb.Append(""); + sb.Append(name); + sb.Append(""); + + if (start + lenght >= e.Length) + lenght = e.Length - start; + + if (e == null || e.Length == 0 || lenght <= 0) + sb.Append("binary />"); + else + { + sb.Append(""); // encode64 is default + base64Encode(e, start, lenght, sb); sb.Append(""); } } @@ -786,5 +820,97 @@ namespace OpenSim.Framework (byte)value }; } + + static readonly char[] base64Chars = {'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O', + 'P','Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d', + 'e','f','g','h','i','j','k','l','m','n','o','p','q','r','s', + 't','u','v','w','x','y','z','0','1','2','3','4','5','6','7', + '8','9','+','/'}; + + public static unsafe void base64Encode(byte[] data, StringBuilder sb) + { + int lenMod3 = data.Length % 3; + int len = data.Length - lenMod3; + + fixed (byte* d = data) + { + fixed (char* b64 = base64Chars) + { + int i = 0; + while(i < len) + { + sb.Append(b64[d[i] >> 2]); + sb.Append(b64[((d[i] & 0x03) << 4) | ((d[i + 1] & 0xf0) >> 4)]); + sb.Append(b64[((d[i + 1] & 0x0f) << 2) | ((d[i + 2] & 0xc0) >> 6)]); + sb.Append(b64[d[i + 2] & 0x3f]); + i += 3; + } + + switch (lenMod3) + { + case 2: + { + i = len; + sb.Append(b64[d[i] >> 2]); + sb.Append(b64[((d[i] & 0x03) << 4) | ((d[i + 1] & 0xf0) >> 4)]); + sb.Append(b64[((d[i + 1] & 0x0f) << 2)]); + sb.Append('='); + break; + } + case 1: + { + i = len; + sb.Append(b64[d[i] >> 2]); + sb.Append(b64[(d[i] & 0x03) << 4]); + sb.Append("=="); + break; + } + } + } + } + } + + public static unsafe void base64Encode(byte[] data, int start, int lenght, StringBuilder sb) + { + int lenMod3 = lenght % 3; + int len = start + (lenght - lenMod3); + + fixed (byte* d = data) + { + fixed (char* b64 = base64Chars) + { + int i = start; + while(i < len) + { + sb.Append(b64[(d[i] & 0xfc) >> 2]); + sb.Append(b64[((d[i] & 0x03) << 4) | (d[i + 1] >> 4)]); + sb.Append(b64[((d[i + 1] & 0x0f) << 2) | (d[i + 2] >> 6)]); + sb.Append(b64[d[i + 2] & 0x3f]); + i += 3; + } + + switch (lenMod3) + { + case 2: + { + i = len; + sb.Append(b64[d[i] >> 2]); + sb.Append(b64[((d[i] & 0x03) << 4) | (d[i + 1] >> 4)]); + sb.Append(b64[((d[i + 1] & 0x0f) << 2)]); + sb.Append('='); + break; + } + case 1: + { + i = len; + sb.Append(b64[d[i] >> 2]); + sb.Append(b64[(d[i] & 0x03) << 4]); + sb.Append("=="); + break; + } + } + } + } + } } }