Esempio n. 1
0
        public Samples LoadSamples(string name, string[] lines)
        {
            int  numCols          = 1;
            int  genderCol        = 0;
            int  rarityCol        = 0;
            bool hasMaleNonRare   = false;
            bool hasFemaleNonRare = false;
            int  i = 0;

            // Skip blank lines and comments that don't contain a comma
            while (i < lines.Length && (lines[i].Trim().Length == 0 || (lines[i][0] == '#' && !lines[i].Contains(','))))
            {
                i++;
            }

            // Is there a header?
            if (i < lines.Length && lines[i][0] == '#' && lines[i].Contains(','))
            {
                var colNames = lines[i].Split(',');
                numCols = colNames.Length;

                if (numCols > 3)
                {
                    throw new Exception($"Multi-column samples '{name}' header must have 2 or 3 columns");
                }

                // Don't validate name of first column (can be anything)
                for (int col = 1; col < numCols; col++)
                {
                    string  colName = colNames[col].Trim();
                    Columns colType;
                    try
                    {
                        colType = (Columns)Enum.Parse(typeof(Columns), colName, true);
                    }
                    catch (ArgumentException)
                    {
                        throw new Exception($"Multi-column samples '{name}' header has invalid column name '{colName}' - " +
                                            $"must be one of: {String.Join(", ", Enum.GetNames(typeof(Columns)))}");
                    }

                    switch (colType)
                    {
                    case Columns.GENDER:
                        genderCol = col;
                        break;

                    case Columns.RARITY:
                        rarityCol = col;
                        break;

                    default:
                        throw new Exception($"SamplesParser missing code for column type: {colType}");
                    }
                }

                i++;
            }

            var samples = new Samples(name, genderCol != 0);

            while (i < lines.Length)
            {
                string value = lines[i].Trim();

                // Skip empty lines and comments
                if (value.Length == 0 || value[0] == '#')
                {
                    i++;
                    continue;
                }

                Sample.Genders gender = Sample.Genders.NEUTRAL;
                int            rarity = 0;

                if (numCols > 1)
                {
                    var columns = value.Split(',');

                    if (columns.Length > numCols)
                    {
                        throw new Exception($"Multi-column samples file '{name}' line {i + 1} " +
                                            $"has too many columns (or embedded comma) - must match number of columns in header.");
                    }

                    string[] colData = new string[numCols];

                    for (int col = 0; col < numCols; col++)
                    {
                        if (col < columns.Length)
                        {
                            colData[col] = columns[col].Trim();
                        }
                        else
                        {
                            colData[col] = "";
                        }
                    }

                    value = colData[0];
                    if (value.Length == 0)
                    {
                        throw new Exception($"Multi-column samples file '{name}' line {i + 1} " +
                                            $"value cannot be blank. Use <null> if you want a null value.");
                    }

                    if (genderCol != 0)
                    {
                        string genderStr = colData[genderCol].ToUpper();

                        if (genderStr.Length > 0)
                        {
                            if (genderStr.Equals("M"))
                            {
                                gender = Sample.Genders.MALE;
                            }
                            else if (genderStr.Equals("F"))
                            {
                                gender = Sample.Genders.FEMALE;
                            }
                            else
                            {
                                throw new Exception($"Multi-column samples file '{name}' line {i + 1} " +
                                                    $"has gender '{genderStr}' but expected M or F");
                            }
                        }
                    }

                    if (rarityCol != 0)
                    {
                        string rarityStr = colData[rarityCol];

                        if (rarityStr.Length > 0)
                        {
                            try
                            {
                                rarity = int.Parse(rarityStr);
                            }
                            catch (Exception)
                            {
                                throw new Exception($"Multi-column samples file '{name}' line {i + 1} " +
                                                    $"has non-integer rarity '{rarityStr}'");
                            }

                            if (rarity < 1 || rarity > 99)
                            {
                                throw new Exception($"Multi-column samples file '{name}' line {i + 1} " +
                                                    $"has rarity {rarity} but expected either blank or value between 1 and 99");
                            }
                        }
                    }
                }

                if ((gender == Sample.Genders.MALE || gender == Sample.Genders.NEUTRAL) && rarity == 0)
                {
                    hasMaleNonRare = true;
                }

                if ((gender == Sample.Genders.FEMALE || gender == Sample.Genders.NEUTRAL) && rarity == 0)
                {
                    hasFemaleNonRare = true;
                }

                samples.AddSample(new Sample(value, gender, rarity));
                i++;
            }

            // Samples must contain at least one sample. If gendered, must be
            // true for both male and female. If rarity, there must be at least
            // one non-rare sample.
            if (!hasMaleNonRare)
            {
                StringBuilder modifier = new StringBuilder();
                if (genderCol != 0)
                {
                    modifier.Append(" Male");
                }
                if (rarityCol != 0)
                {
                    modifier.Append(modifier.Length == 0? " " : ", ");
                    modifier.Append("Non-rare (rarity left blank)");
                }

                throw new Exception($"Samples file '{name}' " +
                                    $"must have at least one{modifier} sample");
            }

            if (genderCol != 0 && !hasFemaleNonRare)
            {
                StringBuilder modifier = new StringBuilder();
                if (genderCol != 0)
                {
                    modifier.Append(" Female");
                }
                if (rarityCol != 0)
                {
                    modifier.Append(modifier.Length == 0 ? " " : ", ");
                    modifier.Append("Non-rare (rarity left blank)");
                }

                throw new Exception($"Multi-column samples file '{name}' " +
                                    $"must have at least one{modifier} sample");
            }

            return(samples);
        }