blob: 247a7eece59e849b46ea1c668d98ba3d7e171214 [file] [log] [blame]
/*
* Copyright 2020 Google LLC
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SKSL_DEHYDRATOR
#define SKSL_DEHYDRATOR
#ifdef SKSL_STANDALONE
#include "include/private/SkSLModifiers.h"
#include "include/private/SkSLSymbol.h"
#include "include/private/SkTHash.h"
#include "src/core/SkSpan.h"
#include "src/sksl/SkSLOutputStream.h"
#include "src/sksl/SkSLStringStream.h"
#include <set>
#include <unordered_map>
#include <vector>
namespace SkSL {
class AnyConstructor;
class Expression;
class ProgramElement;
class Statement;
class Symbol;
class SymbolTable;
// The file has the structure:
//
// uint16 total string length
// string data
// symboltable
// elements
class Dehydrator {
public:
Dehydrator() {
fSymbolMap.emplace_back();
}
~Dehydrator() {
SkASSERT(fSymbolMap.size() == 1);
}
void write(const SymbolTable& symbols);
void write(const std::vector<std::unique_ptr<ProgramElement>>& elements);
void finish(OutputStream& out);
// Inserts line breaks at meaningful offsets.
const char* prefixAtOffset(size_t byte);
private:
void writeS8(int32_t i) {
SkASSERT(i >= -128 && i <= 127);
fBody.write8(i);
}
void writeCommand(int32_t c) {
fCommandBreaks.add(fBody.bytesWritten());
fBody.write8(c);
}
void writeU8(int32_t i) {
SkASSERT(i >= 0 && i <= 255);
fBody.write8(i);
}
void writeS16(int32_t i) {
SkASSERT(i >= -32768 && i <= 32767);
fBody.write16(i);
}
void writeU16(int32_t i) {
SkASSERT(i >= 0 && i <= 65535);
fBody.write16(i);
}
void writeS32(int64_t i) {
SkASSERT(i >= -2147483648 && i <= 2147483647);
fBody.write32(i);
}
void writeId(const Symbol* s) {
if (!symbolId(s, false)) {
fSymbolMap.back()[s] = fNextId++;
}
this->writeU16(symbolId(s));
}
uint16_t symbolId(const Symbol* s, bool required = true) {
for (const auto& symbols : fSymbolMap) {
auto found = symbols.find(s);
if (found != symbols.end()) {
return found->second;
}
}
SkASSERT(!required);
return 0;
}
void write(Layout l);
void write(Modifiers m);
void write(StringFragment s);
void write(String s);
void write(const ProgramElement& e);
void write(const Expression* e);
void write(const Statement* s);
void write(const Symbol& s);
void writeExpressionSpan(const SkSpan<const std::unique_ptr<Expression>>& span);
uint16_t fNextId = 1;
StringStream fStringBuffer;
StringStream fBody;
std::unordered_map<String, int> fStrings;
std::vector<std::unordered_map<const Symbol*, int>> fSymbolMap;
SkTHashSet<size_t> fStringBreaks;
SkTHashSet<size_t> fCommandBreaks;
size_t fStringBufferStart;
size_t fCommandStart;
friend class AutoDehydratorSymbolTable;
};
} // namespace
#endif
#endif