1 | /* |
2 | * Copyright 2020 Google LLC |
3 | * |
4 | * Use of this source code is governed by a BSD-style license that can be |
5 | * found in the LICENSE file. |
6 | */ |
7 | |
8 | #ifndef SKSL_DEHYDRATOR |
9 | #define SKSL_DEHYDRATOR |
10 | |
11 | #ifdef SKSL_STANDALONE |
12 | |
13 | #include "src/sksl/SkSLOutputStream.h" |
14 | #include "src/sksl/SkSLStringStream.h" |
15 | #include "src/sksl/ir/SkSLModifiers.h" |
16 | #include "src/sksl/ir/SkSLSymbol.h" |
17 | |
18 | #include <set> |
19 | #include <unordered_map> |
20 | #include <vector> |
21 | |
22 | namespace SkSL { |
23 | |
24 | struct Expression; |
25 | struct ProgramElement; |
26 | struct Statement; |
27 | struct Symbol; |
28 | class SymbolTable; |
29 | |
30 | // The file has the structure: |
31 | // |
32 | // uint16 total string length |
33 | // string data |
34 | // symboltable |
35 | // elements |
36 | class Dehydrator { |
37 | public: |
38 | Dehydrator() { |
39 | fSymbolMap.emplace_back(); |
40 | } |
41 | |
42 | ~Dehydrator() { |
43 | SkASSERT(fSymbolMap.size() == 1); |
44 | } |
45 | |
46 | void write(const SymbolTable& symbols); |
47 | |
48 | void write(const std::vector<std::unique_ptr<ProgramElement>>& elements); |
49 | |
50 | void finish(OutputStream& out); |
51 | |
52 | private: |
53 | void writeS8(int32_t i) { |
54 | SkASSERT(i >= -128 && i <= 127); |
55 | fBody.write8(i); |
56 | } |
57 | |
58 | void writeU8(int32_t i) { |
59 | SkASSERT(i >= 0 && i <= 255); |
60 | fBody.write8(i); |
61 | } |
62 | |
63 | void writeS16(int32_t i) { |
64 | SkASSERT(i >= -32768 && i <= 32767); |
65 | fBody.write16(i); |
66 | } |
67 | |
68 | void writeU16(int32_t i) { |
69 | SkASSERT(i >= 0 && i <= 65535); |
70 | fBody.write16(i); |
71 | } |
72 | |
73 | void writeS32(int64_t i) { |
74 | SkASSERT(i >= -2147483648 && i <= 2147483647); |
75 | fBody.write32(i); |
76 | } |
77 | |
78 | void writeId(const Symbol* s) { |
79 | if (!symbolId(s, false)) { |
80 | fSymbolMap.back()[s] = fNextId++; |
81 | } |
82 | this->writeU16(symbolId(s)); |
83 | } |
84 | |
85 | uint16_t symbolId(const Symbol* s, bool required = true) { |
86 | for (const auto& symbols : fSymbolMap) { |
87 | auto found = symbols.find(s); |
88 | if (found != symbols.end()) { |
89 | return found->second; |
90 | } |
91 | } |
92 | SkASSERT(!required); |
93 | return 0; |
94 | } |
95 | |
96 | void write(Layout l); |
97 | |
98 | void write(Modifiers m); |
99 | |
100 | void write(StringFragment s); |
101 | |
102 | void write(String s); |
103 | |
104 | void write(const ProgramElement& e); |
105 | |
106 | void write(const Expression* e); |
107 | |
108 | void write(const Statement* s); |
109 | |
110 | void write(const Symbol& s); |
111 | |
112 | uint16_t fNextId = 1; |
113 | |
114 | StringStream fStringBuffer; |
115 | |
116 | StringStream fBody; |
117 | |
118 | std::unordered_map<String, int> fStrings; |
119 | |
120 | std::vector<std::unordered_map<const Symbol*, int>> fSymbolMap; |
121 | |
122 | friend class AutoDehydratorSymbolTable; |
123 | }; |
124 | |
125 | } // namespace |
126 | |
127 | #endif |
128 | |
129 | #endif |
130 | |