tvg format: code refactoring #3

use the Array function instead of own implementation.
This commit is contained in:
Hermet Park 2021-07-20 13:31:25 +09:00
parent 8059a23f7c
commit 2eb920beaf
2 changed files with 44 additions and 96 deletions

View file

@ -53,6 +53,16 @@ struct Array
return true; return true;
} }
bool grow(uint32_t size)
{
return reserve(count + size);
}
T* ptr()
{
return data + count;
}
void pop() void pop()
{ {
if (count > 0) --count; if (count > 0) --count;

View file

@ -32,10 +32,7 @@ struct Saver::Impl
{ {
Saver* saver; Saver* saver;
Paint* paint = nullptr; //TODO: replace with Array Paint* paint = nullptr; //TODO: replace with Array
char* buffer = nullptr; Array<char> buffer;
char* pointer = nullptr;
uint32_t size = 0;
uint32_t reserved = 0;
Impl(Saver* s) : saver(s) Impl(Saver* s) : saver(s)
{ {
@ -50,48 +47,17 @@ struct Saver::Impl
{ {
if (paint) delete(paint); if (paint) delete(paint);
clearBuffer(); buffer.reset();
return true; return true;
} }
void resizeBuffer(uint32_t newSize)
{
//OPTIMIZE ME: find more optimal alg ? "*2" is not opt when raw/png is used
reserved += 100;
if (newSize > reserved) reserved = newSize + 100;
auto bufferOld = buffer;
buffer = static_cast<char*>(realloc(buffer, reserved));
if (buffer != bufferOld)
pointer = buffer + (pointer - bufferOld);
}
void rewindBuffer(ByteCounter bytesNum)
{
if (pointer - bytesNum < buffer) return;
pointer -= bytesNum;
size -= bytesNum;
}
void clearBuffer()
{
if (buffer) free(buffer);
buffer = nullptr;
pointer = nullptr;
size = 0;
reserved = 0;
}
bool saveBufferToFile(const std::string& path) bool saveBufferToFile(const std::string& path)
{ {
ofstream outFile; ofstream outFile;
outFile.open(path, ios::out | ios::trunc | ios::binary); outFile.open(path, ios::out | ios::trunc | ios::binary);
if (!outFile.is_open()) return false; if (!outFile.is_open()) return false;
outFile.write(buffer, size); outFile.write(buffer.data, buffer.count);
outFile.close(); outFile.close();
return true; return true;
@ -99,84 +65,73 @@ struct Saver::Impl
bool writeHeader() bool writeHeader()
{ {
reserved = TVG_BIN_HEADER_SIGNATURE_LENGTH + TVG_BIN_HEADER_VERSION_LENGTH; buffer.grow(TVG_BIN_HEADER_SIGNATURE_LENGTH + TVG_BIN_HEADER_VERSION_LENGTH);
buffer = static_cast<char*>(malloc(reserved)); auto ptr = buffer.ptr();
if (!buffer) return false; memcpy(ptr, TVG_BIN_HEADER_SIGNATURE, TVG_BIN_HEADER_SIGNATURE_LENGTH);
ptr += TVG_BIN_HEADER_SIGNATURE_LENGTH;
memcpy(ptr, TVG_BIN_HEADER_VERSION, TVG_BIN_HEADER_VERSION_LENGTH);
ptr += TVG_BIN_HEADER_VERSION_LENGTH;
pointer = buffer; buffer.count += (TVG_BIN_HEADER_SIGNATURE_LENGTH + TVG_BIN_HEADER_VERSION_LENGTH);
memcpy(pointer, TVG_BIN_HEADER_SIGNATURE, TVG_BIN_HEADER_SIGNATURE_LENGTH);
pointer += TVG_BIN_HEADER_SIGNATURE_LENGTH;
memcpy(pointer, TVG_BIN_HEADER_VERSION, TVG_BIN_HEADER_VERSION_LENGTH);
pointer += TVG_BIN_HEADER_VERSION_LENGTH;
size += (TVG_BIN_HEADER_SIGNATURE_LENGTH + TVG_BIN_HEADER_VERSION_LENGTH);
return true; return true;
} }
void writeMemberIndicator(TvgIndicator ind) void writeMemberIndicator(TvgIndicator ind)
{ {
if (size + TVG_INDICATOR_SIZE > reserved) resizeBuffer(size + TVG_INDICATOR_SIZE); buffer.grow(TVG_INDICATOR_SIZE);
memcpy(buffer.ptr(), &ind, TVG_INDICATOR_SIZE);
memcpy(pointer, &ind, TVG_INDICATOR_SIZE); buffer.count += TVG_INDICATOR_SIZE;
pointer += TVG_INDICATOR_SIZE;
size += TVG_INDICATOR_SIZE;
} }
void writeMemberDataSize(ByteCounter byteCnt) void writeMemberDataSize(ByteCounter byteCnt)
{ {
if (size + BYTE_COUNTER_SIZE > reserved) resizeBuffer(size + BYTE_COUNTER_SIZE); buffer.grow(BYTE_COUNTER_SIZE);
memcpy(buffer.ptr(), &byteCnt, BYTE_COUNTER_SIZE);
memcpy(pointer, &byteCnt, BYTE_COUNTER_SIZE); buffer.count += BYTE_COUNTER_SIZE;
pointer += BYTE_COUNTER_SIZE;
size += BYTE_COUNTER_SIZE;
} }
void writeMemberDataSizeAt(ByteCounter byteCnt) void writeMemberDataSizeAt(ByteCounter byteCnt)
{ {
memcpy(pointer - byteCnt - BYTE_COUNTER_SIZE, &byteCnt, BYTE_COUNTER_SIZE); memcpy(buffer.ptr() - byteCnt - BYTE_COUNTER_SIZE, &byteCnt, BYTE_COUNTER_SIZE);
} }
void skipInBufferMemberDataSize() void skipInBufferMemberDataSize()
{ {
if (size + BYTE_COUNTER_SIZE > reserved) resizeBuffer(size + BYTE_COUNTER_SIZE); buffer.grow(BYTE_COUNTER_SIZE);
pointer += BYTE_COUNTER_SIZE; buffer.count += BYTE_COUNTER_SIZE;
size += BYTE_COUNTER_SIZE;
} }
ByteCounter writeMemberData(const void* data, ByteCounter byteCnt) ByteCounter writeMemberData(const void* data, ByteCounter byteCnt)
{ {
if (size + byteCnt > reserved) resizeBuffer(size + byteCnt); buffer.grow(byteCnt);
memcpy(buffer.ptr(), data, byteCnt);
memcpy(pointer, data, byteCnt); buffer.count += byteCnt;
pointer += byteCnt;
size += byteCnt;
return byteCnt; return byteCnt;
} }
ByteCounter writeMember(TvgIndicator ind, ByteCounter byteCnt, const void* data) ByteCounter writeMember(TvgIndicator ind, ByteCounter byteCnt, const void* data)
{ {
ByteCounter blockByteCnt = TVG_INDICATOR_SIZE + BYTE_COUNTER_SIZE + byteCnt; ByteCounter blockByteCnt = TVG_INDICATOR_SIZE + BYTE_COUNTER_SIZE + byteCnt;
if (size + blockByteCnt > reserved) resizeBuffer(size + blockByteCnt); buffer.grow(blockByteCnt);
memcpy(pointer, &ind, TVG_INDICATOR_SIZE); auto ptr = buffer.ptr();
pointer += TVG_INDICATOR_SIZE;
memcpy(pointer, &byteCnt, BYTE_COUNTER_SIZE);
pointer += BYTE_COUNTER_SIZE;
memcpy(pointer, data, byteCnt);
pointer += byteCnt;
size += blockByteCnt; memcpy(ptr, &ind, TVG_INDICATOR_SIZE);
ptr += TVG_INDICATOR_SIZE;
memcpy(ptr, &byteCnt, BYTE_COUNTER_SIZE);
ptr += BYTE_COUNTER_SIZE;
memcpy(ptr, data, byteCnt);
ptr += byteCnt;
buffer.count += blockByteCnt;
return blockByteCnt; return blockByteCnt;
} }
ByteCounter serializePaint(const Paint* paint) ByteCounter serializePaint(const Paint* paint)
{ {
ByteCounter paintDataByteCnt = 0; ByteCounter paintDataByteCnt = 0;
@ -202,7 +157,6 @@ struct Saver::Impl
return paintDataByteCnt; return paintDataByteCnt;
} }
ByteCounter serializeScene(const Paint* paint) ByteCounter serializeScene(const Paint* paint)
{ {
auto scene = static_cast<const Scene*>(paint); auto scene = static_cast<const Scene*>(paint);
@ -221,7 +175,6 @@ struct Saver::Impl
return TVG_INDICATOR_SIZE + BYTE_COUNTER_SIZE + sceneDataByteCnt; return TVG_INDICATOR_SIZE + BYTE_COUNTER_SIZE + sceneDataByteCnt;
} }
ByteCounter serializeShapeFill(const Fill* f, TvgIndicator fillTvgFlag) ByteCounter serializeShapeFill(const Fill* f, TvgIndicator fillTvgFlag)
{ {
ByteCounter fillDataByteCnt = 0; ByteCounter fillDataByteCnt = 0;
@ -235,25 +188,18 @@ struct Saver::Impl
if (f->id() == TVG_CLASS_ID_RADIAL) { if (f->id() == TVG_CLASS_ID_RADIAL) {
float argRadial[3]; float argRadial[3];
auto radGrad = static_cast<const RadialGradient*>(f); auto radGrad = static_cast<const RadialGradient*>(f);
if (radGrad->radial(argRadial, argRadial + 1,argRadial + 2) != Result::Success) { radGrad->radial(argRadial, argRadial + 1,argRadial + 2);
rewindBuffer(TVG_FLAG_SIZE + BYTE_COUNTER_SIZE);
return 0;
}
fillDataByteCnt += writeMember(TVG_FILL_RADIAL_GRADIENT_INDICATOR, sizeof(argRadial), argRadial); fillDataByteCnt += writeMember(TVG_FILL_RADIAL_GRADIENT_INDICATOR, sizeof(argRadial), argRadial);
} }
else { else {
float argLinear[4]; float argLinear[4];
auto linGrad = static_cast<const LinearGradient*>(f); auto linGrad = static_cast<const LinearGradient*>(f);
if (linGrad->linear(argLinear, argLinear + 1, argLinear + 2, argLinear + 3) != Result::Success) { linGrad->linear(argLinear, argLinear + 1, argLinear + 2, argLinear + 3);
rewindBuffer(TVG_FLAG_SIZE + BYTE_COUNTER_SIZE);
return 0;
}
fillDataByteCnt += writeMember(TVG_FILL_LINEAR_GRADIENT_INDICATOR, sizeof(argLinear), argLinear); fillDataByteCnt += writeMember(TVG_FILL_LINEAR_GRADIENT_INDICATOR, sizeof(argLinear), argLinear);
} }
auto flag = static_cast<TvgFlag>(f->spread()); auto flag = static_cast<TvgFlag>(f->spread());
fillDataByteCnt += writeMember(TVG_FILL_FILLSPREAD_INDICATOR, TVG_FLAG_SIZE, &flag); fillDataByteCnt += writeMember(TVG_FILL_FILLSPREAD_INDICATOR, TVG_FLAG_SIZE, &flag);
fillDataByteCnt += writeMember(TVG_FILL_COLORSTOPS_INDICATOR, stopsCnt * sizeof(stops), stops); fillDataByteCnt += writeMember(TVG_FILL_COLORSTOPS_INDICATOR, stopsCnt * sizeof(stops), stops);
writeMemberDataSizeAt(fillDataByteCnt); writeMemberDataSizeAt(fillDataByteCnt);
@ -261,7 +207,6 @@ struct Saver::Impl
return TVG_INDICATOR_SIZE + BYTE_COUNTER_SIZE + fillDataByteCnt; return TVG_INDICATOR_SIZE + BYTE_COUNTER_SIZE + fillDataByteCnt;
} }
ByteCounter serializeShapeStroke(const Shape* shape) ByteCounter serializeShapeStroke(const Shape* shape)
{ {
ByteCounter strokeDataByteCnt = 0; ByteCounter strokeDataByteCnt = 0;
@ -305,7 +250,6 @@ struct Saver::Impl
return TVG_INDICATOR_SIZE + BYTE_COUNTER_SIZE + strokeDataByteCnt; return TVG_INDICATOR_SIZE + BYTE_COUNTER_SIZE + strokeDataByteCnt;
} }
ByteCounter serializeShapePath(const Shape* shape) ByteCounter serializeShapePath(const Shape* shape)
{ {
const PathCommand* cmds = nullptr; const PathCommand* cmds = nullptr;
@ -330,7 +274,6 @@ struct Saver::Impl
return TVG_INDICATOR_SIZE + BYTE_COUNTER_SIZE + pathDataByteCnt; return TVG_INDICATOR_SIZE + BYTE_COUNTER_SIZE + pathDataByteCnt;
} }
ByteCounter serializeShape(const Paint* paint) ByteCounter serializeShape(const Paint* paint)
{ {
auto shape = static_cast<const Shape*>(paint); auto shape = static_cast<const Shape*>(paint);
@ -366,7 +309,6 @@ struct Saver::Impl
return TVG_INDICATOR_SIZE + BYTE_COUNTER_SIZE + shapeDataByteCnt; return TVG_INDICATOR_SIZE + BYTE_COUNTER_SIZE + shapeDataByteCnt;
} }
ByteCounter serializePicture(const Paint* paint) ByteCounter serializePicture(const Paint* paint)
{ {
auto picture = static_cast<const Picture*>(paint); auto picture = static_cast<const Picture*>(paint);
@ -405,7 +347,6 @@ struct Saver::Impl
return TVG_INDICATOR_SIZE + BYTE_COUNTER_SIZE + pictureDataByteCnt; return TVG_INDICATOR_SIZE + BYTE_COUNTER_SIZE + pictureDataByteCnt;
} }
ByteCounter serializeComposite(const Paint* cmpTarget, CompositeMethod cmpMethod) ByteCounter serializeComposite(const Paint* cmpTarget, CompositeMethod cmpMethod)
{ {
ByteCounter cmpDataByteCnt = 0; ByteCounter cmpDataByteCnt = 0;
@ -423,7 +364,6 @@ struct Saver::Impl
return TVG_INDICATOR_SIZE + BYTE_COUNTER_SIZE + cmpDataByteCnt; return TVG_INDICATOR_SIZE + BYTE_COUNTER_SIZE + cmpDataByteCnt;
} }
ByteCounter serializeChildren(const Paint* paint) ByteCounter serializeChildren(const Paint* paint)
{ {
if (!paint) return 0; if (!paint) return 0;
@ -436,7 +376,6 @@ struct Saver::Impl
return dataByteCnt; return dataByteCnt;
} }
ByteCounter serialize(const Paint* paint) ByteCounter serialize(const Paint* paint)
{ {
if (!paint) return 0; if (!paint) return 0;
@ -460,7 +399,6 @@ struct Saver::Impl
return dataByteCnt; return dataByteCnt;
} }
bool save(Paint* paint, const std::string& path) bool save(Paint* paint, const std::string& path)
{ {
//FIXME: use Array and remove sync() here //FIXME: use Array and remove sync() here