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
22namespace SkSL {
23
24struct Expression;
25struct ProgramElement;
26struct Statement;
27struct Symbol;
28class SymbolTable;
29
30// The file has the structure:
31//
32// uint16 total string length
33// string data
34// symboltable
35// elements
36class Dehydrator {
37public:
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
52private:
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