| 100 | } |
| 101 | |
| 102 | bool SC::PluginDefinition::parse(StringSpan text, PluginDefinition& pluginDefinition) |
| 103 | { |
| 104 | struct Cursor |
| 105 | { |
| 106 | StringSpan text; |
| 107 | size_t offset = 0; |
| 108 | |
| 109 | bool parseLine(StringSpan& key, StringSpan& value) |
| 110 | { |
| 111 | if (text.getEncoding() == StringEncoding::Utf16) |
| 112 | return false; |
| 113 | const auto isSkipped = [](char current) |
| 114 | { return current == '\t' or current == '\n' or current == '\r' or current == ' ' or current == '/'; }; |
| 115 | while (offset < text.sizeInBytes() and isSkipped(text.bytesWithoutTerminator()[offset])) |
| 116 | ++offset; |
| 117 | const size_t keyStart = offset; |
| 118 | while (offset < text.sizeInBytes() and text.bytesWithoutTerminator()[offset] != ':' and |
| 119 | not isSkipped(text.bytesWithoutTerminator()[offset])) |
| 120 | ++offset; |
| 121 | key = PluginString::slice(text, keyStart, offset - keyStart); |
| 122 | while (offset < text.sizeInBytes() and isSkipped(text.bytesWithoutTerminator()[offset])) |
| 123 | ++offset; |
| 124 | if (offset >= text.sizeInBytes() or text.bytesWithoutTerminator()[offset++] != ':') |
| 125 | return false; |
| 126 | while (offset < text.sizeInBytes() and isSkipped(text.bytesWithoutTerminator()[offset])) |
| 127 | ++offset; |
| 128 | const size_t valueStart = offset; |
| 129 | while (offset < text.sizeInBytes() and text.bytesWithoutTerminator()[offset] != '\n' and |
| 130 | text.bytesWithoutTerminator()[offset] != '\r') |
| 131 | ++offset; |
| 132 | value = PluginString::slice(text, valueStart, offset - valueStart); |
| 133 | const bool endedByNewLine = offset < text.sizeInBytes(); |
| 134 | while (offset < text.sizeInBytes() and |
| 135 | (text.bytesWithoutTerminator()[offset] == '\n' or text.bytesWithoutTerminator()[offset] == '\r')) |
| 136 | ++offset; |
| 137 | return endedByNewLine or not value.isEmpty(); |
| 138 | } |
| 139 | } cursor{text}; |
| 140 | |
| 141 | StringSpan key, value; |
| 142 | bool gotFields[4] = {false}; |
| 143 | while (cursor.parseLine(key, value)) |
| 144 | { |
| 145 | if (key == "Name") |
| 146 | { |
| 147 | gotFields[0] = true; |
| 148 | SC_TRY_MSG(pluginDefinition.identity.name.assign(value), "Name exceeds fixed size"); |
| 149 | } |
| 150 | else if (key == "Version") |
| 151 | { |
| 152 | gotFields[1] = true; |
| 153 | SC_TRY_MSG(pluginDefinition.identity.version.assign(value), "Version exceeds fixed size"); |
| 154 | } |
| 155 | else if (key == "Description") |
| 156 | { |
| 157 | gotFields[2] = true; |
| 158 | SC_TRY_MSG(pluginDefinition.description.assign(value), "Description exceeds fixed size"); |
| 159 | } |