コード例 #1
0
ファイル: LoadCupTask.cpp プロジェクト: LK8000/LK8000
bool LoadCupTask(LPCTSTR szFileName) {
  //  LockTaskData();

  mapCode2Waypoint_t mapWaypoint;

  //  ClearTask();
  size_t idxTP = 0;
  bool bTakeOff = true;
  bool bLoadComplet = true;
  bool bLastInvalid=true;

  TCHAR szString[READLINE_LENGTH + 1];
  TCHAR TpCode[NAME_SIZE + 1];

  szString[READLINE_LENGTH] = _T('\0');
  TpCode[NAME_SIZE] = _T('\0');

  memset(szString, 0, sizeof (szString)); // clear Temp Buffer
  WAYPOINT newPoint = {0};
  WAYPOINT* WPtoAdd=NULL;

  enum {
    none, Waypoint, TaskTp, Option
  } FileSection = none;
  zzip_stream stream(szFileName, "rt");
  iNO_Tasks =0;
  TaskIndex =0;
  for (int i =0 ; i< MAX_TASKS;i++)
    szTaskStrings[ i] = NULL;
#define MULTITASKS_CUP
#ifdef MULTITASKS_CUP
    if (stream) {
      while (stream.read_line(szString)) {

          if ((FileSection == none) && ((_tcsncmp(_T("name,code,country"), szString, 17) == 0) ||
              (_tcsncmp(_T("Title,Code,Country"), szString, 18) == 0))) {
              FileSection = Waypoint;
              continue;
          } else if ((FileSection == Waypoint) && (_tcscmp(szString, _T("-----Related Tasks-----")) == 0)) {
              FileSection = TaskTp;
              continue;
          }


          if(  FileSection == TaskTp)
            {
              if(_tcsstr(szString, _T("\",\""))!= NULL)   // really a task? (not an option)
                {
                  if(iNO_Tasks < MAX_TASKS)   // Space in List left
                    {//[READLINE_LENGTH + 1];
                      szTaskStrings[ iNO_Tasks] =  new TCHAR[READLINE_LENGTH + 1];
                      if(  szTaskStrings[ iNO_Tasks] != NULL)
                      {
                        _tcscpy(szTaskStrings[ iNO_Tasks] , szString);  // copy task string
                         // StartupStore(_T("..Cup Task : %s  %s"), szTaskStrings[ iNO_Tasks], NEWLINE);
                        iNO_Tasks++;
                      }
                      else
                        StartupStore(_T("..Cup Task: no memory %s"), NEWLINE);
                    }
                  else
                    StartupStore(_T("..Cup Task Too many Tasks (more than %i) %s"), MAX_TASKS, NEWLINE);
                }
            }
      }
      stream.close();
      StartupStore(_T("..Cup Selected Task:%i %s  %s"), TaskIndex, szTaskStrings[ TaskIndex] , NEWLINE);
    }

  int res = 0;
  if(iNO_Tasks >1)   // Selection only if more than one task found
    res = dlgTaskSelectListShowModal();

  for (int i =0 ; i< MAX_TASKS;i++)    // free dynamic memory
    if(szTaskStrings[i] != NULL)
      {
        // StartupStore(_T("..Cup Task : delete dynamic memoryLine %i %s"), i,NEWLINE);
        delete[] szTaskStrings[i];
        szTaskStrings[i] = NULL;
      }
   if(res == mrCancel)
     return false;

  /***********************************************************************************/

  LockTaskData();
  ClearTask();
  stream.open(szFileName, "rt");
#endif

  FileSection = none;
  int i=0;
  if (stream) {
      while (stream.read_line(szString)) {

          if ((FileSection == none) && ((_tcsncmp(_T("name,code,country"), szString, 17) == 0) ||
              (_tcsncmp(_T("Title,Code,Country"), szString, 18) == 0))) {
              FileSection = Waypoint;
              continue;
          } else if ((FileSection == Waypoint) && (_tcscmp(szString, _T("-----Related Tasks-----")) == 0)) {
              FileSection = TaskTp;

              continue;
          }

          TCHAR *pToken = NULL;
          TCHAR *pWClast = NULL;

          switch (FileSection) {
          case Waypoint:
            memset(&newPoint, 0, sizeof(newPoint));
            if (ParseCUPWayPointString(szString, &newPoint)) {
                mapWaypoint[newPoint.Name] = newPoint;
            }
            break;
          case TaskTp:
            // 1. Description
            //       First column is the description of the task. If filled it should be double quoted.
            //       If left empty, then SeeYou will determine the task type on runtime.
            if ((pToken = strsep_r(szString, TEXT(","), &pWClast)) == NULL) {
                //  UnlockTaskData();  // no need to skip if only name missing!!!
                //  return false;
            }

            // 2. and all successive columns, separated by commas
            //       Each column represents one waypoint name double quoted. The waypoint name must be exactly the
            //       same as the Long name of a waypoint listed above the Related tasks.
            WPtoAdd=NULL;

            if (i++ == TaskIndex)  // load selected task
              {
                while (bLoadComplet && (pToken = strsep_r(NULL, TEXT(","), &pWClast)) != NULL) {
                    if (idxTP < MAXTASKPOINTS) {
                        _tcsncpy(TpCode, pToken, NAME_SIZE);
                        CleanCupCode(TpCode);
                        mapCode2Waypoint_t::iterator It = mapWaypoint.find(TpCode);
                        if(!ISGAAIRCRAFT) {
                            if (It != mapWaypoint.end()) {
                                if (bTakeOff) {
                                    // skip TakeOff Set At Home Waypoint
                                    int ix = FindOrAddWaypoint(&(It->second),false);
                                    if (ix>=0) {
#if 0 // REMOVE
                                        // We must not change HomeWaypoint without user knowing!
                                        // The takeoff and homewaypoint are independent from task.
                                        // In addition, this is a bug because on next run the index is invalid
                                        // and we have no more HowWaypoint!
                                        HomeWaypoint = ix;
#endif
                                        bTakeOff = false;
                                    }
#if BUGSTOP
                                    else LKASSERT(0); // .. else is unmanaged, TODO
#endif
                                } else {
                                    int ix =  FindOrAddWaypoint(&(It->second),false);
                                    if (ix>=0) Task[idxTP++].Index = ix;
#if BUGSTOP
                                    else LKASSERT(0); // .. else is unmanaged, TODO
#endif
                                }
                                bLastInvalid=false;
                            } else {
                                // An invalid takeoff, probably a "???" , which we ignore
#if TESTBENCH
                                if (bTakeOff) StartupStore(_T("....... CUP Takeoff not found: <%s>\n"),TpCode);
#endif
                                // in any case bTakeOff now is false
                                bTakeOff=false;
                                bLastInvalid=true;
                            }
                        } else { //ISGAIRRCRAFT
                            if(It != mapWaypoint.end()) {
                                if(WPtoAdd!=NULL) {
                                    //add what we found in previous cycle: it was not the last one
                                    int ix = FindOrAddWaypoint(WPtoAdd,false);
                                    if (ix>=0) Task[idxTP++].Index = ix;
#if BUGSTOP
                                    else LKASSERT(0); // .. else is unmanaged, TODO
#endif
                                }
                                if (bTakeOff) { //it's the first: may be we have a corresponding airfield
                                    //look for departure airfield and add it
                                    int ix = FindOrAddWaypoint(&(It->second),true);
                                    if (ix>=0) {
                                        Task[idxTP++].Index = ix;
                                        bTakeOff = false;
                                    }
#if BUGSTOP
                                    else LKASSERT(0); // .. else is unmanaged, TODO
#endif
                                } else WPtoAdd=&(It->second); //store it for next cycle (may be it is the last one)
                            }
                        }
                    } else {
                        bLoadComplet = false;
                    }
                }
                if(ISGAAIRCRAFT) { //For GA: check if we have an airport corresponding to the last WP
                    if(WPtoAdd!=NULL) { //if we have the last one (probably an airfield) still to add...
                        if(idxTP<MAXTASKPOINTS) {
                            int ix=FindOrAddWaypoint(WPtoAdd,true); //look for arrival airport and add it
                            if (ix>=0) {
                                Task[idxTP++].Index= ix;
                            }
#if BUGSTOP
                            else LKASSERT(0); // .. else is unmanaged, TODO
#endif
                        }
                        else bLoadComplet=false;
                    }
                }
                FileSection = Option;
              }
            break;
          case Option:
            if ((pToken = strsep_r(szString, TEXT(","), &pWClast)) != NULL) {
                if (_tcscmp(pToken, _T("Options")) == 0) {
                    while ((pToken = strsep_r(NULL, TEXT(","), &pWClast)) != NULL) {
                        if (_tcsstr(pToken, _T("NoStart=")) == pToken) {
                            // Opening of start line
                            PGNumberOfGates = 1;
                            StrToTime(pToken + 8, &PGOpenTimeH, &PGOpenTimeM);
                        } else if (_tcsstr(pToken, _T("TaskTime=")) == pToken) {
                            // Designated Time for the task
                            // TODO :
                        } else if (_tcsstr(pToken, _T("WpDis=")) == pToken) {
                            // Task distance calculation. False = use fixes, True = use waypoints
                            // TODO :
                        } else if (_tcsstr(pToken, _T("NearDis=")) == pToken) {
                            // Distance tolerance
                            // TODO :
                        } else if (_tcsstr(pToken, _T("NearAlt=")) == pToken) {
                            // Altitude tolerance
                            // TODO :
                        } else if (_tcsstr(pToken, _T("MinDis=")) == pToken) {
                            // Uncompleted leg.
                            // False = calculate maximum distance from last observation zone.
                            // TODO :
                        } else if (_tcsstr(pToken, _T("RandomOrder=")) == pToken) {
                            // if true, then Random order of waypoints is checked
                            // TODO :
                        } else if (_tcsstr(pToken, _T("MaxPts=")) == pToken) {
                            // Maximum number of points
                            // TODO :
                        } else if (_tcsstr(pToken, _T("BeforePts=")) == pToken) {
                            // Number of mandatory waypoints at the beginning. 1 means start line only, two means
                            //      start line plus first point in task sequence (Task line).
                            // TODO :
                        } else if (_tcsstr(pToken, _T("AfterPts=")) == pToken) {
                            // Number of mandatory waypoints at the end. 1 means finish line only, two means finish line
                            //      and one point before finish in task sequence (Task line).
                            // TODO :
                        } else if (_tcsstr(pToken, _T("Bonus=")) == pToken) {
                            // Bonus for crossing the finish line
                            // TODO :
                        }
                    }
                } else if (_tcsstr(pToken, _T("ObsZone=")) == pToken) {
                    TCHAR *sz = NULL;
                    CupObsZoneUpdater TmpZone;
                    TmpZone.mIdx = _tcstol(pToken + 8, &sz, 10);
                    if (TmpZone.mIdx < MAXTASKPOINTS) {
                        while ((pToken = strsep_r(NULL, TEXT(","), &pWClast)) != NULL) {
                            if (_tcsstr(pToken, _T("Style=")) == pToken) {
                                // Direction. 0 - Fixed value, 1 - Symmetrical, 2 - To next point, 3 - To previous point, 4 - To start point
                                TmpZone.mType = _tcstol(pToken + 6, &sz, 10);
                            } else if (_tcsstr(pToken, _T("R1=")) == pToken) {
                                // Radius 1
                                TmpZone.mR1 = ReadLength(pToken + 3);
                            } else if (_tcsstr(pToken, _T("A1=")) == pToken) {
                                // Angle 1 in degrees
                                TmpZone.mA1 = _tcstod(pToken + 3, &sz);
                            } else if (_tcsstr(pToken, _T("R2=")) == pToken) {
                                // Radius 2
                                TmpZone.mR2 = ReadLength(pToken + 3);
                            } else if (_tcsstr(pToken, _T("A2=")) == pToken) {
                                // Angle 2 in degrees
                                TmpZone.mA2 = _tcstod(pToken + 3, &sz);
                            } else if (_tcsstr(pToken, _T("A12=")) == pToken) {
                                // Angle 12
                                TmpZone.mA12 = _tcstod(pToken + 4, &sz);
                            } else if (_tcsstr(pToken, _T("Line=")) == pToken) {
                                // true For Line Turmpoint type
                                // Exist only for start an Goalin LK
                                TmpZone.mLine = (_tcstol(pToken + 5, &sz, 10) == 1);
                            }
                        }
                        TmpZone.UpdateTask();
                    }
                }
            }
            break;
          case none:
          default:
            break;
          }
          memset(szString, 0, sizeof (szString)); // clear Temp Buffer
      }
  }
  if(!ISGAAIRCRAFT) {
      // Landing don't exist in LK Task Systems, so Remove It;
      if ( bLoadComplet && !bLastInvalid ) {
          RemoveTaskPoint(getFinalWaypoint());
      }
  }
  UnlockTaskData();
  for (mapCode2Waypoint_t::iterator It = mapWaypoint.begin(); It != mapWaypoint.end(); ++It) {
      if (It->second.Comment) {
          free(It->second.Comment);
      }
      if (It->second.Details) {
          free(It->second.Details);
      }
  }
  mapWaypoint.clear();

  return ValidTaskPoint(0);
}
コード例 #2
0
ファイル: ReadFile.cpp プロジェクト: Acrobot/LK8000
// returns -1 if error, or the WpFileType 
int ReadWayPointFile(ZZIP_FILE *fp, TCHAR *CurrentWpFileName)
{
  WAYPOINT *new_waypoint;
  TCHAR szTemp[100];
  DWORD fSize, fPos=0;
  int nLineNumber=0;
  short fileformat=LKW_DAT;

  HWND hProgress;

  hProgress = CreateProgressDialog(gettext(TEXT("_@M903_"))); // Loading Waypoints File...

  fSize = zzip_file_size(fp);

  fileformat=GetWaypointFileFormatType(CurrentWpFileName);

  if (fileformat<0) {
	StartupStore(_T("... Unknown file format in waypoint file <%s\n"),CurrentWpFileName);
	// We do NOT return, because first we analyze the content.
  }

  if (fSize <10) {
	StartupStore(_T("... ReadWayPointFile: waypoint file %s type=%d is empty%s"), CurrentWpFileName,fileformat,NEWLINE);
	return -1;
  }

  if (!AllocateWaypointList()) {
	StartupStore(_T("!!!!!! ReadWayPointFile: AllocateWaypointList FAILED%s"),NEWLINE);
	return -1;
  }

  new_waypoint = WayPointList+NumberOfWayPoints;


  memset(nTemp2String, 0, sizeof(nTemp2String)); // clear Temp Buffer

  // check file format
  bool fempty=true;
  int  slen=0; // 100204 WIP
  while ( ReadString(fp,READLINE_LENGTH,nTemp2String) ) {
	slen=_tcslen(nTemp2String);
	if (slen<1) continue;
	if ( _tcsncmp(_T("G  WGS 84"),nTemp2String,9) == 0 ||
	   _tcsncmp(_T("G WGS 84"),nTemp2String,8) == 0 ||
	   // consider UCS header, 3 bytes in fact. This is a workaround.
	   _tcsncmp(_T("G  WGS 84"),&nTemp2String[3],9) == 0) {
		if ( !ReadString(fp,READLINE_LENGTH,nTemp2String) ) {
			StartupStore(_T(". Waypoint file %d format: CompeGPS truncated, rejected%s"),globalFileNum+1,NEWLINE);
			return -1;
		}
		slen=_tcslen(nTemp2String);
		if (slen<1) {
			StartupStore(_T(". Waypoint file %d format: CompeGPS MISSING second U line, rejected%s"),globalFileNum+1,NEWLINE);
			return -1;
		}
		if ( (_tcsncmp(_T("U  0"),nTemp2String,4) == 0) ||
		     (_tcsncmp(_T("U 0"),nTemp2String,3) == 0)) {
			StartupStore(_T(". Waypoint file %d format: CompeGPS with UTM coordinates UNSUPPORTED%s"),globalFileNum+1,NEWLINE);
			return -1;
		}
		if ( _tcsncmp(_T("U  1"),nTemp2String,4) != 0 && 
		     _tcsncmp(_T("U 1"),nTemp2String,3) != 0 ) {
			StartupStore(_T(". Waypoint file %d format: CompeGPS unknown U field, rejected%s"),globalFileNum+1,NEWLINE);
			return -1;
		}
		
		StartupStore(_T(". Waypoint file %d format: CompeGPS, LatLon coordinates%s"),globalFileNum+1,NEWLINE);
		fempty=false;
		fileformat=LKW_COMPE;
		break;
	}
	if ( (_tcsncmp(_T("name,code,country"),nTemp2String,17) == 0) || 
		(_tcsncmp(_T("Title,Code,Country"),nTemp2String,18) == 0)  // 100314
	) {
		StartupStore(_T(". Waypoint file %d format: SeeYou%s"),globalFileNum+1,NEWLINE);
		fempty=false;
		fileformat=LKW_CUP;
		break;
	}

	if ( ( _tcsstr(nTemp2String, _T("OziExplorer Waypoint File")) == nTemp2String )||
			   // consider UCS header, 3 bytes in fact. This is a workaround.
			(_tcsstr(&nTemp2String[3], _T("OziExplorer Waypoint File")) == &nTemp2String[3]) ) {
		StartupStore(_T(". Waypoint file %d format: OziExplorer%s"),globalFileNum+1,NEWLINE);
		fempty=false;
		fileformat=LKW_OZI;
		break;
	}

	// consider also the case of empty file, when a waypoint if saved starting with numbering after
	// the virtual wps (including the 0);
	// Warning, using virtualdatheader 3 tcsncmp because virtuals are now more than 9.
	TCHAR virtualdatheader[5];
	wsprintf(virtualdatheader,_T("%d,"),RESWP_END+2);
	if ( _tcsncmp(_T("1,"),nTemp2String,2) == 0 ||
	  _tcsncmp(virtualdatheader,nTemp2String,3) == 0) {
		StartupStore(_T(". Waypoint file %d format: WinPilot%s"),globalFileNum+1,NEWLINE);
		fempty=false;
		fileformat=LKW_DAT;
		break;
	}
	// Otherwise we use the fileformat .xxx suffix. 
	// Why we did not do it since the beginning? Simply because we should not rely on .xxx suffix
	// because some formats like CompeGPS and OZI, for example, share the same .WPT suffix.
	// 
	if (fileformat<0) {
		StartupStore(_T(".. Unknown WP header, unknown format in <%s>%s"),nTemp2String,NEWLINE);
		// leaving fempty true, so no good file available
		break;
	} else {
		fempty=false;
		StartupStore(_T(".. Unknown WP header, using format %d.  Header: <%s>%s"),fileformat,nTemp2String,NEWLINE);
		break;
	}
  }
  if (fempty) {
	return -1;
  }

  // SetFilePointer(hFile,0,NULL,FILE_BEGIN);
  fPos = 0;

  // a real shame, too lazy to change into do while loop
  // Skip already read lines containing header, unless we are using DAT, which has no header
  if ( fileformat==LKW_DAT) goto goto_inloop; 

  memset(nTemp2String, 0, sizeof(nTemp2String)); // clear Temp Buffer

  while(ReadString(fp, READLINE_LENGTH, nTemp2String)){
goto_inloop:    
	nLineNumber++;
	nTemp2String[READLINE_LENGTH]=_T('\0');
	nTemp2String[READLINE_LENGTH-1]=_T('\n');
	nTemp2String[READLINE_LENGTH-2]=_T('\r');
	fPos += _tcslen(nTemp2String);
   
	if (_tcsstr(nTemp2String, TEXT("**")) == nTemp2String) // Look For Comment
		continue;

	if (_tcsstr(nTemp2String, TEXT("*")) == nTemp2String)  // Look For SeeYou Comment
		continue;

	if (nTemp2String[0] == '\0')
		continue;

	new_waypoint->Details = NULL; 
	new_waypoint->Comment = NULL; 

	if ( fileformat == LKW_DAT || fileformat== LKW_XCW ) {
		if (ParseDAT(nTemp2String, new_waypoint)) {

			if ( (_tcscmp(new_waypoint->Name, gettext(TEXT(RESWP_TAKEOFF_NAME)))==0) && (new_waypoint->Number==RESWP_ID)) {
				StartupStore(_T("... FOUND TAKEOFF (%s) INSIDE WAYPOINTS FILE%s"), gettext(TEXT(RESWP_TAKEOFF_NAME)), NEWLINE);
				memcpy(WayPointList,new_waypoint,sizeof(WAYPOINT));
				continue;
			}

			if (WaypointInTerrainRange(new_waypoint)) { 
				new_waypoint = GrowWaypointList();
				if (!new_waypoint) {
					return -1; // failed to allocate
				}
				new_waypoint++; // we want the next blank one
			}	
	  	}
	}
	if ( fileformat == LKW_CUP ) {
		if ( _tcsncmp(_T("-----Related Tasks"),nTemp2String,18)==0) {
			break;
		}
		if (ParseCUPWayPointString(nTemp2String, new_waypoint)) {
			if ( (_tcscmp(new_waypoint->Name, gettext(TEXT(RESWP_TAKEOFF_NAME)))==0) && (new_waypoint->Number==RESWP_ID)) {
				StartupStore(_T("... FOUND TAKEOFF (%s) INSIDE WAYPOINTS FILE%s"), gettext(TEXT(RESWP_TAKEOFF_NAME)), NEWLINE);
				memcpy(WayPointList,new_waypoint,sizeof(WAYPOINT));
				continue;
			}

			if (WaypointInTerrainRange(new_waypoint)) { 
				new_waypoint = GrowWaypointList();
				if (!new_waypoint) {
					return -1; // failed to allocate
				}
				new_waypoint++; // we want the next blank one
			}
		}
	}
	if ( fileformat == LKW_COMPE ) {
		if (ParseCOMPEWayPointString(nTemp2String, new_waypoint)) {
			if ( (_tcscmp(new_waypoint->Name, gettext(TEXT(RESWP_TAKEOFF_NAME)))==0) && (new_waypoint->Number==RESWP_ID)) {
				StartupStore(_T("... FOUND TAKEOFF (%s) INSIDE WAYPOINTS FILE%s"), gettext(TEXT(RESWP_TAKEOFF_NAME)), NEWLINE);
				memcpy(WayPointList,new_waypoint,sizeof(WAYPOINT));
				continue;
			}

			if (WaypointInTerrainRange(new_waypoint)) { 
				new_waypoint = GrowWaypointList();
				if (!new_waypoint) {
					return -1; // failed to allocate
				}
				new_waypoint++; // we want the next blank one
			}
		}
	}

	if(fileformat == LKW_OZI){
		// Ignore first four header lines
		if(nLineNumber <= 3)
			continue;

		if(ParseOZIWayPointString(nTemp2String, new_waypoint)){
			if ( (_tcscmp(new_waypoint->Name, gettext(TEXT(RESWP_TAKEOFF_NAME)))==0) && (new_waypoint->Number==RESWP_ID)) {
				StartupStore(_T("... FOUND TAKEOFF (%s) INSIDE WAYPOINTS FILE%s"), gettext(TEXT(RESWP_TAKEOFF_NAME)), NEWLINE);
				memcpy(WayPointList,new_waypoint,sizeof(WAYPOINT));
				continue;
			}

			if (WaypointInTerrainRange(new_waypoint)) {
				new_waypoint = GrowWaypointList();
				if (!new_waypoint) {
					return -1; // failed to allocate
				}
				new_waypoint++; // we want the next blank one
			}
		}
	}

	memset(nTemp2String, 0, sizeof(nTemp2String)); // clear Temp Buffer

	continue;

  }

  if (hProgress) {
	_stprintf(szTemp,TEXT("100%%"));       
	SetDlgItemText(hProgress,IDC_PROGRESS,szTemp);
  }
  return fileformat;

}