return true;
}
+ void Error()
+ {
+ st_ = kError;
+ }
protected:
explicit LookaheadParserHandler(char *str);
int GetInt();
double GetDouble();
const char * GetString();
+ std::string GetStringObject();
bool GetBool();
void GetNull();
{
if (st_ != kEnteringObject) {
st_ = kError;
- RAPIDJSON_ASSERT(false);
return false;
}
{
if (st_ != kEnteringArray) {
st_ = kError;
- RAPIDJSON_ASSERT(false);
return false;
}
}
if (st_ != kExitingObject) {
- RAPIDJSON_ASSERT(false);
st_ = kError;
return nullptr;
}
}
if (st_ == kError || st_ == kHasKey) {
- RAPIDJSON_ASSERT(false);
st_ = kError;
return false;
}
{
if (st_ != kHasNumber || !v_.IsInt()) {
st_ = kError;
- RAPIDJSON_ASSERT(false);
return 0;
}
{
if (st_ != kHasNumber) {
st_ = kError;
- RAPIDJSON_ASSERT(false);
return 0.;
}
{
if (st_ != kHasBool) {
st_ = kError;
- RAPIDJSON_ASSERT(false);
return false;
}
{
if (st_ != kHasString) {
st_ = kError;
- RAPIDJSON_ASSERT(false);
return nullptr;
}
return result;
}
+std::string LottieParserImpl::GetStringObject()
+{
+ auto str = GetString();
+
+ if (str) {
+ return std::string(str);
+ }
+
+ return {};
+}
+
void LottieParserImpl::SkipOut(int depth)
{
do {
} else if (st_ == kExitingArray || st_ == kExitingObject) {
--depth;
} else if (st_ == kError) {
- RAPIDJSON_ASSERT(false);
return;
}
model::BlendMode LottieParserImpl::getBlendMode()
{
- RAPIDJSON_ASSERT(PeekType() == kNumberType);
auto mode = model::BlendMode::Normal;
switch (GetInt()) {
void LottieParserImpl::parseComposition()
{
- RAPIDJSON_ASSERT(PeekType() == kObjectType);
EnterObject();
std::shared_ptr<model::Composition> sharedComposition =
std::make_shared<model::Composition>();
compRef = comp;
while (const char *key = NextObjectKey()) {
if (0 == strcmp(key, "v")) {
- RAPIDJSON_ASSERT(PeekType() == kStringType);
- comp->mVersion = std::string(GetString());
+ comp->mVersion = GetStringObject();
} else if (0 == strcmp(key, "w")) {
- RAPIDJSON_ASSERT(PeekType() == kNumberType);
comp->mSize.setWidth(GetInt());
} else if (0 == strcmp(key, "h")) {
- RAPIDJSON_ASSERT(PeekType() == kNumberType);
comp->mSize.setHeight(GetInt());
} else if (0 == strcmp(key, "ip")) {
- RAPIDJSON_ASSERT(PeekType() == kNumberType);
comp->mStartFrame = GetDouble();
} else if (0 == strcmp(key, "op")) {
- RAPIDJSON_ASSERT(PeekType() == kNumberType);
comp->mEndFrame = GetDouble();
} else if (0 == strcmp(key, "fr")) {
- RAPIDJSON_ASSERT(PeekType() == kNumberType);
comp->mFrameRate = GetDouble();
} else if (0 == strcmp(key, "assets")) {
parseAssets(comp);
void LottieParserImpl::parseMarker()
{
- RAPIDJSON_ASSERT(PeekType() == kObjectType);
EnterObject();
std::string comment;
int timeframe{0};
int duration{0};
while (const char *key = NextObjectKey()) {
if (0 == strcmp(key, "cm")) {
- RAPIDJSON_ASSERT(PeekType() == kStringType);
- comment = std::string(GetString());
+ comment = GetStringObject();
} else if (0 == strcmp(key, "tm")) {
- RAPIDJSON_ASSERT(PeekType() == kNumberType);
timeframe = GetDouble();
} else if (0 == strcmp(key, "dr")) {
- RAPIDJSON_ASSERT(PeekType() == kNumberType);
duration = GetDouble();
} else {
void LottieParserImpl::parseMarkers()
{
- RAPIDJSON_ASSERT(PeekType() == kArrayType);
EnterArray();
while (NextArrayValue()) {
parseMarker();
void LottieParserImpl::parseAssets(model::Composition *composition)
{
- RAPIDJSON_ASSERT(PeekType() == kArrayType);
EnterArray();
while (NextArrayValue()) {
auto asset = parseAsset();
*/
model::Asset *LottieParserImpl::parseAsset()
{
- RAPIDJSON_ASSERT(PeekType() == kObjectType);
-
auto asset = allocator().make<model::Asset>();
std::string filename;
std::string relativePath;
EnterObject();
while (const char *key = NextObjectKey()) {
if (0 == strcmp(key, "w")) {
- RAPIDJSON_ASSERT(PeekType() == kNumberType);
asset->mWidth = GetInt();
} else if (0 == strcmp(key, "h")) {
- RAPIDJSON_ASSERT(PeekType() == kNumberType);
asset->mHeight = GetInt();
} else if (0 == strcmp(key, "p")) { /* image name */
asset->mAssetType = model::Asset::Type::Image;
- RAPIDJSON_ASSERT(PeekType() == kStringType);
- filename = std::string(GetString());
+ filename = GetStringObject();
} else if (0 == strcmp(key, "u")) { /* relative image path */
- RAPIDJSON_ASSERT(PeekType() == kStringType);
- relativePath = std::string(GetString());
+ relativePath = GetStringObject();
} else if (0 == strcmp(key, "e")) { /* relative image path */
embededResource = GetInt();
} else if (0 == strcmp(key, "id")) { /* reference id*/
if (PeekType() == kStringType) {
- asset->mRefId = std::string(GetString());
+ asset->mRefId = GetStringObject();
} else {
- RAPIDJSON_ASSERT(PeekType() == kNumberType);
asset->mRefId = toString(GetInt());
}
} else if (0 == strcmp(key, "layers")) {
asset->mAssetType = model::Asset::Type::Precomp;
- RAPIDJSON_ASSERT(PeekType() == kArrayType);
EnterArray();
bool staticFlag = true;
while (NextArrayValue()) {
comp->mRootLayer->mLayerType = model::Layer::Type::Precomp;
comp->mRootLayer->setName("__");
bool staticFlag = true;
- RAPIDJSON_ASSERT(PeekType() == kArrayType);
EnterArray();
while (NextArrayValue()) {
auto layer = parseLayer();
model::Color LottieParserImpl::toColor(const char *str)
{
+ if (!str) return {};
+
model::Color color;
auto len = strlen(str);
model::MatteType LottieParserImpl::getMatteType()
{
- RAPIDJSON_ASSERT(PeekType() == kNumberType);
switch (GetInt()) {
case 1:
return model::MatteType::Alpha;
model::Layer::Type LottieParserImpl::getLayerType()
{
- RAPIDJSON_ASSERT(PeekType() == kNumberType);
switch (GetInt()) {
case 0:
return model::Layer::Type::Precomp;
*/
model::Layer *LottieParserImpl::parseLayer()
{
- RAPIDJSON_ASSERT(PeekType() == kObjectType);
model::Layer *layer = allocator().make<model::Layer>();
curLayerRef = layer;
bool ddd = true;
if (0 == strcmp(key, "ty")) { /* Type of layer*/
layer->mLayerType = getLayerType();
} else if (0 == strcmp(key, "nm")) { /*Layer name*/
- RAPIDJSON_ASSERT(PeekType() == kStringType);
layer->setName(GetString());
} else if (0 == strcmp(key, "ind")) { /*Layer index in AE. Used for
parenting and expressions.*/
- RAPIDJSON_ASSERT(PeekType() == kNumberType);
layer->mId = GetInt();
} else if (0 == strcmp(key, "ddd")) { /*3d layer */
- RAPIDJSON_ASSERT(PeekType() == kNumberType);
ddd = GetInt();
} else if (0 ==
strcmp(key,
"parent")) { /*Layer Parent. Uses "ind" of parent.*/
- RAPIDJSON_ASSERT(PeekType() == kNumberType);
layer->mParentId = GetInt();
} else if (0 == strcmp(key, "refId")) { /*preComp Layer reference id*/
- RAPIDJSON_ASSERT(PeekType() == kStringType);
- layer->extra()->mPreCompRefId = std::string(GetString());
+ layer->extra()->mPreCompRefId = GetStringObject();
layer->mHasGradient = true;
mLayersToUpdate.push_back(layer);
} else if (0 == strcmp(key, "sr")) { // "Layer Time Stretching"
- RAPIDJSON_ASSERT(PeekType() == kNumberType);
layer->mTimeStreatch = GetDouble();
} else if (0 == strcmp(key, "tm")) { // time remapping
parseProperty(layer->extra()->mTimeRemap);
} else if (0 == strcmp(key, "ip")) {
- RAPIDJSON_ASSERT(PeekType() == kNumberType);
layer->mInFrame = std::lround(GetDouble());
} else if (0 == strcmp(key, "op")) {
- RAPIDJSON_ASSERT(PeekType() == kNumberType);
layer->mOutFrame = std::lround(GetDouble());
} else if (0 == strcmp(key, "st")) {
- RAPIDJSON_ASSERT(PeekType() == kNumberType);
layer->mStartFrame = GetDouble();
} else if (0 == strcmp(key, "bm")) {
layer->mBlendMode = getBlendMode();
} else if (0 == strcmp(key, "ks")) {
- RAPIDJSON_ASSERT(PeekType() == kObjectType);
EnterObject();
layer->mTransform = parseTransformObject(ddd);
} else if (0 == strcmp(key, "shapes")) {
void LottieParserImpl::parseMaskProperty(model::Layer *layer)
{
- RAPIDJSON_ASSERT(PeekType() == kArrayType);
EnterArray();
while (NextArrayValue()) {
layer->extra()->mMasks.push_back(parseMaskObject());
{
auto obj = allocator().make<model::Mask>();
- RAPIDJSON_ASSERT(PeekType() == kObjectType);
EnterObject();
while (const char *key = NextObjectKey()) {
if (0 == strcmp(key, "inv")) {
void LottieParserImpl::parseShapesAttr(model::Layer *layer)
{
- RAPIDJSON_ASSERT(PeekType() == kArrayType);
EnterArray();
while (NextArrayValue()) {
parseObject(layer);
model::Object *LottieParserImpl::parseObjectTypeAttr()
{
- RAPIDJSON_ASSERT(PeekType() == kStringType);
const char *type = GetString();
if (0 == strcmp(type, "gr")) {
return parseGroupObject();
void LottieParserImpl::parseObject(model::Group *parent)
{
- RAPIDJSON_ASSERT(PeekType() == kObjectType);
EnterObject();
while (const char *key = NextObjectKey()) {
if (0 == strcmp(key, "ty")) {
if (0 == strcmp(key, "nm")) {
group->setName(GetString());
} else if (0 == strcmp(key, "it")) {
- RAPIDJSON_ASSERT(PeekType() == kArrayType);
EnterArray();
while (NextArrayValue()) {
- RAPIDJSON_ASSERT(PeekType() == kObjectType);
parseObject(group);
}
if (group->mChildren.back()->type() ==
model::Trim::TrimType LottieParserImpl::getTrimType()
{
- RAPIDJSON_ASSERT(PeekType() == kNumberType);
switch (GetInt()) {
case 1:
return model::Trim::TrimType::Simultaneously;
return model::Trim::TrimType::Individually;
break;
default:
- RAPIDJSON_ASSERT(0);
+ Error();
return model::Trim::TrimType::Simultaneously;
break;
}
*/
CapStyle LottieParserImpl::getLineCap()
{
- RAPIDJSON_ASSERT(PeekType() == kNumberType);
switch (GetInt()) {
case 1:
return CapStyle::Flat;
FillRule LottieParserImpl::getFillRule()
{
- RAPIDJSON_ASSERT(PeekType() == kNumberType);
switch (GetInt()) {
case 1:
return FillRule::Winding;
*/
JoinStyle LottieParserImpl::getLineJoin()
{
- RAPIDJSON_ASSERT(PeekType() == kNumberType);
switch (GetInt()) {
case 1:
return JoinStyle::Miter;
} else if (0 == strcmp(key, "lj")) {
obj->mJoinStyle = getLineJoin();
} else if (0 == strcmp(key, "ml")) {
- RAPIDJSON_ASSERT(PeekType() == kNumberType);
obj->mMiterLimit = GetDouble();
} else if (0 == strcmp(key, "d")) {
parseDashProperty(obj->mDash);
const char * key)
{
if (0 == strcmp(key, "t")) {
- RAPIDJSON_ASSERT(PeekType() == kNumberType);
obj->mGradientType = GetInt();
} else if (0 == strcmp(key, "o")) {
parseProperty(obj->mOpacity);
void LottieParserImpl::parseDashProperty(model::Dash &dash)
{
- RAPIDJSON_ASSERT(PeekType() == kArrayType);
EnterArray();
while (NextArrayValue()) {
- RAPIDJSON_ASSERT(PeekType() == kObjectType);
EnterObject();
while (const char *key = NextObjectKey()) {
if (0 == strcmp(key, "v")) {
} else if (0 == strcmp(key, "lj")) {
obj->mJoinStyle = getLineJoin();
} else if (0 == strcmp(key, "ml")) {
- RAPIDJSON_ASSERT(PeekType() == kNumberType);
obj->mMiterLimit = GetDouble();
} else if (0 == strcmp(key, "d")) {
parseDashProperty(obj->mDash);
void LottieParserImpl::getValue(std::vector<VPointF> &v)
{
- RAPIDJSON_ASSERT(PeekType() == kArrayType);
EnterArray();
while (NextArrayValue()) {
- RAPIDJSON_ASSERT(PeekType() == kArrayType);
EnterArray();
VPointF pt;
getValue(pt);
} else if (PeekType() == kNumberType) {
val = GetDouble();
} else {
- RAPIDJSON_ASSERT(0);
+ Error();
}
}
} else if (PeekType() == kNumberType) {
val = GetInt();
} else {
- RAPIDJSON_ASSERT(0);
+ Error();
}
}
bool arrayWrapper = (PeekType() == kArrayType);
if (arrayWrapper) EnterArray();
- RAPIDJSON_ASSERT(PeekType() == kObjectType);
EnterObject();
while (const char *key = NextObjectKey()) {
if (0 == strcmp(key, "i")) {
} else if (0 == strcmp(key, "c")) {
mPathInfo.mClosed = GetBool();
} else {
- RAPIDJSON_ASSERT(0);
+ Error();
Skip(nullptr);
}
}
VPointF LottieParserImpl::parseInperpolatorPoint()
{
VPointF cp;
- RAPIDJSON_ASSERT(PeekType() == kObjectType);
EnterObject();
while (const char *key = NextObjectKey()) {
if (0 == strcmp(key, "x")) {
continue;
} else if (0 == strcmp(key, "n")) {
if (PeekType() == kStringType) {
- parsed.interpolatorKey = GetString();
+ parsed.interpolatorKey = GetStringObject();
} else {
- RAPIDJSON_ASSERT(PeekType() == kArrayType);
EnterArray();
while (NextArrayValue()) {
- RAPIDJSON_ASSERT(PeekType() == kStringType);
if (parsed.interpolatorKey.empty()) {
- parsed.interpolatorKey = GetString();
+ parsed.interpolatorKey = GetStringObject();
} else {
// skip rest of the string
- GetString();
+ Skip(nullptr);
}
}
}
if (PeekType() == kArrayType) {
EnterArray();
while (NextArrayValue()) {
- RAPIDJSON_ASSERT(PeekType() == kObjectType);
parseKeyFrame(obj.animation());
}
} else {
if (!obj.isStatic()) {
- RAPIDJSON_ASSERT(false);
st_ = kError;
return;
}
{
if (PeekType() == kNumberType) {
if (!obj.isStatic()) {
- RAPIDJSON_ASSERT(false);
st_ = kError;
return;
}
/*single value property with no animation*/
getValue(obj.value());
} else {
- RAPIDJSON_ASSERT(PeekType() == kArrayType);
EnterArray();
while (NextArrayValue()) {
/* property with keyframe info*/
* or array of object without entering the array
* thats why this hack is there
*/
- RAPIDJSON_ASSERT(PeekType() == kNumberType);
if (!obj.isStatic()) {
- RAPIDJSON_ASSERT(false);
st_ = kError;
return;
}