private static IEnumerable <ExtractedString> Extract(Stream data, long base_offset, int minimum_length, ExtractedStringType type, string source) { if (data is null) { throw new ArgumentNullException(nameof(data)); } if (minimum_length <= 0) { throw new ArgumentException("Must specify a minimum length of at least 1."); } StringBuilder ascii = new StringBuilder(); StringBuilder unicode = new StringBuilder(); StringBuilder unicode_unaligned = new StringBuilder(); bool parse_ascii = type.HasFlagSet(ExtractedStringType.Ascii); bool parse_unicode = type.HasFlagSet(ExtractedStringType.Unicode); byte[] unicode_char = new byte[2]; int b = data.ReadByte(); long i = 0; while (b >= 0) { if (parse_ascii) { char c = (char)b; if (IsPrintable(c)) { ascii.Append(c); } else { if (ascii.Length >= minimum_length) { yield return(ascii.CreateResult(base_offset, i, ExtractedStringType.Ascii, source)); } ascii.Clear(); } } if (parse_unicode) { unicode_char[0] = unicode_char[1]; unicode_char[1] = (byte)b; char c = BitConverter.ToChar(unicode_char, 0); if ((i & 1) == 1) { if (IsPrintable(c)) { unicode.Append(c); } else { if (unicode.Length >= minimum_length) { yield return(unicode.CreateResult(base_offset, i, ExtractedStringType.Unicode, source)); } unicode.Clear(); } } else if (i > 1) { if (IsPrintable(c)) { unicode_unaligned.Append(c); } else { if (unicode_unaligned.Length >= minimum_length) { yield return(unicode_unaligned.CreateResult(base_offset, i, ExtractedStringType.Unicode, source)); } unicode_unaligned.Clear(); } } } i++; b = data.ReadByte(); } if (ascii.Length >= minimum_length) { yield return(ascii.CreateResult(base_offset, i, ExtractedStringType.Ascii, source)); } if (unicode.Length >= minimum_length) { yield return(unicode.CreateResult(base_offset, i, ExtractedStringType.Unicode, source)); } if (unicode_unaligned.Length >= minimum_length) { yield return(unicode_unaligned.CreateResult(base_offset, i, ExtractedStringType.Unicode, source)); } }
private static ExtractedString CreateResult(this StringBuilder builder, long base_offset, long i, ExtractedStringType type, string source) { int str_length = type.HasFlagSet(ExtractedStringType.Unicode) ? (builder.Length * 2 + 1) : builder.Length; return(new ExtractedString(builder.ToString(), base_offset + i - str_length, type, source)); }