/// <summary> /// Dekomprimiert eine Zeichenkette. /// </summary> /// <param name="bytes">Feld mit den dekomprimierten Werten.</param> /// <param name="index">Laufende Nummer des ersten zu dekomprimierenden Wertes.</param> /// <param name="count">Die Anzahl der zur Dekomprimierung zu verwenden Werte.</param> /// <returns>Die dekomprimierte Zeichenketten - bei Fehlern wird ein <i>...</i> angehängt.</returns> /// <exception cref="ArgumentException">Mindestens ein Parameter ist unzulässig.</exception> public override string GetString(byte[] bytes, int index, int count) { // Validate if (count < 1) { return(string.Empty); } // Get the table ushort[] table = null; if (1 == bytes[index]) { table = BinaryTables[0]; } else if (2 == bytes[index]) { table = BinaryTables[1]; } // Not table if (null == table) { return(Section.DefaultEncoding.GetString(bytes, index, count)); } // Advance index ++index; --count; // Nothing in it if (count < 1) { return(string.Empty); } // Remember int initialIndex = index, initialCount = count; // Constructor List <byte> builder = new List <byte>(); // Set current processing index ushort tableIndex = table[0]; // Current index shift int indexShift = 0; // Previous pattern and width uint?previous = null; // Last checkpoint int lastCharPosition = 0; // Process for (; ;) { // Check for regular stop if (0 == tableIndex) { // Load the initial check pattern byte check = (byte)(0xff >> indexShift); // All bytes must be zero for (; count-- > 0; check = 0xff) { if (0 != (bytes[index++] & check)) { break; } } // Found something bad if (count >= 0) { break; } // Load result string decompressed = Encoding.UTF8.GetString(builder.ToArray()); // Load client EventHandler <DecodingReportArgs> successHandler = OnSuccess; // Report if (null != successHandler) { // Create full data byte[] compressed = new byte[initialCount]; // Fill it Array.Copy(bytes, initialIndex, compressed, 0, compressed.Length); // Create argument list DecodingReportArgs args = new DecodingReportArgs(); // Fill it args.CodePage = (table == BinaryTables[0]) ? 1 : 2; args.Uncompressed = decompressed; args.CompressedData = compressed; // Report successHandler(this, args); } // Report return(decompressed); } // Unexpected end of input if (count < 1) { break; } // Check for leaf if (tableIndex <= 127) { // At this position lastCharPosition = 8 * (index - initialIndex) + indexShift; // Append builder.Add((byte)('\x0001' + tableIndex - 1)); // Restart tableIndex = table[tableIndex]; } // In error if (tableIndex == TableCreator.ErrorIndicator) { break; } // Check for escape mode bool inEscape = (tableIndex == TableCreator.EscapeIndicator); // Get the number of bits to process ushort bitWidth = inEscape ? (ushort)8 : table[tableIndex++]; // Check limitation if (bitWidth > 24) { break; } // Not possible if (bitWidth > 8 * count) { break; } // The pattern uint pattern; // Quick load pattern if (previous.HasValue) { // Use pattern = previous.Value; } else { // The pattern pattern = bytes[index + 0]; // Append pattern <<= 8; if (count > 1) { pattern |= bytes[index + 1]; } // Append pattern <<= 8; if (count > 2) { pattern |= bytes[index + 2]; } // Append pattern <<= 8; if (count > 3) { pattern |= bytes[index + 3]; } // Remember previous = pattern; } // Correct it pattern <<= indexShift; // Adjust shift indexShift += bitWidth; // Adjust index if (indexShift >= 8) { // Shift bytes int bytesEaten = indexShift / 8; // Adjust all index += bytesEaten; count -= bytesEaten; indexShift %= 8; // Clear cache previous = null; } // Check for escape mode if (inEscape) { // At this position lastCharPosition = 8 * (index - initialIndex) + indexShift; // Get character pattern >>= 24; // See if this is it if (pattern < 128) { if (0 == pattern) { tableIndex = 0; } else { tableIndex = (ushort)(1 + (pattern - 1)); } } else { builder.Add((byte)pattern); } // Next continue; } // Get the first link position ushort linkIndex = table[tableIndex++]; // Translate the pattern uint patternIndex = pattern >> (32 - bitWidth); // Check mode if (linkIndex == TableCreator.EndIndicator) { // Attach to the entry tableIndex = table[tableIndex + patternIndex]; } else { // Try to find do { // Test pattern - upper half uint test = table[linkIndex - 4]; // Test pattern - lower half test <<= 16; test |= table[linkIndex - 3]; // Next table tableIndex = table[linkIndex - 2]; // Did it if (test == patternIndex) { break; } // Advance linkIndex = table[linkIndex - 1]; }while (linkIndex != TableCreator.EndIndicator); // In error if (linkIndex == TableCreator.EndIndicator) { break; } } } // Load client EventHandler <DecodingFailureArgs> handler = OnFailure; // Report if (null != handler) { // Create full data byte[] compressed = new byte[initialCount]; // Fill it Array.Copy(bytes, initialIndex, compressed, 0, compressed.Length); // Create argument list DecodingFailureArgs args = new DecodingFailureArgs(); // Fill it args.Uncompressed = Encoding.UTF8.GetString(builder.ToArray()); args.CodePage = (table == BinaryTables[0]) ? 1 : 2; args.BitPosition = lastCharPosition; args.CompressedData = compressed; // Report handler(this, args); } // Report return(Encoding.UTF8.GetString(builder.ToArray()) + "...."); }
/// <summary> /// Dekomprimiert eine Zeichenkette. /// </summary> /// <param name="bytes">Feld mit den dekomprimierten Werten.</param> /// <param name="index">Laufende Nummer des ersten zu dekomprimierenden Wertes.</param> /// <param name="count">Die Anzahl der zur Dekomprimierung zu verwenden Werte.</param> /// <returns>Die dekomprimierte Zeichenketten - bei Fehlern wird ein <i>...</i> angehängt.</returns> /// <exception cref="ArgumentException">Mindestens ein Parameter ist unzulässig.</exception> public override string GetString( byte[] bytes, int index, int count ) { // Validate if (count < 1) return string.Empty; // Get the table ushort[] table = null; if (1 == bytes[index]) table = BinaryTables[0]; else if (2 == bytes[index]) table = BinaryTables[1]; // Not table if (null == table) return Section.DefaultEncoding.GetString( bytes, index, count ); // Advance index ++index; --count; // Nothing in it if (count < 1) return string.Empty; // Remember int initialIndex = index, initialCount = count; // Constructor List<byte> builder = new List<byte>(); // Set current processing index ushort tableIndex = table[0]; // Current index shift int indexShift = 0; // Previous pattern and width uint? previous = null; // Last checkpoint int lastCharPosition = 0; // Process for (; ; ) { // Check for regular stop if (0 == tableIndex) { // Load the initial check pattern byte check = (byte) (0xff >> indexShift); // All bytes must be zero for (; count-- > 0; check = 0xff) if (0 != (bytes[index++] & check)) break; // Found something bad if (count >= 0) break; // Load result string decompressed = Encoding.UTF8.GetString( builder.ToArray() ); // Load client EventHandler<DecodingReportArgs> successHandler = OnSuccess; // Report if (null != successHandler) { // Create full data byte[] compressed = new byte[initialCount]; // Fill it Array.Copy( bytes, initialIndex, compressed, 0, compressed.Length ); // Create argument list DecodingReportArgs args = new DecodingReportArgs(); // Fill it args.CodePage = (table == BinaryTables[0]) ? 1 : 2; args.Uncompressed = decompressed; args.CompressedData = compressed; // Report successHandler( this, args ); } // Report return decompressed; } // Unexpected end of input if (count < 1) break; // Check for leaf if (tableIndex <= 127) { // At this position lastCharPosition = 8 * (index - initialIndex) + indexShift; // Append builder.Add( (byte) ('\x0001' + tableIndex - 1) ); // Restart tableIndex = table[tableIndex]; } // In error if (tableIndex == TableCreator.ErrorIndicator) break; // Check for escape mode bool inEscape = (tableIndex == TableCreator.EscapeIndicator); // Get the number of bits to process ushort bitWidth = inEscape ? (ushort) 8 : table[tableIndex++]; // Check limitation if (bitWidth > 24) break; // Not possible if (bitWidth > 8 * count) break; // The pattern uint pattern; // Quick load pattern if (previous.HasValue) { // Use pattern = previous.Value; } else { // The pattern pattern = bytes[index + 0]; // Append pattern <<= 8; if (count > 1) pattern |= bytes[index + 1]; // Append pattern <<= 8; if (count > 2) pattern |= bytes[index + 2]; // Append pattern <<= 8; if (count > 3) pattern |= bytes[index + 3]; // Remember previous = pattern; } // Correct it pattern <<= indexShift; // Adjust shift indexShift += bitWidth; // Adjust index if (indexShift >= 8) { // Shift bytes int bytesEaten = indexShift / 8; // Adjust all index += bytesEaten; count -= bytesEaten; indexShift %= 8; // Clear cache previous = null; } // Check for escape mode if (inEscape) { // At this position lastCharPosition = 8 * (index - initialIndex) + indexShift; // Get character pattern >>= 24; // See if this is it if (pattern < 128) if (0 == pattern) tableIndex = 0; else tableIndex = (ushort) (1 + (pattern - 1)); else builder.Add( (byte) pattern ); // Next continue; } // Get the first link position ushort linkIndex = table[tableIndex++]; // Translate the pattern uint patternIndex = pattern >> (32 - bitWidth); // Check mode if (linkIndex == TableCreator.EndIndicator) { // Attach to the entry tableIndex = table[tableIndex + patternIndex]; } else { // Try to find do { // Test pattern - upper half uint test = table[linkIndex - 4]; // Test pattern - lower half test <<= 16; test |= table[linkIndex - 3]; // Next table tableIndex = table[linkIndex - 2]; // Did it if (test == patternIndex) break; // Advance linkIndex = table[linkIndex - 1]; } while (linkIndex != TableCreator.EndIndicator); // In error if (linkIndex == TableCreator.EndIndicator) break; } } // Load client EventHandler<DecodingFailureArgs> handler = OnFailure; // Report if (null != handler) { // Create full data byte[] compressed = new byte[initialCount]; // Fill it Array.Copy( bytes, initialIndex, compressed, 0, compressed.Length ); // Create argument list DecodingFailureArgs args = new DecodingFailureArgs(); // Fill it args.Uncompressed = Encoding.UTF8.GetString( builder.ToArray() ); args.CodePage = (table == BinaryTables[0]) ? 1 : 2; args.BitPosition = lastCharPosition; args.CompressedData = compressed; // Report handler( this, args ); } // Report return Encoding.UTF8.GetString( builder.ToArray() ) + "...."; }