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;
}
Exemplo n.º 2
0
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;
}
Exemplo n.º 3
0
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;
}
Exemplo n.º 4
0
/**
 * 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;
}
Exemplo n.º 5
0
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;
}
Exemplo n.º 6
0
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;
	}
}
Exemplo n.º 7
0
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;
}
Exemplo n.º 8
0
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;
}
Exemplo n.º 9
0
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;
}
Exemplo n.º 10
0
// 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;
}
Exemplo n.º 11
0
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;
}