| 859 | |
| 860 | |
| 861 | Option<Error> Resources::validate(const Resource& resource) |
| 862 | { |
| 863 | if (resource.name().empty()) { |
| 864 | return Error("Empty resource name"); |
| 865 | } |
| 866 | |
| 867 | if (!Value::Type_IsValid(resource.type())) { |
| 868 | return Error("Invalid resource type"); |
| 869 | } |
| 870 | |
| 871 | if (resource.type() == Value::SCALAR) { |
| 872 | if (!resource.has_scalar() || |
| 873 | resource.has_ranges() || |
| 874 | resource.has_set()) { |
| 875 | return Error("Invalid scalar resource"); |
| 876 | } |
| 877 | |
| 878 | if (resource.scalar().value() < 0) { |
| 879 | return Error("Invalid scalar resource: value < 0"); |
| 880 | } |
| 881 | } else if (resource.type() == Value::RANGES) { |
| 882 | if (resource.has_scalar() || |
| 883 | !resource.has_ranges() || |
| 884 | resource.has_set()) { |
| 885 | return Error("Invalid ranges resource"); |
| 886 | } |
| 887 | |
| 888 | for (int i = 0; i < resource.ranges().range_size(); i++) { |
| 889 | const Value::Range& range = resource.ranges().range(i); |
| 890 | |
| 891 | // Ensure the range make sense (isn't inverted). |
| 892 | if (range.begin() > range.end()) { |
| 893 | return Error("Invalid ranges resource: begin > end"); |
| 894 | } |
| 895 | |
| 896 | // Ensure ranges don't overlap (but not necessarily coalesced). |
| 897 | for (int j = i + 1; j < resource.ranges().range_size(); j++) { |
| 898 | if (range.begin() <= resource.ranges().range(j).begin() && |
| 899 | resource.ranges().range(j).begin() <= range.end()) { |
| 900 | return Error("Invalid ranges resource: overlapping ranges"); |
| 901 | } |
| 902 | } |
| 903 | } |
| 904 | } else if (resource.type() == Value::SET) { |
| 905 | if (resource.has_scalar() || |
| 906 | resource.has_ranges() || |
| 907 | !resource.has_set()) { |
| 908 | return Error("Invalid set resource"); |
| 909 | } |
| 910 | |
| 911 | for (int i = 0; i < resource.set().item_size(); i++) { |
| 912 | const string& item = resource.set().item(i); |
| 913 | |
| 914 | // Ensure no duplicates. |
| 915 | for (int j = i + 1; j < resource.set().item_size(); j++) { |
| 916 | if (item == resource.set().item(j)) { |
| 917 | return Error("Invalid set resource: duplicated elements"); |
| 918 | } |