static bool ParseLocation(const TCHAR *&src, GeoPoint &p) { // A 41.234234N 7.234424W // Ignore but require 'A' placeholder if (*src != _T('A')) return false; src++; // Skip whitespace while (*src == _T(' ')) src++; Angle lat, lon; if (!ParseAngle(src, lat) || !ParseAngle(src, lon)) return false; p.longitude = lon; p.latitude = lat; // ensure longitude is within -180:180 p.Normalize(); return true; }
bool WaypointReaderOzi::ParseLine(const TCHAR *line, Waypoints &way_points) { if (line[0] == '\0') return true; // Ignore first four header lines if (ignore_lines > 0) { --ignore_lines; return true; } TCHAR ctemp[255]; const TCHAR *params[20]; static constexpr unsigned int max_params = ARRAY_SIZE(params); size_t n_params; if (_tcslen(line) >= ARRAY_SIZE(ctemp)) /* line too long for buffer */ return false; // Get fields n_params = ExtractParameters(line, ctemp, params, max_params, true, _T('"')); // Check if the basic fields are provided if (n_params < 15) return false; GeoPoint location; // Latitude (e.g. 5115.900N) if (!ParseAngle(params[2], location.latitude)) return false; // Longitude (e.g. 00715.900W) if (!ParseAngle(params[3], location.longitude)) return false; location.Normalize(); // ensure longitude is within -180:180 Waypoint new_waypoint = factory.Create(location); long value; new_waypoint.original_id = (ParseNumber(params[0], value) ? value : 0); if (!ParseString(params[1], new_waypoint.name)) return false; if (ParseNumber(params[14], value) && value != -777) new_waypoint.elevation = Units::ToSysUnit(value, Unit::FEET); else if (!factory.FallbackElevation(new_waypoint)) return false; // Description (Characters 35-44) ParseString(params[11], new_waypoint.comment); way_points.Append(std::move(new_waypoint)); return true; }
bool WaypointReaderZander::ParseLine(const TCHAR* line, const unsigned linenum, Waypoints &way_points) { // If (end-of-file or comment) if (line[0] == '\0' || line[0] == 0x1a || _tcsstr(line, _T("**")) == line || _tcsstr(line, _T("*")) == line) // -> return without error condition return true; // Determine the length of the line size_t len = _tcslen(line); // If less then 34 characters -> something is wrong -> cancel if (len < 34) return false; GeoPoint location; // Latitude (Characters 13-20 // DDMMSS(N/S)) if (!ParseAngle(line + 13, location.latitude, true)) return false; // Longitude (Characters 21-29 // DDDMMSS(E/W)) if (!ParseAngle(line + 21, location.longitude, false)) return false; location.Normalize(); // ensure longitude is within -180:180 Waypoint new_waypoint(location); new_waypoint.file_num = file_num; new_waypoint.original_id = 0; // Name (Characters 0-12) if (!ParseString(line, new_waypoint.name, 12)) return false; // Altitude (Characters 30-34 // e.g. 1561 (in meters)) /// @todo configurable behaviour if (!ParseAltitude(line + 30, new_waypoint.elevation) && !CheckAltitude(new_waypoint)) return false; // Description (Characters 35-44) if (len > 35) ParseString(line + 35, new_waypoint.comment, 9); // Flags (Characters 45-49) if (len < 46 || !ParseFlags(line + 45, new_waypoint)) if (len < 36 || !ParseFlagsFromDescription(line + 35, new_waypoint)) new_waypoint.flags.turn_point = true; way_points.Append(new_waypoint); return true; }
/** * Parses one ObsZone line from the See You task file * @param turnpoint_infos Updated with the OZ info * @param params Input array of parameters preparsed from See You task file * @param n_params Number parameters in the line * @return OZ index from CU (0 to n-1) or -1 if no OZ found */ static int ParseOZs(SeeYouTurnpointInformation turnpoint_infos[], const TCHAR *params[], unsigned n_params) { // Read OZ index TCHAR* end; const int oz_index = _tcstol(params[0] + 8, &end, 10); if (params[0] + 8 == end || oz_index >= 30) return -1; turnpoint_infos[oz_index].valid = true; // Iterate through available OZ options for (unsigned i = 1; i < n_params; i++) { const TCHAR *pair = params[i]; SeeYouTurnpointInformation &tp_info = turnpoint_infos[oz_index]; if (_tcsncmp(pair, _T("style"), 5) == 0) { if (_tcslen(pair) > 6) tp_info.style = ParseStyle(pair + 6); } else if (_tcsncmp(pair, _T("R1="), 3) == 0) { if (_tcslen(pair) > 3) tp_info.radius1 = ParseRadius(pair + 3); } else if (_tcsncmp(pair, _T("A1="), 3) == 0) { if (_tcslen(pair) > 3) tp_info.angle1 = ParseAngle(pair + 3); } else if (_tcsncmp(pair, _T("R2="), 3) == 0) { if (_tcslen(pair) > 3) tp_info.radius2 = ParseRadius(pair + 3); } else if (_tcsncmp(pair, _T("A2="), 3) == 0) { if (_tcslen(pair) > 3) tp_info.angle2 = ParseAngle(pair + 3); } else if (_tcsncmp(pair, _T("A12="), 4) == 0) { if (_tcslen(pair) > 3) tp_info.angle12 = ParseAngle(pair + 4); } else if (_tcsncmp(pair, _T("max_altitude="), 7) == 0) { if (_tcslen(pair) > 7) tp_info.max_altitude = ParseMaxAlt(pair + 7); } else if (_tcsncmp(pair, _T("is_line"), 4) == 0) { if (_tcslen(pair) > 5 && pair[5] == _T('1')) tp_info.is_line = true; } else if (_tcsncmp(pair, _T("reduce"), 6) == 0) { if (_tcslen(pair) > 7 && pair[7] == _T('1')) tp_info.reduce = true; } } return oz_index; }
static bool ParseLocation(const TCHAR *src, GeoPoint &p) { Angle lon, lat; if (!ParseAngle(src, lat)) return false; if (!ParseAngle(src + 17, lon)) return false; p.longitude = lon; p.latitude = lat; // ensure longitude is within -180:180 p.Normalize(); return true; }
int MIValue::Parse(String const &s, int i) { // if starts with '"', it's a string // if starts with '[', it's an array // if starts with '{', it's a tuple // otherwise, it can be a sequence of pair name="value" which is stored like a tuple // latter case is an example o bad design of MI interface.... Clear(); while(s[i] && isspace(s[i])) i++; if(s[i] == '"') return ParseString(s, i); else if(s[i] == '<') return ParseAngle(s, i); else if(s[i] == '[') return ParseArray(s, i); else if(s[i] == '{') return ParseTuple(s, i); else { String name; MIValue val; type = MITuple; while(s[i]) { i = ParsePair(name, val, s, i); tuple.AddPick(name, pick(val)); while(s[i] && isspace(s[i])) i++; if(s[i] != ',') break; i++; } return i; } }
bool WaypointReaderSeeYou::ParseLine(const TCHAR* line, Waypoints &waypoints) { enum { iName = 0, iLatitude = 3, iLongitude = 4, iElevation = 5, iStyle = 6, iRWDir = 7, iRWLen = 8, iFrequency = 9, iDescription = 10, }; if (first) { first = false; /* skip first line if it doesn't begin with a quotation character (usually the field order line) */ if (line[0] != _T('\"')) return true; } // If (end-of-file or comment) if (StringIsEmpty(line) || StringStartsWith(line, _T("*"))) // -> return without error condition return true; TCHAR ctemp[4096]; if (_tcslen(line) >= ARRAY_SIZE(ctemp)) /* line too long for buffer */ return false; // If task marker is reached ignore all following lines if (StringStartsWith(line, _T("-----Related Tasks-----"))) ignore_following = true; if (ignore_following) return true; // Get fields const TCHAR *params[20]; size_t n_params = ExtractParameters(line, ctemp, params, ARRAY_SIZE(params), true, _T('"')); // Check if the basic fields are provided if (iName >= n_params || iLatitude >= n_params || iLongitude >= n_params) return false; GeoPoint location; // Latitude (e.g. 5115.900N) if (!ParseAngle(params[iLatitude], location.latitude, true)) return false; // Longitude (e.g. 00715.900W) if (!ParseAngle(params[iLongitude], location.longitude, false)) return false; location.Normalize(); // ensure longitude is within -180:180 Waypoint new_waypoint = factory.Create(location); // Name (e.g. "Some Turnpoint") if (*params[iName] == _T('\0')) return false; new_waypoint.name = params[iName]; // Elevation (e.g. 458.0m) /// @todo configurable behaviour if ((iElevation >= n_params || !ParseAltitude(params[iElevation], new_waypoint.elevation)) && !factory.FallbackElevation(new_waypoint)) return false; // Style (e.g. 5) if (iStyle < n_params) ParseStyle(params[iStyle], new_waypoint.type); new_waypoint.flags.turn_point = true; // Frequency & runway direction/length (for airports and landables) // and description (e.g. "Some Description") if (new_waypoint.IsLandable()) { if (iFrequency < n_params) new_waypoint.radio_frequency = RadioFrequency::Parse(params[iFrequency]); // Runway length (e.g. 546.0m) double rwlen = -1; if (iRWLen < n_params && ParseDistance(params[iRWLen], rwlen) && rwlen > 0) new_waypoint.runway.SetLength(uround(rwlen)); if (iRWDir < n_params && *params[iRWDir]) { TCHAR *end; int direction =_tcstol(params[iRWDir], &end, 10); if (end == params[iRWDir] || direction < 0 || direction > 360 || (direction == 0 && rwlen <= 0)) direction = -1; else if (direction == 360) direction = 0; if (direction >= 0) new_waypoint.runway.SetDirectionDegrees(direction); } } if (iDescription < n_params) { /* * This convention was introduced by the OpenAIP * project (http://www.openaip.net/), since no waypoint type * exists for thermal hotspots. */ if (StringStartsWith(params[iDescription], _T("Hotspot"))) new_waypoint.type = Waypoint::Type::THERMAL_HOTSPOT; new_waypoint.comment = params[iDescription]; } waypoints.Append(std::move(new_waypoint)); return true; }
bool WaypointReaderWinPilot::ParseLine(const TCHAR *line, Waypoints &waypoints) { TCHAR ctemp[4096]; const TCHAR *params[20]; static constexpr unsigned int max_params = ARRAY_SIZE(params); size_t n_params; // If (end-of-file) if (line[0] == '\0') // -> return without error condition return true; // If comment if (line[0] == _T('*')) { if (first) { first = false; welt2000_format = (_tcsstr(line, _T("WRITTEN BY WELT2000")) != nullptr); } // -> return without error condition return true; } if (_tcslen(line) >= ARRAY_SIZE(ctemp)) /* line too long for buffer */ return false; GeoPoint location; // Get fields n_params = ExtractParameters(line, ctemp, params, max_params, true); if (n_params < 6) return false; // Latitude (e.g. 51:15.900N) if (!ParseAngle(params[1], location.latitude, true)) return false; // Longitude (e.g. 00715.900W) if (!ParseAngle(params[2], location.longitude, false)) return false; location.Normalize(); // ensure longitude is within -180:180 Waypoint new_waypoint = factory.Create(location); // Name (e.g. KAMPLI) if (*params[5] == _T('\0')) return false; new_waypoint.name=params[5]; // Altitude (e.g. 458M) /// @todo configurable behaviour if (!ParseAltitude(params[3], new_waypoint.elevation) && !factory.FallbackElevation(new_waypoint)) return false; if (n_params > 6) { // Description (e.g. 119.750 Airport) new_waypoint.comment=params[6]; if (welt2000_format) ParseRunwayDirection(params[6], new_waypoint.runway); } // Waypoint Flags (e.g. AT) ParseFlags(params[4], new_waypoint); waypoints.Append(std::move(new_waypoint)); return true; }
static bool ParseWayPointString(WAYPOINT *Temp, const TCHAR *input, RasterTerrain &terrain) { TCHAR *endptr; size_t length; Temp->FileNum = globalFileNum; Temp->Number = _tcstol(input, &endptr, 10); if (endptr == input || *endptr != _T(',')) return false; input = endptr + 1; if (!ParseAngle(input, &Temp->Location.Latitude, &endptr) || Temp->Location.Latitude > 90 || Temp->Location.Latitude < -90 || *endptr != _T(',')) return false; input = endptr + 1; ParseAngle(input, &Temp->Location.Longitude, &endptr); if (!ParseAngle(input, &Temp->Location.Longitude, &endptr) || Temp->Location.Longitude > 180 || Temp->Location.Longitude < -180 || *endptr != _T(',')) return false; input = endptr + 1; if (!ParseAltitude(input, &Temp->Altitude, &endptr) || *endptr != _T(',')) return false; input = endptr + 1; Temp->Flags = ParseFlags(input, &input); if (*input != _T(',')) return false; ++input; endptr = _tcschr(input, _T(',')); if (endptr != NULL) length = endptr - input; else length = _tcslen(input); if (length >= sizeof(Temp->Name)) length = sizeof(Temp->Name) - 1; while (length > 0 && input[length - 1] == 0) --length; memcpy(Temp->Name, input, length * sizeof(input[0])); Temp->Name[length] = 0; if (endptr != NULL) { input = endptr + 1; endptr = _tcschr(input, '*'); if (endptr != NULL) { length = endptr - input; // if it is a home waypoint raise zoom level Temp->Zoom = _tcstol(endptr + 2, NULL, 10); } else { length = _tcslen(input); Temp->Zoom = 0; } if (length >= sizeof(Temp->Comment)) length = sizeof(Temp->Comment) - 1; while (length > 0 && input[length - 1] == 0) --length; memcpy(Temp->Comment, input, length * sizeof(input[0])); Temp->Comment[length] = 0; } else { Temp->Comment[0] = 0; Temp->Zoom = 0; } if(Temp->Altitude <= 0) { WaypointAltitudeFromTerrain(Temp, terrain); } if (Temp->Details) { free(Temp->Details); } return true; }
// Parse a primitive, apply defaults first, grab any base level // key pairs, then process any sub groups we may contain. //------------------------------------------------------ bool CPrimitiveTemplate::ParsePrimitive( CGPGroup *grp ) { CGPGroup *subGrp; CGPValue *pairs; const char *key; const char *val; // Lets work with the pairs first pairs = grp->GetPairs(); while( pairs ) { // the fields key = pairs->GetName(); val = pairs->GetTopValue(); // Huge stricmp lists suxor if ( !stricmp( key, "count" )) { ParseCount( val ); } else if ( !stricmp( key, "shaders" ) || !stricmp( key, "shader" )) { ParseShaders( pairs ); } else if ( !stricmp( key, "models" ) || !stricmp( key, "model" )) { ParseModels( pairs ); } else if ( !stricmp( key, "sounds" ) || !stricmp( key, "sound" )) { ParseSounds( pairs ); } else if ( !stricmp( key, "impactfx" )) { ParseImpactFxStrings( pairs ); } else if ( !stricmp( key, "deathfx" )) { ParseDeathFxStrings( pairs ); } else if ( !stricmp( key, "emitfx" )) { ParseEmitterFxStrings( pairs ); } else if ( !stricmp( key, "playfx" )) { ParsePlayFxStrings( pairs ); } else if ( !stricmp( key, "life" )) { ParseLife( val ); } else if ( !stricmp( key, "cullrange" )) { mCullRange = atoi( val ); mCullRange *= mCullRange; // Square } else if ( !stricmp( key, "delay" )) { ParseDelay( val ); } else if ( !stricmp( key, "bounce" ) || !stricmp( key, "intensity" )) // me==bad for reusing this...but it shouldn't hurt anything) { ParseElasticity( val ); } else if ( !stricmp( key, "min" )) { ParseMin( val ); } else if ( !stricmp( key, "max" )) { ParseMax( val ); } else if ( !stricmp( key, "angle" ) || !stricmp( key, "angles" )) { ParseAngle( val ); } else if ( !stricmp( key, "angleDelta" )) { ParseAngleDelta( val ); } else if ( !stricmp( key, "velocity" ) || !stricmp( key, "vel" )) { ParseVelocity( val ); } else if ( !stricmp( key, "acceleration" ) || !stricmp( key, "accel" )) { ParseAcceleration( val ); } else if ( !stricmp( key, "gravity" )) { ParseGravity( val ); } else if ( !stricmp( key, "density" )) { ParseDensity( val ); } else if ( !stricmp( key, "variance" )) { ParseVariance( val ); } else if ( !stricmp( key, "origin" )) { ParseOrigin1( val ); } else if ( !stricmp( key, "origin2" )) { ParseOrigin2( val ); } else if ( !stricmp( key, "radius" )) // part of ellipse/cylinder calcs. { ParseRadius( val ); } else if ( !stricmp( key, "height" )) // part of ellipse/cylinder calcs. { ParseHeight( val ); } else if ( !stricmp( key, "rotation" )) { ParseRotation( val ); } else if ( !Q_stricmp( key, "rotationDelta" )) { ParseRotationDelta( val ); } else if ( !stricmp( key, "flags" ) || !stricmp( key, "flag" )) { // these need to get passed on to the primitive ParseFlags( val ); } else if ( !stricmp( key, "spawnFlags" ) || !stricmp( key, "spawnFlag" )) { // these are used to spawn things in cool ways, but don't ever get passed on to prims. ParseSpawnFlags( val ); } else if ( !stricmp( key, "name" )) { if ( val ) { // just stash the descriptive name of the primitive strcpy( mName, val ); } } else { theFxHelper.Print( "Unknown key parsing an effect primitive: %s\n", key ); } pairs = (CGPValue *)pairs->GetNext(); } subGrp = grp->GetSubGroups(); // Lets chomp on the groups now while ( subGrp ) { key = subGrp->GetName(); if ( !stricmp( key, "rgb" )) { ParseRGB( subGrp ); } else if ( !stricmp( key, "alpha" )) { ParseAlpha( subGrp ); } else if ( !stricmp( key, "size" ) || !stricmp( key, "width" )) { ParseSize( subGrp ); } else if ( !stricmp( key, "size2" ) || !stricmp( key, "width2" )) { ParseSize2( subGrp ); } else if ( !stricmp( key, "length" ) || !stricmp( key, "height" )) { ParseLength( subGrp ); } else { theFxHelper.Print( "Unknown group key parsing a particle: %s\n", key ); } subGrp = (CGPGroup *)subGrp->GetNext(); } return true; }
bool WaypointReaderSeeYou::ParseLine(const TCHAR* line, const unsigned linenum, Waypoints &waypoints) { enum { iName = 0, iLatitude = 3, iLongitude = 4, iElevation = 5, iStyle = 6, iRWDir = 7, iRWLen = 8, iFrequency = 9, iDescription = 10, }; if (linenum == 0) ignore_following = false; // If (end-of-file or comment) if (StringIsEmpty(line) || StringStartsWith(line, _T("**")) || StringStartsWith(line, _T("*"))) // -> return without error condition return true; TCHAR ctemp[4096]; if (_tcslen(line) >= ARRAY_SIZE(ctemp)) /* line too long for buffer */ return false; // Skip first line if it doesn't begin with a quotation character // (usually the field order line) if (linenum == 0 && line[0] != _T('\"')) return true; // If task marker is reached ignore all following lines if (_tcsstr(line, _T("-----Related Tasks-----")) == line) ignore_following = true; if (ignore_following) return true; // Get fields const TCHAR *params[20]; size_t n_params = ExtractParameters(line, ctemp, params, ARRAY_SIZE(params), true, _T('"')); // Check if the basic fields are provided if (iName >= n_params || iLatitude >= n_params || iLongitude >= n_params) return false; Waypoint new_waypoint; // Latitude (e.g. 5115.900N) if (!ParseAngle(params[iLatitude], new_waypoint.location.latitude, true)) return false; // Longitude (e.g. 00715.900W) if (!ParseAngle(params[iLongitude], new_waypoint.location.longitude, false)) return false; new_waypoint.location.Normalize(); // ensure longitude is within -180:180 new_waypoint.file_num = file_num; new_waypoint.original_id = 0; // Name (e.g. "Some Turnpoint") if (*params[iName] == _T('\0')) return false; new_waypoint.name = params[iName]; // Elevation (e.g. 458.0m) /// @todo configurable behaviour if ((iElevation >= n_params || !ParseAltitude(params[iElevation], new_waypoint.elevation)) && !CheckAltitude(new_waypoint)) return false; // Style (e.g. 5) if (iStyle < n_params) ParseStyle(params[iStyle], new_waypoint.type); new_waypoint.flags.turn_point = true; // Frequency & runway direction/length (for airports and landables) // and description (e.g. "Some Description") if (new_waypoint.IsLandable()) { if (iFrequency < n_params) new_waypoint.radio_frequency = RadioFrequency::Parse(params[iFrequency]); // Runway length (e.g. 546.0m) fixed rwlen = fixed_minus_one; if (iRWLen < n_params && ParseDistance(params[iRWLen], rwlen) && positive(rwlen)) new_waypoint.runway.SetLength(uround(rwlen)); if (iRWDir < n_params && *params[iRWDir]) { TCHAR *end; int direction =_tcstol(params[iRWDir], &end, 10); if (end == params[iRWDir] || direction < 0 || direction > 360 || (direction == 0 && !positive(rwlen))) direction = -1; else if (direction == 360) direction = 0; if (direction >= 0) new_waypoint.runway.SetDirectionDegrees(direction); } } if (iDescription < n_params) new_waypoint.comment = params[iDescription]; waypoints.Append(new_waypoint); return true; }