Beispiel #1
0
        private bool CheckIndices(int[] Indices, ShocoPack Pack)
        {
            // TODO: Investigate hardware acceleration

            for (int i = 0; i < Pack.BytesUnpacked; ++i)
            {
                if (Indices[i] > Pack.masks[i])
                {
                    return(false);
                }
            }

            return(true);
        }
Beispiel #2
0
        /// <summary>
        /// Reads a C Header into a ShocoModel
        /// </summary>
        /// <param name="FileContent">C Header source</param>
        /// <returns>ShocoModel representation from the C Header</returns>
        public static ShocoModel ReadFromCHeaderContent(string FileContent)
        {
            Match             match;
            Match             subMatch;
            CaptureCollection captures;
            int dimention1;
            int dimention2;

            int minimumCharacter;
            int maximumCharacter;
            int maximumSuccessorLength;

            byte[] charactersById;
            byte[] idsByCharacter;
            byte[,] successorIdsByCharacterId = null;
            byte[,] charactersBySuccessorId   = null;
            ShocoPack[] packs;

            match = Regex.Match(FileContent, @"^#define\s+MIN_CHR\s+(\d+)", RegexOptions.Multiline);
            if (!match.Success)
            {
                throw new ArgumentException("Could not extract MIN_CHR value", nameof(FileContent));
            }
            if (!int.TryParse(match.Groups[1].Value, out minimumCharacter))
            {
                throw new ArgumentException("Invalid MIN_CHR value present", nameof(FileContent));
            }

            match = Regex.Match(FileContent, @"^#define\s+MAX_CHR\s+(\d+)", RegexOptions.Multiline);
            if (!match.Success)
            {
                throw new ArgumentException("Could not extract MAX_CHR value", nameof(FileContent));
            }
            if (!int.TryParse(match.Groups[1].Value, out maximumCharacter))
            {
                throw new ArgumentException("Invalid MAX_CHR value present", nameof(FileContent));
            }

            match = Regex.Match(FileContent, @"^#define\s+MAX_SUCCESSOR_N\s+(\d+)", RegexOptions.Multiline);
            if (!match.Success)
            {
                throw new ArgumentException("Could not extract MAX_SUCCESSOR_N value", nameof(FileContent));
            }
            if (!int.TryParse(match.Groups[1].Value, out maximumSuccessorLength))
            {
                throw new ArgumentException("Invalid MAX_CHR value present", nameof(FileContent));
            }

            match = Regex.Match(FileContent, @"chrs_by_chr_id\[[^{}]+?{(?:\s*'(\\[abfnrtv\\'""?e]|\\\d\d\d|\\x[\dA-Fa-f]{2}|.)'\s*,?\s*)+}");
            if (!match.Success)
            {
                throw new ArgumentException("Could not extract chrs_by_chr_id values", nameof(FileContent));
            }
            charactersById = match.Groups[1].Captures.Cast <Capture>().Select(c => c.Value).Select(UnescapeC).ToArray();

            match = Regex.Match(FileContent, @"chr_ids_by_chr\[[^{}]+?{(?:\s*([\d-]+)\s*,?\s*)+}");
            if (!match.Success)
            {
                throw new ArgumentException("Could not extract chr_ids_by_chr values", nameof(FileContent));
            }
            idsByCharacter = match.Groups[1].Captures.Cast <Capture>().Select(c => c.Value).Select(ParseCByte).ToArray();

            match = Regex.Match(FileContent, @"successor_ids_by_chr_id_and_chr_id\[[^{}]+?{(?:\s*{((?:\s*[\d-]+\s*,?\s*)+)}\s*,?)*}");
            if (!match.Success)
            {
                throw new ArgumentException("Could not extract successor_ids_by_chr_id_and_chr_id values", nameof(FileContent));
            }
            dimention1 = match.Groups[1].Captures.Count;
            dimention2 = 0;
            for (int d1 = 0; d1 < dimention1; d1++)
            {
                subMatch = Regex.Match(match.Groups[1].Captures[d1].Value, @"(?:\s*([\d-]+)\s*,?\s*)+");
                if (!subMatch.Success)
                {
                    throw new ArgumentException("Could not extract successor_ids_by_chr_id_and_chr_id values", nameof(FileContent));
                }
                captures = subMatch.Groups[1].Captures;
                if (successorIdsByCharacterId == null)
                {
                    dimention2 = captures.Count;
                    successorIdsByCharacterId = new byte[dimention1, dimention2];
                }
                for (int d2 = 0; d2 < dimention2; d2++)
                {
                    successorIdsByCharacterId[d1, d2] = ParseCByte(captures[d2].Value);
                }
            }

            match = Regex.Match(FileContent, @"chrs_by_chr_and_successor_id\[[^{}]+?{(\s*{(?:\s*'(?:\\[abfnrtv\\'""?e]|\\\d\d\d|\\x[\dA-Fa-f]{2}|.)'\s*,?\s*)+}\s*,?)*}");
            if (!match.Success)
            {
                throw new ArgumentException("Could not extract chrs_by_chr_and_successor_id values", nameof(FileContent));
            }
            dimention1 = match.Groups[1].Captures.Count;
            if (dimention1 != maximumCharacter - minimumCharacter)
            {
                throw new ArgumentException("Could not extract chrs_by_chr_and_successor_id values; invalid length", nameof(FileContent));
            }
            dimention2 = 0;
            for (int d1 = 0; d1 < dimention1; d1++)
            {
                subMatch = Regex.Match(match.Groups[1].Captures[d1].Value, @"(?:\s*'(\\[abfnrtv\\'""?e]|\\\d\d\d|\\x[\dA-Fa-f]{2}|.)'\s*,?\s*)+");
                if (!subMatch.Success)
                {
                    throw new ArgumentException("Could not extract chrs_by_chr_and_successor_id values", nameof(FileContent));
                }
                captures = subMatch.Groups[1].Captures;
                if (charactersBySuccessorId == null)
                {
                    dimention2 = captures.Count;
                    charactersBySuccessorId = new byte[dimention1, dimention2];
                }
                for (int d2 = 0; d2 < dimention2; d2++)
                {
                    charactersBySuccessorId[d1, d2] = UnescapeC(captures[d2].Value);
                }
            }

            match = Regex.Match(FileContent, @"Pack packs\[[^{}]+?{(\s*{\s*0x[^\s,]*\s*,\s*\d+\s*,\s*\d+\s*,\s*{[^}]*}\s*,\s*{[^}]*}\s*,\s*0x[0-9A-Fa-f]{2}\s*,\s*0x[0-9A-Fa-f]{2}\s*}\s*,?)+\s*}");
            if (!match.Success)
            {
                throw new ArgumentException("Could not extract packs", nameof(FileContent));
            }
            packs = new ShocoPack[match.Groups[1].Captures.Count];
            for (int i = 0; i < packs.Length; i++)
            {
                var capture = match.Groups[1].Captures[i];
                subMatch = Regex.Match(capture.Value, @"\s*{\s*0x([^\s,]*)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*{(?:\s*(\d+)\s*,?)*}\s*,\s*{(?:\s*(\d+)\s*,?)*}\s*,\s*0x[0-9A-Fa-f]{2}\s*,\s*0x[0-9A-Fa-f]{2}\s*}");
                if (!subMatch.Success)
                {
                    throw new ArgumentException("Could not extract pack", nameof(FileContent));
                }
                if (!uint.TryParse(subMatch.Groups[1].Value, NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture, out var code_word))
                {
                    throw new ArgumentException("Could not extract pack code word", nameof(FileContent));
                }
                if (!int.TryParse(subMatch.Groups[2].Value, out var bytes_packed))
                {
                    throw new ArgumentException("Could not extract pack bytes_packed", nameof(FileContent));
                }
                if (!int.TryParse(subMatch.Groups[3].Value, out var bytes_unpacked))
                {
                    throw new ArgumentException("Could not extract pack bytes_unpacked", nameof(FileContent));
                }
                var offsets = subMatch.Groups[4].Captures.Cast <Capture>().Select(c => c.Value).Select(int.Parse).ToArray();
                var masks   = subMatch.Groups[5].Captures.Cast <Capture>().Select(c => c.Value).Select(int.Parse).ToArray();

                packs[i] = new ShocoPack(
                    Header: (byte)(code_word >> 24),
                    BytesPacked: bytes_packed,
                    BytesUnpacked: bytes_unpacked,
                    Offsets: offsets,
                    Masks: masks);
            }

            return(new ShocoModel(minimumCharacter, maximumCharacter, maximumSuccessorLength,
                                  charactersById, idsByCharacter, successorIdsByCharacterId, charactersBySuccessorId,
                                  packs));
        }