src/SSBParser.cpp
// Parse geometry and adds to SSB event object
Parse geometry and adds to SSB event object
Parse geometry and adds to SSB event object
void parse_geometry(std::string& geometry, SSBGeometry::Type geometry_type, SSBEvent& ssb_event, unsigned long int line_i, bool warnings) throw(std::string){
		switch(geometry_type){
            case SSBGeometry::Type::POINTS:
                {
                    std::vector<Point> points;
                    std::istringstream points_stream(geometry);
                    Point point;
                    while(points_stream >> point.x)
                        if(points_stream >> point.y)
                            points.push_back(point);
                        else if(warnings)
                            throw_parse_error(line_i, "Points must have 2 numbers");
                    if((points_stream >> std::ws).eof())
                        ssb_event.objects.push_back(std::shared_ptr<SSBObject>(new SSBPoints(points)));
                    else if(warnings)
                        throw_parse_error(line_i, "Points are invalid");
                }
                break;
            case SSBGeometry::Type::PATH:
                {
                    std::vector<SSBPath::Segment> path;
                    std::istringstream path_stream(geometry);
                    std::string path_token;
                    SSBPath::Segment segments[3];
                    segments[0].type = SSBPath::SegmentType::MOVE_TO;
                    while(path_stream >> path_token)
                        if(path_token == "m")
                            segments[0].type = SSBPath::SegmentType::MOVE_TO;
                        else if(path_token == "l")
                            segments[0].type = SSBPath::SegmentType::LINE_TO;
                        else if(path_token == "b")
                            segments[0].type = segments[1].type = segments[2].type = SSBPath::SegmentType::CURVE_TO;
                        else if(path_token == "a")
                            segments[0].type = segments[1].type = SSBPath::SegmentType::ARC_TO;
                        else if(path_token == "c"){
                            segments[0].type = SSBPath::SegmentType::CLOSE;
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
                            path.push_back({SSBPath::SegmentType::CLOSE});
#pragma GCC diagnostic pop
                        }
                        else{
                            path_stream.seekg(-static_cast<long int>(path_token.length()), std::istringstream::cur);
                            switch(segments[0].type){
                                case SSBPath::SegmentType::MOVE_TO:
                                case SSBPath::SegmentType::LINE_TO:
                                    if(path_stream >> segments[0].point.x &&
                                            path_stream >> segments[0].point.y)
                                        path.push_back(segments[0]);
                                    else if(warnings)
                                        throw_parse_error(line_i, segments[0].type == SSBPath::SegmentType::MOVE_TO ? "Path (move) is invalid" : "Path (line) is invalid");
                                    break;
                                case SSBPath::SegmentType::CURVE_TO:
                                    if(path_stream >> segments[0].point.x &&
                                            path_stream >> segments[0].point.y &&
                                            path_stream >> segments[1].point.x &&
                                            path_stream >> segments[1].point.y &&
                                            path_stream >> segments[2].point.x &&
                                            path_stream >> segments[2].point.y){
                                        path.push_back(segments[0]);
                                        path.push_back(segments[1]);
                                        path.push_back(segments[2]);
                                    }else if(warnings)
                                        throw_parse_error(line_i, "Path (curve) is invalid");
                                    break;
                                case SSBPath::SegmentType::ARC_TO:
                                    if(path_stream >> segments[0].point.x &&
                                            path_stream >> segments[0].point.y &&
                                            path_stream >> segments[1].angle){
                                        path.push_back(segments[0]);
                                        path.push_back(segments[1]);
                                    }else if(warnings)
                                        throw_parse_error(line_i, "Path (arc) is invalid");
                                    break;
                                case SSBPath::SegmentType::CLOSE:
                                    if(warnings)
                                        throw_parse_error(line_i, "Path (close) is invalid");
                                    break;
                            }
                        }
                    ssb_event.objects.push_back(std::shared_ptr<SSBObject>(new SSBPath(path)));
                }
                break;
            case SSBGeometry::Type::TEXT:
                {
                    string_replace(geometry, "\t", "    ");
                    string_replace(geometry, "\\n", "\n");
                    string_replace(geometry, "\\{", "{");
                    ssb_event.objects.push_back(std::shared_ptr<SSBObject>(new SSBText(geometry)));
                }
                break;
		}
    }
void parse_geometry ( std :: string & geometry , SSBGeometry :: Type geometry_type , SSBEvent & ssb_event , unsigned long int line_i , bool warnings ) throw ( std :: string ) { switch ( geometry_type ) { case SSBGeometry :: Type :: POINTS : { std :: vector < Point > points ; std :: istringstream points_stream ( geometry ) ; Point point ; while ( points_stream >> point . x ) if ( points_stream >> point . y ) points . push_back ( point ) ; else if ( warnings ) throw_parse_error ( line_i , " " ) ; if ( ( points_stream >> std :: ws ) . eof ( ) ) ssb_event . objects . push_back ( std :: shared_ptr < SSBObject > ( new SSBPoints ( points ) ) ) ; else if ( warnings ) throw_parse_error ( line_i , " " ) ; } break ; case SSBGeometry :: Type :: PATH : { std :: vector < SSBPath :: Segment > path ; std :: istringstream path_stream ( geometry ) ; std :: string path_token ; SSBPath :: Segment segments [ 3 ] ; segments [ 0 ] . type = SSBPath :: SegmentType :: MOVE_TO ; while ( path_stream >> path_token ) if ( path_token == " " ) segments [ 0 ] . type = SSBPath :: SegmentType :: MOVE_TO ; else if ( path_token == " " ) segments [ 0 ] . type = SSBPath :: SegmentType :: LINE_TO ; else if ( path_token == " " ) segments [ 0 ] . type = segments [ 1 ] . type = segments [ 2 ] . type = SSBPath :: SegmentType :: CURVE_TO ; else if ( path_token == " " ) segments [ 0 ] . type = segments [ 1 ] . type = SSBPath :: SegmentType :: ARC_TO ; else if ( path_token == " " ) { segments [ 0 ] . type = SSBPath :: SegmentType :: CLOSE ; #pragma  GCC diagnostic push #pragma  GCC diagnostic ignored "-Wmissing-field-initializers" path . push_back ( { SSBPath :: SegmentType :: CLOSE } ) ; #pragma  GCC diagnostic pop } else { path_stream . seekg ( - static_cast < long int > ( path_token . length ( ) ) , std :: istringstream :: cur ) ; switch ( segments [ 0 ] . type ) { case SSBPath :: SegmentType :: MOVE_TO : case SSBPath :: SegmentType :: LINE_TO : if ( path_stream >> segments [ 0 ] . point . x && path_stream >> segments [ 0 ] . point . y ) path . push_back ( segments [ 0 ] ) ; else if ( warnings ) throw_parse_error ( line_i , segments [ 0 ] . type == SSBPath :: SegmentType :: MOVE_TO ? " " : " " ) ; break ; case SSBPath :: SegmentType :: CURVE_TO : if ( path_stream >> segments [ 0 ] . point . x && path_stream >> segments [ 0 ] . point . y && path_stream >> segments [ 1 ] . point . x && path_stream >> segments [ 1 ] . point . y && path_stream >> segments [ 2 ] . point . x && path_stream >> segments [ 2 ] . point . y ) { path . push_back ( segments [ 0 ] ) ; path . push_back ( segments [ 1 ] ) ; path . push_back ( segments [ 2 ] ) ; } else if ( warnings ) throw_parse_error ( line_i , " " ) ; break ; case SSBPath :: SegmentType :: ARC_TO : if ( path_stream >> segments [ 0 ] . point . x && path_stream >> segments [ 0 ] . point . y && path_stream >> segments [ 1 ] . angle ) { path . push_back ( segments [ 0 ] ) ; path . push_back ( segments [ 1 ] ) ; } else if ( warnings ) throw_parse_error ( line_i , " " ) ; break ; case SSBPath :: SegmentType :: CLOSE : if ( warnings ) throw_parse_error ( line_i , " " ) ; break ; } } ssb_event . objects . push_back ( std :: shared_ptr < SSBObject > ( new SSBPath ( path ) ) ) ; } break ; case SSBGeometry :: Type :: TEXT : { string_replace ( geometry , " \t " , " " ) ; string_replace ( geometry , " \\ " , " \n " ) ; string_replace ( geometry , " \\ " , " " ) ; ssb_event . objects . push_back ( std :: shared_ptr < SSBObject > ( new SSBText ( geometry ) ) ) ; } break ; } }
Parse geometry and adds to SSB event object
Parse geometry and adds to SSB event object
// Points buffer // Iterate through numbers // Check for successfull streaming end // Path buffer // Iterate through words // Set segment type // Get complete segment // Put token back in stream for rereading // Parse segment // Segments collection successfull without exception -> insert SSBPath as SSBObject to SSBEvent // Replace in string \t to 4 spaces // Replace in string \n to real line breaks // Replace in string \{ to single { // Insert SSBText as SSBObject to SSBEvent