//------------------------------------------------------------------------------ // queryRunwayBySubkey() -- find runway record(s) by the key/subkey //------------------------------------------------------------------------------ int AirportLoader::queryRunwayBySubkey(const char* subkey) { // truncate to length of runway key char rwKey[RW_KEY_LEN+1]; lcStrncpy(rwKey,RW_KEY_LEN+1,subkey,RW_KEY_LEN); rwKey[RW_KEY_LEN] = '\0'; stripSpaces(rwKey,RW_KEY_LEN); // Use queryByKey() find the airport queryByKey(rwKey); // keep a pointer to the airport AirportKey* apk = 0; if (nql == 1) apk = static_cast<AirportKey*>(ql[0]); // find all runways that have matching keys nql = 0; if (apk != 0) { int len = static_cast<int>(strlen(rwKey)); for (RunwayKey* rwk = apk->runways; rwk != 0; rwk = rwk->next) { if (strncmp(rwk->key,rwKey,len) == 0) ql[nql++] = rwk; } } // limit number of result records if (qlimit > 0 && nql > qlimit) nql = qlimit; return nql; }
//------------------------------------------------------------------------------ // queryByKey() -- find a airport by the airport record key //------------------------------------------------------------------------------ int AirportLoader::queryByKey(const char* subkey) { char apKey[AP_KEY_LEN+1]; lcStrncpy(apKey,AP_KEY_LEN+1,subkey,AP_KEY_LEN); apKey[AP_KEY_LEN] = '\0'; AirportKey key(apKey); Key* pkey = &key; return Database::sQuery(&pkey, rl, nrl, kl_cmp); }
//------------------------------------------------------------------------------ // dsAtoln() -- convert n-characters to long //------------------------------------------------------------------------------ long Record::dsAtoln(const char* const s, const int n) { if (s == 0) return 0; if (*s == 'U') return 0; const size_t BUF_LENGTH = 256; char buf[BUF_LENGTH]; lcStrncpy(buf, BUF_LENGTH, s, n); buf[n] = '\0'; return atol(buf); }
//------------------------------------------------------------------------------ // queryRunwayByIdent() -- find runway record by its identifier (airport_id + // runway end identifier). Therefore, each runway records will respond to two // identifiers: airport_id + high_end_id and airport_id + low_end_id. //------------------------------------------------------------------------------ int AirportLoader::queryRunwayByIdent(const char* id) { // Use queryByKey() find the airport queryByKey(id); // keep a pointer to the airport AirportKey* apk = 0; if (nql == 1) apk = static_cast<AirportKey*>(ql[0]); // find the runway that matches the identifier nql = 0; if (apk != 0) { char rwId[RW_XE_IDENT_LEN+1]; lcStrncpy(rwId,RW_XE_IDENT_LEN+1,&id[AP_KEY_LEN],RW_XE_IDENT_LEN); rwId[RW_XE_IDENT_LEN] = '\0'; fillSpaces(rwId,RW_XE_IDENT_LEN); char rwId2[RW_XE_IDENT_LEN+1]; lcStrncpy(rwId2,RW_XE_IDENT_LEN+1,&id[AP_KEY_LEN],RW_XE_IDENT_LEN); rwId2[RW_XE_IDENT_LEN] = '\0'; stripSpaces(rwId2,RW_XE_IDENT_LEN); for (RunwayKey* rwk = apk->runways; rwk != 0; rwk = rwk->next) { if ( (strncmp( &rwk->key[AP_KEY_LEN], rwId, RW_XE_IDENT_LEN ) == 0) || (strncmp( &rwk->key[AP_KEY_LEN+RW_XE_IDENT_LEN], rwId2, RW_XE_IDENT_LEN ) == 0) ) { ql[nql++] = rwk; } } } // limit number of result records if (qlimit > 0 && nql > qlimit) nql = qlimit; return nql; }
//------------------------------------------------------------------------------ // getSubString() -- Returns in "subStr" a "numChars" character sub-string // of 'this' string that starts a "startIndex" //------------------------------------------------------------------------------ bool String::getSubString(String& subStr, const unsigned int startIndex, const size_t numChars) const { if(startIndex > (n - 1)) return false; size_t maxChars = 0; if((startIndex + numChars) > n) maxChars = (n - startIndex); else maxChars = numChars; char* subString = new char[maxChars + 1]; lcStrncpy(subString, (maxChars + 1), &str[startIndex], maxChars); subString[maxChars] = '\0'; subStr.setStr(subString); delete[] subString; return true; }
// Get the description const char* TabLogger::LogGunActivity::getDescription() { if (msg == 0) { std::stringstream sout; // Time & Event message if (theType != 0) makeTimeMsg(sout); else makeTimeHdr(sout); sout << "GUN\t" ; switch(theType) { case 0: { sout << "HEADER\t"; break; } // same header shared for all of following case 1: { sout << "FIRED\t"; break; } default: { sout << "UNKNOWN\t"; break; } // unknown weapon activity.... } if (theType == 0) { sout << "launcher: "; makePlayerIdHdr(sout); sout << "rounds" << "\t"; // (1 field) } else { makePlayerIdMsg(sout, thePlayer); sout << rounds << "\t"; // (1 field) } // Complete the description int len = (int)sout.str().size(); msg = new char[len+1]; lcStrncpy(msg, (len+1), sout.str().c_str(), len); } return msg; }
//------------------------------------------------------------------------------ // findGlideSlope() -- find matching glideslope record //------------------------------------------------------------------------------ void AirportLoader::findGlideSlope(const RunwayKey* rwk, const IlsKey* lk) { // get the runway key without component type int locKeyLen = ILS_KEY_LEN - 1; char locKey[ILS_KEY_LEN]; lcStrncpy(locKey,ILS_KEY_LEN,lk->key,locKeyLen); locKey[locKeyLen] = '\0'; stripSpaces(locKey,locKeyLen); // find glide slope record that matches the localizer key for (IlsKey* ilsk = rwk->ils; ilsk != 0; ilsk = ilsk->next) { if (ilsk->type == Ils::GLIDESLOPE) { if (strncmp(locKey,ilsk->key,locKeyLen) == 0) { ql[nql++] = ilsk; } } } }
// Get the description const char* TabLogger::LogActiveTrack::getDescription() { if (msg == 0) { std::stringstream sout; // Time & Event message if (theType != 0) makeTimeMsg(sout); else makeTimeHdr(sout); sout << "TRACK_ACTIVE\t" ; switch(theType) { case 0: { sout << "HEADER\t"; break; } // same header shared for all of following case 1: { sout << "ADDED\t"; break; } case 2: { sout << "UPDATE\t"; break; } case 3: { sout << "REMOVED\t"; break; } default: { sout << "UNKNOWN\t"; break; } // someone called for a track.... unknown reason } if (theType == 0) // header line { sout << "Player: " ; makePlayerIdHdr(sout); makePlayerDataHdr(sout); sout << "Target: " ; makePlayerIdHdr(sout); makePlayerDataHdr(sout); sout << "Track: " ; makeTrackDataHdr(sout); } else { // Player information makePlayerIdMsg(sout, thePlayer); if (thePlayer != 0) makePlayerDataMsg(sout,pos,vel,angles); else makePlayerDataSpacer(sout); // Target Information if (theEmission != 0) { makePlayerIdMsg(sout, theEmission->getTarget()); if (theEmission->getTarget() != 0) makePlayerDataMsg(sout,tgtPos,tgtVel,tgtAngles); else makePlayerDataSpacer(sout); } else { makePlayerIdSpacer(sout); makePlayerDataSpacer(sout); } // General track information makeTrackDataMsg(sout, theTrack); } // Complete the description int len = (int)sout.str().size(); msg = new char[len+1]; lcStrncpy(msg, (len+1), sout.str().c_str(), len); } return msg; }
// Get the description const char* TabLogger::LogWeaponActivity::getDescription() { if (msg == 0) { std::stringstream sout; // Time & Event message if (theType != 0) makeTimeMsg(sout); else makeTimeHdr(sout); sout << "WEAPON\t" ; switch(theType) { case 0: { sout << "HEADER\t"; break; } // same header shared for all of following case 1: { sout << "RELEASE\t"; break; } case 2: { sout << "DETONATE\t"; break; } case 3: { sout << "KILL\t"; break; } // "KILL" not currently in use. case 4: { sout << "HUNG\t"; break; } default: { sout << "UNKNOWN\t"; break; } // unknown weapon activity.... } if (theType == 0) // header line { sout << "launcher: "; makePlayerIdHdr(sout); sout << "weapon: "; makePlayerIdHdr(sout); sout << "target: "; makePlayerIdHdr(sout); sout << "launch event ID\t" ; // launch event ID // (1 field) sout << "detonation type\t" ; // detonation type // (1 field) sout << "miss distance\t" ; // miss distance // (1 field) sout << "track: "; // track stored on weapon makeTrackDataHdr(sout); } else { // Print the (launcher) Player ID makePlayerIdMsg(sout, thePlayer); // Print the weapon ID makePlayerIdMsg(sout, theWeapon); // Print the target ID makePlayerIdMsg(sout, theTarget); sout << eventID << "\t" ; // launch event ID // (1 field) if ((theType == 1) || (theType == 4)) // (type 1, launch) or (type 4, hung store) { sout << "\t"; // detonation type // (1 field) sout << "\t"; // miss distance // (1 field) } else // (type 2, detonation) or (type 3, kill) { sout << detType << "\t"; // detonation type // (1 field) sout << missDist << "\t"; // miss distance // (1 field) } makeTrackDataMsg(sout, theTrack); } // Complete the description int len = (int)sout.str().size(); msg = new char[len+1]; lcStrncpy(msg, (len+1), sout.str().c_str(), len); } return msg; }
// Get the description const char* TabLogger::LogPlayerData::getDescription() { if (msg == 0) { std::stringstream sout; if (theType != 0) makeTimeMsg(sout); else makeTimeHdr(sout); sout << "PLAYER\t"; switch(theType) { case 0: { sout << "HEADER\t"; break; } // same header shared for all of following case 1: { sout << "NEW\t"; break; } case 2: { sout << "DATA\t"; break; } case 3: { sout << "REMOVED\t"; break; } case 4: { sout << "DAMAGE\t"; break; } case 5: { sout << "COLLISION\t"; break; } case 6: { sout << "CRASH\t"; break; } case 7: { sout << "KILL\t"; break; } default: { sout << "UNKNOWN\t"; break; } // someone called for a player.... unknown reason } if (theType == 0) // header line { makePlayerIdHdr(sout); makePlayerDataHdr(sout); makePlayerLatLonHdr(sout); sout << "alpha" << "\t" ; // (1 field) sout << "beta" << "\t" ; // (1 field) sout << "ias" << "\t" ; // (1 field) sout << "mach" << "\t" ; // (1 field) sout << "pLoading" << "\t" ; // (1 field) makePlayerDamageHdr(sout); sout << "damage source: " ; makePlayerIdHdr(sout); } else if (thePlayer == 0) { // no player data, so leave the line blank and skedaddle //sout << "\n"; } else { // Print the Player data makePlayerIdMsg(sout,thePlayer); makePlayerDataMsg(sout,pos,vel,angles); makePlayerLatLonMsg(sout, latitude, longitude); if ((ias >= 0.0f) && (theType == 2)) { sout << alpha << "\t" ; // (1 field) sout << beta << "\t" ; // (1 field) sout << ias << "\t" ; // (1 field) } else { sout << " \t\t\t"; } if (mach > 0.0) { sout << mach << "\t" ; // (1 field) sout << pLoading << "\t" ; // (1 field) } else { sout << "\t\t" ; } // print damage data if (theType == 4) // detonation { // third field in makePlayerDamageMsg differentiates between checking // killOverride (true) and crashOverride (false). makePlayerDamageMsg(sout, thePlayer, true); makePlayerIdMsg(sout, theSource); } else if ((theType == 5) || (theType == 7)) // collision or kill { makePlayerDamageMsg(sout, thePlayer, false); makePlayerIdMsg(sout, theSource); } else if (theType == 6) // crash (ground) { makePlayerDamageMsg(sout, thePlayer, false); makePlayerIdSpacer(sout); } else { makePlayerDamageSpacer(sout); makePlayerIdSpacer(sout); } } // Complete the description int len = (int)sout.str().size(); msg = new char[len+1]; lcStrncpy(msg, (len+1), sout.str().c_str(), len); } return msg; }