skyscraper8/skyscraper8/Skyscraper/Text/SkyscraperBaseEncoding8.cs
feyris-tan ef86554f9a Import
2025-05-12 22:09:16 +02:00

151 lines
5.2 KiB
C#

using System;
using System.Text;
namespace skyscraper5.Skyscraper.Text
{
abstract class SkyscraperBaseEncoding8 : Encoding
{
protected abstract char[] Decrypt(byte[] preprocessed);
private char[] lastDecrypted;
private byte[] lastBuffer;
private bool IsSameStringAsLast(byte[] buffer, int index, int count)
{
if (lastBuffer == null)
{
//Dies ist der erste call.
lastBuffer = new byte[count];
Array.Copy(buffer, index, lastBuffer, 0, count);
return false;
}
if (lastBuffer.Length != count)
{
//string länge anders als beim letzten mal, kann also nicht der selbe sein.
lastBuffer = new byte[count];
Array.Copy(buffer, index, lastBuffer, 0, count);
return false;
}
for (int i = 0; i < count; i++)
{
if (lastBuffer[i] != buffer[i + index])
{
//String anders als beim letzen mal
lastBuffer = new byte[count];
Array.Copy(buffer, index, lastBuffer, 0, count);
return false;
}
}
return true;
}
protected virtual int GetPreProcessLength(byte[] buffer, int index, int count)
{
int result = 0;
byte t;
for (int i = 0; i < count; i++)
{
t = buffer[i + index];
if (t >= 0x80 && t <= 0x85)
continue; //reserved for future use
if (t == 0x86)
continue; //character emphasis on
if (t == 0x87)
continue; //character emphasis off
if (t >= 0x88 && t <= 0x89)
continue; //reserved for future use
if (t == 0x8a)
result += 2; //CRLF
if (t >= 0x8b && t <= 0x9f)
continue; //user defined
result++;
}
return result;
}
protected virtual byte[] PreProcess(byte[] buffer, int index, int count, int predictedLength)
{
byte[] result = new byte[predictedLength];
int outputOffset = 0;
byte t;
for (int inputOffset = 0; inputOffset < count; inputOffset++)
{
t = buffer[inputOffset + index];
if (t >= 0x80 && t <= 0x85)
continue; //reserved for future use
if (t == 0x86)
continue; //character emphasis on
if (t == 0x87)
continue; //character emphasis off
if (t >= 0x88 && t <= 0x89)
continue; //reserved for future use
if (t == 0x8a)
{
result[outputOffset++] = 0x10;
result[outputOffset++] = 0x13;
continue;
}
if (t >= 0x8b && t <= 0x9f)
continue; //user defined
result[outputOffset++] = t;
}
return result;
}
public override int GetByteCount(char[] chars, int index, int count)
{
throw new NotImplementedException();
}
public override int GetBytes(char[] chars, int charIndex, int charCount, byte[] bytes, int byteIndex)
{
throw new NotImplementedException();
}
public override int GetCharCount(byte[] bytes, int index, int count)
{
if (!IsSameStringAsLast(bytes, index, count))
{
int preProcessLength = GetPreProcessLength(bytes, index, count);
byte[] preProcess = PreProcess(bytes, index, count, preProcessLength);
lastDecrypted = Decrypt(preProcess);
}
return lastDecrypted.Length;
}
public override int GetChars(byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex)
{
if (!IsSameStringAsLast(bytes, byteIndex, byteCount))
{
int preProcessLength = GetPreProcessLength(bytes, byteIndex, byteCount);
byte[] preProcess = PreProcess(bytes, byteIndex, byteCount, preProcessLength);
int maxAllowedSize = lastDecrypted.Length;
char[] overwriting = Decrypt(preProcess);
if (overwriting.Length > maxAllowedSize)
{
throw new AccessViolationException("Oh no, I guess the multithreading went haywire...");
}
lastDecrypted = overwriting;
}
int result = Math.Min(chars.Length - charIndex, lastDecrypted.Length);
Array.Copy(lastDecrypted, 0, chars, charIndex, result);
return result;
}
public override int GetMaxByteCount(int charCount)
{
throw new NotImplementedException();
}
public override int GetMaxCharCount(int byteCount)
{
throw new NotImplementedException();
}
}
}