| 836 | |
| 837 | |
| 838 | Option<Error> Resources::validate(const Resource& resource) |
| 839 | { |
| 840 | if (resource.name().empty()) { |
| 841 | return Error("Empty resource name"); |
| 842 | } |
| 843 | |
| 844 | if (!Value::Type_IsValid(resource.type())) { |
| 845 | return Error("Invalid resource type"); |
| 846 | } |
| 847 | |
| 848 | if (resource.type() == Value::SCALAR) { |
| 849 | if (!resource.has_scalar() || |
| 850 | resource.has_ranges() || |
| 851 | resource.has_set()) { |
| 852 | return Error("Invalid scalar resource"); |
| 853 | } |
| 854 | |
| 855 | // We do not allow negative scalar resource values or |
| 856 | // non-zero values which would be represented as zero. |
| 857 | if (resource.scalar().value() != 0 && |
| 858 | resource.scalar() <= Value::Scalar()) { |
| 859 | return Error("Invalid scalar resource: value <= 0"); |
| 860 | } |
| 861 | } else if (resource.type() == Value::RANGES) { |
| 862 | if (resource.has_scalar() || |
| 863 | !resource.has_ranges() || |
| 864 | resource.has_set()) { |
| 865 | return Error("Invalid ranges resource"); |
| 866 | } |
| 867 | |
| 868 | for (int i = 0; i < resource.ranges().range_size(); i++) { |
| 869 | const Value::Range& range = resource.ranges().range(i); |
| 870 | |
| 871 | // Ensure the range make sense (isn't inverted). |
| 872 | if (range.begin() > range.end()) { |
| 873 | return Error("Invalid ranges resource: begin > end"); |
| 874 | } |
| 875 | |
| 876 | // Ensure ranges don't overlap (but not necessarily coalesced). |
| 877 | for (int j = i + 1; j < resource.ranges().range_size(); j++) { |
| 878 | if (range.begin() <= resource.ranges().range(j).begin() && |
| 879 | resource.ranges().range(j).begin() <= range.end()) { |
| 880 | return Error("Invalid ranges resource: overlapping ranges"); |
| 881 | } |
| 882 | } |
| 883 | } |
| 884 | } else if (resource.type() == Value::SET) { |
| 885 | if (resource.has_scalar() || |
| 886 | resource.has_ranges() || |
| 887 | !resource.has_set()) { |
| 888 | return Error("Invalid set resource"); |
| 889 | } |
| 890 | |
| 891 | for (int i = 0; i < resource.set().item_size(); i++) { |
| 892 | const string& item = resource.set().item(i); |
| 893 | |
| 894 | // Ensure no duplicates. |
| 895 | for (int j = i + 1; j < resource.set().item_size(); j++) { |