xtd 0.2.0
Loading...
Searching...
No Matches
css_reader.hpp
Go to the documentation of this file.
1
4#pragma once
5#include "selector_map.hpp"
6#include "../..//io/stream_reader.hpp"
7#include "../../argument_exception.hpp"
8#include "../../format_exception.hpp"
9#include "../../object.hpp"
10
12namespace xtd {
14 namespace web {
15 namespace css {
16 class css_reader : public object {
17 public:
19
21 css_reader(std::istream& stream) {parse_text(xtd::io::stream_reader(stream).read_to_end());}
22 css_reader(xtd::io::text_reader& text_reader) {parse_text(text_reader.read_to_end());}
23 css_reader(const xtd::string& text) {parse_text(text);}
25
27
29 const xtd::web::css::selector_map& selectors() const noexcept {return selectors_;}
31
32 private:
33 void parse_text(const xtd::string& text) {
34 enum class parse_status {
36 key,
37 value
38 };
39 parse_status status = parse_status::selector;
40 size_t start_index = 0;
41 xtd::web::css::selector current_selector;
42 xtd::string current_selector_name;
43 xtd::string current_key;
44 for (size_t index = 0; index < text.size(); index++) {
45 if (text[index] == '/' && text[index + 1] == '*') {
46 // Skip comments...
47 index = text.index_of("*/", index + 2);
48 if (index == text.npos) throw xtd::format_exception("expected end comment"_t);
49 index++;
50 start_index = index + 1;
51 continue;
52 } else if (status == parse_status::selector && text[index] == '{') {
53 current_selector_name = text.substring(start_index, index - start_index).trim();
54 current_selector.name(text.substring(start_index, index - start_index).trim());
55 start_index = index + 1;
56 status = parse_status::key;
57 } else if (status == parse_status::key && text[index] == '}') {
58 selectors_[current_selector_name] = current_selector;
59 current_selector = xtd::web::css::selector();
60 start_index = index + 1;
61 status = parse_status::selector;
62 } else if (status == parse_status::key && text[index] == ':') {
63 current_key = text.substring(start_index, index - start_index).trim().to_lower();
64 if (current_key.empty()) throw xtd::format_exception("key cannot be empty"_t);
65 start_index = index + 1;
66 status = parse_status::value;
67 } else if (status == parse_status::value && text[index] == ';') {
68 auto value = text.substring(start_index, index - start_index).trim();
69 if (value.empty()) throw xtd::format_exception("value cannot be empty"_t);
70 start_index = index + 1;
71 current_selector.properties()[current_key] = property(value);
72 status = parse_status::key;
73 }
74 }
75 }
76
78 };
79 }
80 }
81}
Represents text as a sequence of character units.
Definition basic_string.hpp:79
bool empty() const noexcept
Checks if the string has no characters, i.e. whether begin() == end().
Definition basic_string.hpp:904
The exception that is thrown when the format of an argument does not meet the parameter specification...
Definition format_exception.hpp:19
Implements a xtd::io::text_reader that reads characters from a byte stream.
Definition stream_reader.hpp:28
Represents a reader that can read a sequential series of characters.
Definition text_reader.hpp:36
virtual xtd::string read_to_end()
Reads all characters from the current position to the end of the text_reader and returns them as one ...
Supports all classes in the xtd class hierarchy and provides low-level services to derived classes....
Definition object.hpp:42
Definition css_reader.hpp:16
Definition property.hpp:13
Definition selector.hpp:12
The xtd namespace contains all fundamental classes to access Hardware, Os, System,...
Definition xtd_about_box.hpp:10
Contains xtd::web::css::selector_map alias.
std::map< xtd::string, xtd::web::css::selector > selector_map
Represents the map of a selector name - selector pair.
Definition selector_map.hpp:13