public static byte[] ToBytesLe(uint value, UintType uintType) { byte[] bytes = new byte[(int)uintType]; for (int i = 0; i < (int)uintType; i++) { bytes[i] = (byte)(value >> ((int)uintType - i - 1) * 8); } return(bytes); }
public static uint ToUintBe(byte[] bytes, int startIndex, UintType uintType) { uint value = 0; for (int i = 0; i < (int)uintType; i++) { value |= (uint)bytes[startIndex + i] << ((int)uintType - i - 1) * 8; } return(value); }
//Основной метод декодирования public static IEnumerable <string> DecodeAutoDict(string inputPath) { using (BinaryReader br = new BinaryReader(File.OpenRead(inputPath))) { //Восстановка словаря фраз длиной в 1 символ int dictLength = BitConverter.ToInt32(br.ReadBytes(4)); List <string> words = new List <string>(); for (int j = 0; j < dictLength; j++) { words.Add(BitConverter.ToChar(br.ReadBytes(2)).ToString()); } //Прочитать закодированную длину одной записи в словаре UintType uType = ByteToUintType(br.ReadByte()); //Декодировать первую фразу, отправить в поток int entry = ReadAndConvert(br, uType); string entryWord = words[entry]; string newWordPart = entryWord; yield return(entryWord); //Номер следующей записи в словаре int i = dictLength; //Пока не достигнут конец потока while (br.BaseStream.Position != br.BaseStream.Length) { //Декодировать и отправить в поток следующую фразу, занести в словарь //конкатенацию прошлой фразы и первого символа новой фразы entry = ReadAndConvert(br, uType); if (entry == i) { words.Add(newWordPart + newWordPart.First()); } else { words.Add(newWordPart + words[entry].First()); } entryWord = words[entry]; newWordPart = entryWord; yield return(entryWord); i++; } } }
//В зависимости от используемого целочисленного типа, //прочитать один или несколько байтов и преобразовать их в число private static int ReadAndConvert(BinaryReader br, UintType uintType) { int entry; switch (uintType) { case UintType.Byte: entry = br.ReadByte(); break; case UintType.Uint: entry = BitConverter.ToInt16(br.ReadBytes(2)); break; case UintType.Ushort: entry = BitConverter.ToInt32(br.ReadBytes(4)); break; default: throw new ArgumentException(); } return(entry); }