skia2/tools/debugger/JsonWriteBuffer.cpp
Ben Wagner f15f78c905 [debugger] Handle '\0' and such in json strings.
This allows mskps produced with Chromium to be displayed in the
debugger. Previously, the debugger would produce invalid json if any
string contained characters which needed to be escaped. The debugger
also treated all strings like NULL terminated strings, but json is
Unicode based and code point U+0000 is a perfectly good code point.

Change-Id: I28150bad666b02be9f1e4af4078a4ca1e65bf000
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/549098
Commit-Queue: Ben Wagner <bungeman@google.com>
Reviewed-by: Herb Derby <herb@google.com>
2022-06-11 17:49:01 +00:00

225 lines
6.1 KiB
C++

/*
* Copyright 2016 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "tools/debugger/JsonWriteBuffer.h"
#include "include/core/SkFlattenable.h"
#include "include/core/SkPoint.h"
#include "include/core/SkSamplingOptions.h"
#include "include/core/SkString.h"
#include "src/utils/SkJSONWriter.h"
#include "tools/debugger/DrawCommand.h"
class SkImage;
class SkMatrix;
class SkPaint;
class SkRegion;
class SkStream;
class SkTypeface;
struct SkIRect;
struct SkPoint3;
struct SkRect;
void JsonWriteBuffer::append(const char* type) {
SkString fullName = SkStringPrintf("%02d_%s", fCount++, type);
fWriter->appendName(fullName.c_str());
}
void JsonWriteBuffer::writePad32(const void* data, size_t size) {
this->append("rawBytes");
fWriter->beginArray();
const uint8_t* bytes = reinterpret_cast<const uint8_t*>(data);
for (size_t i = 0; i < size; ++i) {
SkString hexByte = SkStringPrintf("%02x", bytes[i]);
fWriter->appendString(hexByte);
}
fWriter->endArray();
}
void JsonWriteBuffer::writeByteArray(const void* data, size_t size) {
this->append("byteArray");
fWriter->beginArray();
const uint8_t* bytes = reinterpret_cast<const uint8_t*>(data);
for (size_t i = 0; i < size; ++i) {
SkString hexByte = SkStringPrintf("%02x", bytes[i]);
fWriter->appendString(hexByte);
}
fWriter->endArray();
}
void JsonWriteBuffer::writeBool(bool value) {
this->append("bool");
fWriter->appendBool(value);
}
void JsonWriteBuffer::writeScalar(SkScalar value) {
this->append("scalar");
fWriter->appendFloat(value);
}
void JsonWriteBuffer::writeScalarArray(const SkScalar* value, uint32_t count) {
this->append("scalarArray");
fWriter->beginArray();
for (uint32_t i = 0; i < count; ++i) {
fWriter->appendFloat(value[i]);
}
fWriter->endArray();
}
void JsonWriteBuffer::writeInt(int32_t value) {
this->append("int");
fWriter->appendS32(value);
}
void JsonWriteBuffer::writeIntArray(const int32_t* value, uint32_t count) {
this->append("intArray");
fWriter->beginArray();
for (uint32_t i = 0; i < count; ++i) {
fWriter->appendS32(value[i]);
}
fWriter->endArray();
}
void JsonWriteBuffer::writeUInt(uint32_t value) {
this->append("uint");
fWriter->appendU32(value);
}
void JsonWriteBuffer::writeString(const char* value) {
this->append("string");
fWriter->appendCString(value);
}
void JsonWriteBuffer::writeFlattenable(const SkFlattenable* flattenable) {
if (flattenable) {
this->append(flattenable->getTypeName());
fWriter->beginObject();
JsonWriteBuffer flattenableBuffer(fWriter, fUrlDataManager);
flattenable->flatten(flattenableBuffer);
fWriter->endObject();
} else {
this->append("flattenable");
fWriter->appendPointer(nullptr);
}
}
void JsonWriteBuffer::writeColor(SkColor color) {
this->append("color");
DrawCommand::MakeJsonColor(*fWriter, color);
}
void JsonWriteBuffer::writeColorArray(const SkColor* color, uint32_t count) {
this->append("colorArray");
fWriter->beginArray();
for (uint32_t i = 0; i < count; ++i) {
DrawCommand::MakeJsonColor(*fWriter, color[i]);
}
fWriter->endArray();
}
void JsonWriteBuffer::writeColor4f(const SkColor4f& color) {
this->append("color");
DrawCommand::MakeJsonColor4f(*fWriter, color);
}
void JsonWriteBuffer::writeColor4fArray(const SkColor4f* color, uint32_t count) {
this->append("colorArray");
fWriter->beginArray();
for (uint32_t i = 0; i < count; ++i) {
DrawCommand::MakeJsonColor4f(*fWriter, color[i]);
}
fWriter->endArray();
}
void JsonWriteBuffer::writePoint(const SkPoint& point) {
this->append("point");
DrawCommand::MakeJsonPoint(*fWriter, point);
}
void JsonWriteBuffer::writePoint3(const SkPoint3& point) {
this->append("point3");
DrawCommand::MakeJsonPoint3(*fWriter, point);
}
void JsonWriteBuffer::writePointArray(const SkPoint* point, uint32_t count) {
this->append("pointArray");
fWriter->beginArray();
for (uint32_t i = 0; i < count; ++i) {
DrawCommand::MakeJsonPoint(*fWriter, point[i]);
}
fWriter->endArray();
}
void JsonWriteBuffer::write(const SkM44& matrix) {
this->append("matrix");
fWriter->beginArray();
for (int r = 0; r < 4; ++r) {
fWriter->beginArray(nullptr, false);
SkV4 v = matrix.row(r);
for (int c = 0; c < 4; ++c) {
fWriter->appendFloat(v[c]);
}
fWriter->endArray();
}
fWriter->endArray();
}
void JsonWriteBuffer::writeMatrix(const SkMatrix& matrix) {
this->append("matrix");
DrawCommand::MakeJsonMatrix(*fWriter, matrix);
}
void JsonWriteBuffer::writeIRect(const SkIRect& rect) {
this->append("irect");
DrawCommand::MakeJsonIRect(*fWriter, rect);
}
void JsonWriteBuffer::writeRect(const SkRect& rect) {
this->append("rect");
DrawCommand::MakeJsonRect(*fWriter, rect);
}
void JsonWriteBuffer::writeRegion(const SkRegion& region) {
this->append("region");
DrawCommand::MakeJsonRegion(*fWriter, region);
}
void JsonWriteBuffer::writePath(const SkPath& path) {
this->append("path");
DrawCommand::MakeJsonPath(*fWriter, path);
}
void JsonWriteBuffer::writeSampling(const SkSamplingOptions& sampling) {
this->append("sampling");
DrawCommand::MakeJsonSampling(*fWriter, sampling);
}
size_t JsonWriteBuffer::writeStream(SkStream* stream, size_t length) {
// Contents not supported
this->append("stream");
fWriter->appendU64(static_cast<uint64_t>(length));
return 0;
}
void JsonWriteBuffer::writeImage(const SkImage* image) {
this->append("image");
fWriter->beginObject();
DrawCommand::flatten(*image, *fWriter, *fUrlDataManager);
fWriter->endObject();
}
void JsonWriteBuffer::writeTypeface(SkTypeface* typeface) {
// Unsupported
this->append("typeface");
fWriter->appendPointer(typeface);
}
void JsonWriteBuffer::writePaint(const SkPaint& paint) {
this->append("paint");
DrawCommand::MakeJsonPaint(*fWriter, paint, *fUrlDataManager);
}