Compare commits

..

11 Commits

Author SHA1 Message Date
Erik Hofman
c19cf094a7 Backport the code to be able to display the region name of the file that holds the selected material. 2021-05-27 15:55:02 +02:00
Automatic Release Builder
279179e88d new version: 2020.3.9 2021-05-27 11:09:42 +01:00
James Turner
0ddd3e7f2f Add sg_location to all exceptions, add report flag
Move sg_location member up to the base clase, since it’s potentially
useful in more types.

Allow suppression of the report callback when the exception is thrown
2021-05-05 15:00:23 +01:00
James Turner
fe96298be5 Thread-safe error reporting in lowlevel.cxx
Use an exception rather than polling a flag, for checking errors
during BTG reading. This should allow us to give a correctly
identified error, at exactly the point the read fails.
2021-05-05 14:58:37 +01:00
James Turner
c6351292dd TerraSync: add a warning file to the root dir.
Try to discourage users from adding custom content underneath the
Terrasync dir, since it can be over-written.
2021-04-23 12:15:34 +01:00
James Turner
e2caad3b0b TerraSync: better reporting of permissions failures removing files
Log a ‘failed to remove orphan’ error as an error with the repository,
instead of failing the entire sync
2021-04-23 12:15:34 +01:00
James Turner
a095ab684c ASan: fix a leak in GZ extraction 2021-04-23 11:55:02 +01:00
James Turner
fe41a03180 Asan: fix leaks in Catalog code 2021-04-23 11:54:56 +01:00
Automatic Release Builder
332d9dfadb new version: 2020.3.8 2021-03-24 11:08:07 +00:00
Automatic Release Builder
c05802a498 new version: 2020.3.8 2021-03-24 11:04:18 +00:00
James Turner
0970bb1be2 Fix for local particle update
See issue at:
https://sourceforge.net/p/flightgear/codetickets/2568/
2021-03-24 09:59:13 +00:00
17 changed files with 671 additions and 651 deletions

View File

@@ -1 +1 @@
2020.3.7
2020.3.9

View File

@@ -377,7 +377,12 @@ public:
// We now have a list of entries that need to be updated, and a list
// of orphan files that should be removed.
removeOrphans(orphans);
try {
removeOrphans(orphans);
} catch (sg_exception& e) {
_repository->failedToUpdateChild(_relativePath, HTTPRepository::ResultCode::REPO_ERROR_IO);
}
scheduleUpdates(toBeUpdated);
}
@@ -389,11 +394,10 @@ public:
void removeOrphans(const PathList orphans)
{
PathList::const_iterator it;
for (it = orphans.begin(); it != orphans.end(); ++it) {
if (it->file() == ".dirindex") continue;
if (it->file() == ".hash") continue;
removeChild(*it);
for (const auto& o : orphans) {
if (o.file() == ".dirindex") continue;
if (o.file() == ".hash") continue;
removeChild(o);
}
}

View File

@@ -23,28 +23,41 @@
// $Id$
#ifdef HAVE_CONFIG_H
# include <simgear_config.h>
#endif
#include <simgear_config.h>
#include <string.h> // for memcpy()
#include <errno.h>
#include "lowlevel.hxx"
#include <simgear/structure/exception.hxx>
#include <simgear/misc/strutils.hxx>
#include <simgear/misc/sg_path.hxx>
#include "lowlevel.hxx"
static int read_error = false ;
static int write_error = false ;
thread_local SGPath thread_gzPath;
void sgClearReadError() { read_error = false; }
void sgClearWriteError() { write_error = false; }
int sgReadError() { return read_error ; }
int sgWriteError() { return write_error ; }
void setThreadLocalSimgearReadPath(const SGPath& path)
{
thread_gzPath = path;
}
static std::string gzErrorMessage(gzFile fd)
{
int errNum = 0;
const char *gzMsg = gzerror(fd, &errNum);
if (errNum == Z_ERRNO) {
return simgear::strutils::error_string(errno);
} else {
return {gzMsg};
}
}
void sgReadChar ( gzFile fd, char *var )
{
if ( gzread ( fd, var, sizeof(char) ) != sizeof(char) ) {
read_error = true ;
throw sg_io_exception("sgReadChar: GZRead failed:" + gzErrorMessage(fd),
sg_location{thread_gzPath}, nullptr, false);
}
}
@@ -52,7 +65,7 @@ void sgReadChar ( gzFile fd, char *var )
void sgWriteChar ( gzFile fd, const char var )
{
if ( gzwrite ( fd, (void *)(&var), sizeof(char) ) != sizeof(char) ) {
write_error = true ;
throw sg_io_exception("sgWriteChar: gzwrite failed:" + gzErrorMessage(fd), {} /* origin */, false);
}
}
@@ -61,7 +74,8 @@ void sgReadFloat ( gzFile fd, float *var )
{
union { float v; uint32_t u; } buf;
if ( gzread ( fd, &buf.u, sizeof(float) ) != sizeof(float) ) {
read_error = true ;
throw sg_io_exception("sgReadFloat: GZRead failed:" + gzErrorMessage(fd),
sg_location{thread_gzPath}, nullptr, false);
}
if ( sgIsBigEndian() ) {
sgEndianSwap( &buf.u );
@@ -78,7 +92,7 @@ void sgWriteFloat ( gzFile fd, const float var )
sgEndianSwap( &buf.u );
}
if ( gzwrite ( fd, (void *)(&buf.u), sizeof(float) ) != sizeof(float) ) {
write_error = true ;
throw sg_io_exception("sgWriteFloat: gzwrite failed:" + gzErrorMessage(fd), {} /* origin */, false);
}
}
@@ -87,7 +101,8 @@ void sgReadDouble ( gzFile fd, double *var )
{
union { double v; uint64_t u; } buf;
if ( gzread ( fd, &buf.u, sizeof(double) ) != sizeof(double) ) {
read_error = true ;
throw sg_io_exception("sgReadDouble: GZRead failed:" + gzErrorMessage(fd),
sg_location{thread_gzPath}, nullptr, false);
}
if ( sgIsBigEndian() ) {
sgEndianSwap( &buf.u );
@@ -104,7 +119,7 @@ void sgWriteDouble ( gzFile fd, const double var )
sgEndianSwap( &buf.u );
}
if ( gzwrite ( fd, (void *)(&buf.u), sizeof(double) ) != sizeof(double) ) {
write_error = true ;
throw sg_io_exception("sgWriteDouble: gzwrite failed:" + gzErrorMessage(fd), {} /* origin */, false);
}
}
@@ -112,7 +127,8 @@ void sgWriteDouble ( gzFile fd, const double var )
void sgReadUInt ( gzFile fd, unsigned int *var )
{
if ( gzread ( fd, var, sizeof(unsigned int) ) != sizeof(unsigned int) ) {
read_error = true ;
throw sg_io_exception("sgReadUInt: GZRead failed:" + gzErrorMessage(fd),
sg_location{thread_gzPath}, nullptr, false);
}
if ( sgIsBigEndian() ) {
sgEndianSwap( (uint32_t *)var);
@@ -128,7 +144,7 @@ void sgWriteUInt ( gzFile fd, const unsigned int var )
if ( gzwrite ( fd, (void *)(&var), sizeof(unsigned int) )
!= sizeof(unsigned int) )
{
write_error = true ;
throw sg_io_exception("sgWriteUInt: gzwrite failed:" + gzErrorMessage(fd), {} /* origin */, false);
}
}
@@ -136,7 +152,8 @@ void sgWriteUInt ( gzFile fd, const unsigned int var )
void sgReadInt ( gzFile fd, int *var )
{
if ( gzread ( fd, var, sizeof(int) ) != sizeof(int) ) {
read_error = true ;
throw sg_io_exception("sgReadInt: GZRead failed:" + gzErrorMessage(fd),
sg_location{thread_gzPath}, nullptr, false);
}
if ( sgIsBigEndian() ) {
sgEndianSwap( (uint32_t *)var);
@@ -150,7 +167,7 @@ void sgWriteInt ( gzFile fd, const int var )
sgEndianSwap( (uint32_t *)&var);
}
if ( gzwrite ( fd, (void *)(&var), sizeof(int) ) != sizeof(int) ) {
write_error = true ;
throw sg_io_exception("sgWriteInt: gzwrite failed:" + gzErrorMessage(fd), {} /* origin */, false);
}
}
@@ -158,7 +175,8 @@ void sgWriteInt ( gzFile fd, const int var )
void sgReadLong ( gzFile fd, int32_t *var )
{
if ( gzread ( fd, var, sizeof(int32_t) ) != sizeof(int32_t) ) {
read_error = true ;
throw sg_io_exception("sgReadLong: GZRead failed:" + gzErrorMessage(fd),
sg_location{thread_gzPath}, nullptr, false);
}
if ( sgIsBigEndian() ) {
sgEndianSwap( (uint32_t *)var);
@@ -174,7 +192,7 @@ void sgWriteLong ( gzFile fd, const int32_t var )
if ( gzwrite ( fd, (void *)(&var), sizeof(int32_t) )
!= sizeof(int32_t) )
{
write_error = true ;
throw sg_io_exception("sgWriteLong: gzwrite failed:" + gzErrorMessage(fd), {} /* origin */, false);
}
}
@@ -182,7 +200,8 @@ void sgWriteLong ( gzFile fd, const int32_t var )
void sgReadLongLong ( gzFile fd, int64_t *var )
{
if ( gzread ( fd, var, sizeof(int64_t) ) != sizeof(int64_t) ) {
read_error = true ;
throw sg_io_exception("sgReadLongLong: GZRead failed:" + gzErrorMessage(fd),
sg_location{thread_gzPath}, nullptr, false);
}
if ( sgIsBigEndian() ) {
sgEndianSwap( (uint64_t *)var);
@@ -198,7 +217,7 @@ void sgWriteLongLong ( gzFile fd, const int64_t var )
if ( gzwrite ( fd, (void *)(&var), sizeof(int64_t) )
!= sizeof(int64_t) )
{
write_error = true ;
throw sg_io_exception("sgWriteLongLong: gzwrite failed:" + gzErrorMessage(fd), {} /* origin */, false);
}
}
@@ -206,7 +225,8 @@ void sgWriteLongLong ( gzFile fd, const int64_t var )
void sgReadUShort ( gzFile fd, unsigned short *var )
{
if ( gzread ( fd, var, sizeof(unsigned short) ) != sizeof(unsigned short) ){
read_error = true ;
throw sg_io_exception("sgReadUShort: GZRead failed:" + gzErrorMessage(fd),
sg_location{thread_gzPath}, nullptr, false);
}
if ( sgIsBigEndian() ) {
sgEndianSwap( (uint16_t *)var);
@@ -222,7 +242,7 @@ void sgWriteUShort ( gzFile fd, const unsigned short var )
if ( gzwrite ( fd, (void *)(&var), sizeof(unsigned short) )
!= sizeof(unsigned short) )
{
write_error = true ;
throw sg_io_exception("sgWriteUShort: gzwrite failed:" + gzErrorMessage(fd), {} /* origin */, false);
}
}
@@ -230,7 +250,8 @@ void sgWriteUShort ( gzFile fd, const unsigned short var )
void sgReadShort ( gzFile fd, short *var )
{
if ( gzread ( fd, var, sizeof(short) ) != sizeof(short) ) {
read_error = true ;
throw sg_io_exception("sgReadShort: GZRead failed:" + gzErrorMessage(fd),
sg_location{thread_gzPath}, nullptr, false);
}
if ( sgIsBigEndian() ) {
sgEndianSwap( (uint16_t *)var);
@@ -244,7 +265,7 @@ void sgWriteShort ( gzFile fd, const short var )
sgEndianSwap( (uint16_t *)&var);
}
if ( gzwrite ( fd, (void *)(&var), sizeof(short) ) != sizeof(short) ) {
write_error = true ;
throw sg_io_exception("sgWriteShort: gzwrite failed:" + gzErrorMessage(fd), {} /* origin */, false);
}
}
@@ -252,7 +273,8 @@ void sgWriteShort ( gzFile fd, const short var )
void sgReadFloat ( gzFile fd, const unsigned int n, float *var )
{
if ( gzread ( fd, var, sizeof(float) * n ) != (int)(sizeof(float) * n) ) {
read_error = true ;
throw sg_io_exception("sgReadFloat array: GZRead failed:" + gzErrorMessage(fd),
sg_location{thread_gzPath}, nullptr, false);
}
if ( sgIsBigEndian() ) {
for ( unsigned int i = 0; i < n; ++i ) {
@@ -276,14 +298,15 @@ void sgWriteFloat ( gzFile fd, const unsigned int n, const float *var )
if ( gzwrite ( fd, (void *)var, sizeof(float) * n )
!= (int)(sizeof(float) * n) )
{
write_error = true ;
throw sg_io_exception("sgWriteFloat array: gzwrite failed:" + gzErrorMessage(fd), {} /* origin */, false);
}
}
void sgReadDouble ( gzFile fd, const unsigned int n, double *var )
{
if ( gzread ( fd, var, sizeof(double) * n ) != (int)(sizeof(double) * n) ) {
read_error = true ;
throw sg_io_exception("sgReadDouble array: GZRead failed:" + gzErrorMessage(fd),
sg_location{thread_gzPath}, nullptr, false);
}
if ( sgIsBigEndian() ) {
for ( unsigned int i = 0; i < n; ++i ) {
@@ -307,7 +330,7 @@ void sgWriteDouble ( gzFile fd, const unsigned int n, const double *var )
if ( gzwrite ( fd, (void *)var, sizeof(double) * n )
!= (int)(sizeof(double) * n) )
{
write_error = true ;
throw sg_io_exception("sgWriteDouble array: gzwrite failed:" + gzErrorMessage(fd), {} /* origin */, false);
}
}
@@ -315,7 +338,8 @@ void sgReadBytes ( gzFile fd, const unsigned int n, void *var )
{
if ( n == 0) return;
if ( gzread ( fd, var, n ) != (int)n ) {
read_error = true ;
throw sg_io_exception("sgReadBytes: GZRead failed:" + gzErrorMessage(fd),
sg_location{thread_gzPath}, nullptr, false);
}
}
@@ -323,7 +347,7 @@ void sgWriteBytes ( gzFile fd, const unsigned int n, const void *var )
{
if ( n == 0) return;
if ( gzwrite ( fd, (void *)var, n ) != (int)n ) {
write_error = true ;
throw sg_io_exception("sgWriteBytes: gzwrite failed:" + gzErrorMessage(fd), {} /* origin */, false);
}
}
@@ -333,7 +357,8 @@ void sgReadUShort ( gzFile fd, const unsigned int n, unsigned short *var )
if ( gzread ( fd, var, sizeof(unsigned short) * n )
!= (int)(sizeof(unsigned short) * n) )
{
read_error = true ;
throw sg_io_exception("sgReadUShort array: GZRead failed:" + gzErrorMessage(fd),
sg_location{thread_gzPath}, nullptr, false);
}
if ( sgIsBigEndian() ) {
for ( unsigned int i = 0; i < n; ++i ) {
@@ -357,7 +382,7 @@ void sgWriteUShort ( gzFile fd, const unsigned int n, const unsigned short *var
if ( gzwrite ( fd, (void *)var, sizeof(unsigned short) * n )
!= (int)(sizeof(unsigned short) * n) )
{
write_error = true ;
throw sg_io_exception("sgWriteUShort array: gzwrite failed:" + gzErrorMessage(fd), {} /* origin */, false);
}
}
@@ -368,7 +393,8 @@ void sgReadShort ( gzFile fd, const unsigned int n, short *var )
if ( gzread ( fd, var, sizeof(short) * n )
!= (int)(sizeof(short) * n) )
{
read_error = true ;
throw sg_io_exception("sgReadShort array: GZRead failed:" + gzErrorMessage(fd),
sg_location{thread_gzPath}, nullptr, false);
}
if ( sgIsBigEndian() ) {
for ( unsigned int i = 0; i < n; ++i ) {
@@ -392,7 +418,7 @@ void sgWriteShort ( gzFile fd, const unsigned int n, const short *var )
if ( gzwrite ( fd, (void *)var, sizeof(short) * n )
!= (int)(sizeof(short) * n) )
{
write_error = true ;
throw sg_io_exception("sgWriteShort array: gzwrite failed:" + gzErrorMessage(fd), {} /* origin */, false);
}
}
@@ -402,7 +428,8 @@ void sgReadUInt ( gzFile fd, const unsigned int n, unsigned int *var )
if ( gzread ( fd, var, sizeof(unsigned int) * n )
!= (int)(sizeof(unsigned int) * n) )
{
read_error = true ;
throw sg_io_exception("sgReadUInt array: GZRead failed:" + gzErrorMessage(fd),
sg_location{thread_gzPath}, nullptr, false);
}
if ( sgIsBigEndian() ) {
for ( unsigned int i = 0; i < n; ++i ) {
@@ -426,7 +453,7 @@ void sgWriteUInt ( gzFile fd, const unsigned int n, const unsigned int *var )
if ( gzwrite ( fd, (void *)var, sizeof(unsigned int) * n )
!= (int)(sizeof(unsigned int) * n) )
{
write_error = true ;
throw sg_io_exception("sgWriteUInt array: gzwrite failed:" + gzErrorMessage(fd), {} /* origin */, false);
}
}
@@ -437,7 +464,8 @@ void sgReadInt ( gzFile fd, const unsigned int n, int *var )
if ( gzread ( fd, var, sizeof(int) * n )
!= (int)(sizeof(int) * n) )
{
read_error = true ;
throw sg_io_exception("sgReadInt array: GZRead failed:" + gzErrorMessage(fd),
sg_location{thread_gzPath}, nullptr, false);
}
if ( sgIsBigEndian() ) {
for ( unsigned int i = 0; i < n; ++i ) {
@@ -461,7 +489,7 @@ void sgWriteInt ( gzFile fd, const unsigned int n, const int *var )
if ( gzwrite ( fd, (void *)var, sizeof(int) * n )
!= (int)(sizeof(int) * n) )
{
write_error = true ;
throw sg_io_exception("sgWriteInt array: gzwrite failed:" + gzErrorMessage(fd), {} /* origin */, false);
}
}

View File

@@ -35,6 +35,9 @@
#include <simgear/math/SGMath.hxx>
// forward decls
class SGPath;
// Note that output is written in little endian form (and converted as
// necessary for big endian machines)
@@ -121,9 +124,10 @@ inline void sgWriteGeod ( gzFile fd, const SGGeod& var ) {
sgWriteDouble( fd, var.getElevationM() );
}
void sgClearReadError();
void sgClearWriteError();
int sgReadError();
int sgWriteError();
/**
@ error aid: allow calling code to specify which file path we're reading from, so that erros we
throw from sgReadXXXX can have a valid location set.
*/
void setThreadLocalSimgearReadPath(const SGPath& path);
#endif // _SG_LOWLEVEL_HXX

View File

@@ -454,10 +454,6 @@ void SGBinObject::read_object( gzFile fp,
}
}
if ( sgReadError() ) {
throw sg_exception("Error reading object properties");
}
size_t indexCount = std::bitset<32>((int)idx_mask).count();
if (indexCount == 0) {
throw sg_exception("object index mask has no bits set");
@@ -465,18 +461,10 @@ void SGBinObject::read_object( gzFile fp,
for ( j = 0; j < nelements; ++j ) {
sgReadUInt( fp, &nbytes );
if ( sgReadError() ) {
throw sg_exception("Error reading element size");
}
buf.resize( nbytes );
char *ptr = buf.get_ptr();
sgReadBytes( fp, nbytes, ptr );
if ( sgReadError() ) {
throw sg_exception("Error reading element bytes");
}
int_list vs;
int_list ns;
int_list cs;
@@ -503,314 +491,309 @@ void SGBinObject::read_object( gzFile fp,
// read a binary file and populate the provided structures.
bool SGBinObject::read_bin( const SGPath& file ) {
SGVec3d p;
int i, k;
size_t j;
unsigned int nbytes;
sgSimpleBuffer buf( 32768 ); // 32 Kb
bool SGBinObject::read_bin( const SGPath& file )
{
gzFile fp = NULL;
try {
SGVec3d p;
int i, k;
size_t j;
unsigned int nbytes;
sgSimpleBuffer buf( 32768 ); // 32 Kb
// zero out structures
gbs_center = SGVec3d(0, 0, 0);
gbs_radius = 0.0;
// zero out structures
gbs_center = SGVec3d(0, 0, 0);
gbs_radius = 0.0;
wgs84_nodes.clear();
normals.clear();
texcoords.clear();
wgs84_nodes.clear();
normals.clear();
texcoords.clear();
pts_v.clear();
pts_n.clear();
pts_c.clear();
pts_tcs.clear();
pts_vas.clear();
pt_materials.clear();
pts_v.clear();
pts_n.clear();
pts_c.clear();
pts_tcs.clear();
pts_vas.clear();
pt_materials.clear();
tris_v.clear();
tris_n.clear();
tris_c.clear();
tris_tcs.clear();
tris_vas.clear();
tri_materials.clear();
tris_v.clear();
tris_n.clear();
tris_c.clear();
tris_tcs.clear();
tris_vas.clear();
tri_materials.clear();
strips_v.clear();
strips_n.clear();
strips_c.clear();
strips_tcs.clear();
strips_vas.clear();
strip_materials.clear();
strips_v.clear();
strips_n.clear();
strips_c.clear();
strips_tcs.clear();
strips_vas.clear();
strip_materials.clear();
fans_v.clear();
fans_n.clear();
fans_c.clear();
fans_tcs.clear();
fans_vas.clear();
fan_materials.clear();
fans_v.clear();
fans_n.clear();
fans_c.clear();
fans_tcs.clear();
fans_vas.clear();
fan_materials.clear();
gzFile fp = gzFileFromSGPath(file, "rb");
if ( fp == NULL ) {
SGPath withGZ = file;
withGZ.concat(".gz");
fp = gzFileFromSGPath(withGZ, "rb");
if (fp == nullptr) {
SG_LOG( SG_EVENT, SG_ALERT,
"ERROR: opening " << file << " or " << withGZ << " for reading!");
throw sg_io_exception("Error opening for reading (and .gz)", sg_location(file));
gzFile fp = gzFileFromSGPath(file, "rb");
if ( fp == NULL ) {
SGPath withGZ = file;
withGZ.concat(".gz");
fp = gzFileFromSGPath(withGZ, "rb");
if (fp == nullptr) {
throw sg_io_exception("Error opening for reading (and .gz)", sg_location(file), {}, false);
}
}
}
setThreadLocalSimgearReadPath(file);
sgClearReadError();
// read headers
unsigned int header;
sgReadUInt( fp, &header );
// read headers
unsigned int header;
sgReadUInt( fp, &header );
if (sgReadError()) {
int code = 0;
const char* gzErrorString = gzerror(fp, &code);
gzclose(fp);
throw sg_io_exception("Unable to read BTG header: " + string{gzErrorString} + ", code =" + std::to_string(code), sg_location(file));
}
if ( ((header & 0xFF000000) >> 24) == 'S' &&
((header & 0x00FF0000) >> 16) == 'G' ) {
if ( ((header & 0xFF000000) >> 24) == 'S' &&
((header & 0x00FF0000) >> 16) == 'G' ) {
// read file version
version = (header & 0x0000FFFF);
} else {
throw sg_io_exception("Bad BTG magic/version", sg_location(file), {}, false);
}
// read file version
version = (header & 0x0000FFFF);
} else {
// close the file before we return
gzclose(fp);
throw sg_io_exception("Bad BTG magic/version", sg_location(file));
}
// read creation time
unsigned int foo_calendar_time;
sgReadUInt( fp, &foo_calendar_time );
// read creation time
unsigned int foo_calendar_time;
sgReadUInt( fp, &foo_calendar_time );
#if 0
time_t calendar_time = foo_calendar_time;
// The following code has a global effect on the host application
// and can screws up the time elsewhere. It should be avoided
// unless you need this for debugging in which case you should
// disable it again once the debugging task is finished.
struct tm *local_tm;
local_tm = localtime( &calendar_time );
char time_str[256];
strftime( time_str, 256, "%a %b %d %H:%M:%S %Z %Y", local_tm);
SG_LOG( SG_EVENT, SG_DEBUG, "File created on " << time_str);
#endif
#if 0
time_t calendar_time = foo_calendar_time;
// The following code has a global effect on the host application
// and can screws up the time elsewhere. It should be avoided
// unless you need this for debugging in which case you should
// disable it again once the debugging task is finished.
struct tm *local_tm;
local_tm = localtime( &calendar_time );
char time_str[256];
strftime( time_str, 256, "%a %b %d %H:%M:%S %Z %Y", local_tm);
SG_LOG( SG_EVENT, SG_DEBUG, "File created on " << time_str);
#endif
// read number of top level objects
int nobjects;
if ( version >= 10) { // version 10 extends everything to be 32-bit
sgReadInt( fp, &nobjects );
} else if ( version >= 7 ) {
uint16_t v;
sgReadUShort( fp, &v );
nobjects = v;
} else {
int16_t v;
sgReadShort( fp, &v );
nobjects = v;
}
SG_LOG(SG_IO, SG_DEBUG, "SGBinObject::read_bin Total objects to read = " << nobjects);
if ( sgReadError() ) {
throw sg_io_exception("Error reading BTG file header", sg_location(file));
}
// read in objects
for ( i = 0; i < nobjects; ++i ) {
// read object header
char obj_type;
uint32_t nproperties, nelements;
sgReadChar( fp, &obj_type );
if ( version >= 10 ) {
sgReadUInt( fp, &nproperties );
sgReadUInt( fp, &nelements );
// read number of top level objects
int nobjects;
if ( version >= 10) { // version 10 extends everything to be 32-bit
sgReadInt( fp, &nobjects );
} else if ( version >= 7 ) {
uint16_t v;
sgReadUShort( fp, &v );
nproperties = v;
sgReadUShort( fp, &v );
nelements = v;
nobjects = v;
} else {
int16_t v;
sgReadShort( fp, &v );
nproperties = v;
sgReadShort( fp, &v );
nelements = v;
nobjects = v;
}
SG_LOG(SG_IO, SG_DEBUG, "SGBinObject::read_bin object " << i <<
" = " << (int)obj_type << " props = " << nproperties <<
" elements = " << nelements);
SG_LOG(SG_IO, SG_DEBUG, "SGBinObject::read_bin Total objects to read = " << nobjects);
if ( obj_type == SG_BOUNDING_SPHERE ) {
// read bounding sphere properties
read_properties( fp, nproperties );
// read bounding sphere elements
for ( j = 0; j < nelements; ++j ) {
sgReadUInt( fp, &nbytes );
buf.resize( nbytes );
buf.reset();
char *ptr = buf.get_ptr();
sgReadBytes( fp, nbytes, ptr );
gbs_center = buf.readVec3d();
gbs_radius = buf.readFloat();
// read in objects
for ( i = 0; i < nobjects; ++i ) {
// read object header
char obj_type;
uint32_t nproperties, nelements;
sgReadChar( fp, &obj_type );
if ( version >= 10 ) {
sgReadUInt( fp, &nproperties );
sgReadUInt( fp, &nelements );
} else if ( version >= 7 ) {
uint16_t v;
sgReadUShort( fp, &v );
nproperties = v;
sgReadUShort( fp, &v );
nelements = v;
} else {
int16_t v;
sgReadShort( fp, &v );
nproperties = v;
sgReadShort( fp, &v );
nelements = v;
}
} else if ( obj_type == SG_VERTEX_LIST ) {
// read vertex list properties
read_properties( fp, nproperties );
// read vertex list elements
for ( j = 0; j < nelements; ++j ) {
sgReadUInt( fp, &nbytes );
buf.resize( nbytes );
buf.reset();
char *ptr = buf.get_ptr();
sgReadBytes( fp, nbytes, ptr );
int count = nbytes / (sizeof(float) * 3);
wgs84_nodes.reserve( count );
for ( k = 0; k < count; ++k ) {
SGVec3f v = buf.readVec3f();
// extend from float to double, hmmm
wgs84_nodes.push_back( SGVec3d(v[0], v[1], v[2]) );
SG_LOG(SG_IO, SG_DEBUG, "SGBinObject::read_bin object " << i <<
" = " << (int)obj_type << " props = " << nproperties <<
" elements = " << nelements);
if ( obj_type == SG_BOUNDING_SPHERE ) {
// read bounding sphere properties
read_properties( fp, nproperties );
// read bounding sphere elements
for ( j = 0; j < nelements; ++j ) {
sgReadUInt( fp, &nbytes );
buf.resize( nbytes );
buf.reset();
char *ptr = buf.get_ptr();
sgReadBytes( fp, nbytes, ptr );
gbs_center = buf.readVec3d();
gbs_radius = buf.readFloat();
}
}
} else if ( obj_type == SG_COLOR_LIST ) {
// read color list properties
read_properties( fp, nproperties );
} else if ( obj_type == SG_VERTEX_LIST ) {
// read vertex list properties
read_properties( fp, nproperties );
// read color list elements
for ( j = 0; j < nelements; ++j ) {
sgReadUInt( fp, &nbytes );
buf.resize( nbytes );
buf.reset();
char *ptr = buf.get_ptr();
sgReadBytes( fp, nbytes, ptr );
int count = nbytes / (sizeof(float) * 4);
colors.reserve(count);
for ( k = 0; k < count; ++k ) {
colors.push_back( buf.readVec4f() );
// read vertex list elements
for ( j = 0; j < nelements; ++j ) {
sgReadUInt( fp, &nbytes );
buf.resize( nbytes );
buf.reset();
char *ptr = buf.get_ptr();
sgReadBytes( fp, nbytes, ptr );
int count = nbytes / (sizeof(float) * 3);
wgs84_nodes.reserve( count );
for ( k = 0; k < count; ++k ) {
SGVec3f v = buf.readVec3f();
// extend from float to double, hmmm
wgs84_nodes.push_back( SGVec3d(v[0], v[1], v[2]) );
}
}
}
} else if ( obj_type == SG_NORMAL_LIST ) {
// read normal list properties
read_properties( fp, nproperties );
} else if ( obj_type == SG_COLOR_LIST ) {
// read color list properties
read_properties( fp, nproperties );
// read normal list elements
for ( j = 0; j < nelements; ++j ) {
sgReadUInt( fp, &nbytes );
buf.resize( nbytes );
buf.reset();
unsigned char *ptr = (unsigned char *)(buf.get_ptr());
sgReadBytes( fp, nbytes, ptr );
int count = nbytes / 3;
normals.reserve( count );
for ( k = 0; k < count; ++k ) {
SGVec3f normal( (ptr[0]) / 127.5 - 1.0,
(ptr[1]) / 127.5 - 1.0,
(ptr[2]) / 127.5 - 1.0);
normals.push_back(normalize(normal));
ptr += 3;
// read color list elements
for ( j = 0; j < nelements; ++j ) {
sgReadUInt( fp, &nbytes );
buf.resize( nbytes );
buf.reset();
char *ptr = buf.get_ptr();
sgReadBytes( fp, nbytes, ptr );
int count = nbytes / (sizeof(float) * 4);
colors.reserve(count);
for ( k = 0; k < count; ++k ) {
colors.push_back( buf.readVec4f() );
}
}
}
} else if ( obj_type == SG_TEXCOORD_LIST ) {
// read texcoord list properties
read_properties( fp, nproperties );
} else if ( obj_type == SG_NORMAL_LIST ) {
// read normal list properties
read_properties( fp, nproperties );
// read texcoord list elements
for ( j = 0; j < nelements; ++j ) {
sgReadUInt( fp, &nbytes );
buf.resize( nbytes );
buf.reset();
char *ptr = buf.get_ptr();
sgReadBytes( fp, nbytes, ptr );
int count = nbytes / (sizeof(float) * 2);
texcoords.reserve(count);
for ( k = 0; k < count; ++k ) {
texcoords.push_back( buf.readVec2f() );
// read normal list elements
for ( j = 0; j < nelements; ++j ) {
sgReadUInt( fp, &nbytes );
buf.resize( nbytes );
buf.reset();
unsigned char *ptr = (unsigned char *)(buf.get_ptr());
sgReadBytes( fp, nbytes, ptr );
int count = nbytes / 3;
normals.reserve( count );
for ( k = 0; k < count; ++k ) {
SGVec3f normal( (ptr[0]) / 127.5 - 1.0,
(ptr[1]) / 127.5 - 1.0,
(ptr[2]) / 127.5 - 1.0);
normals.push_back(normalize(normal));
ptr += 3;
}
}
}
} else if ( obj_type == SG_VA_FLOAT_LIST ) {
// read vertex attribute (float) properties
read_properties( fp, nproperties );
} else if ( obj_type == SG_TEXCOORD_LIST ) {
// read texcoord list properties
read_properties( fp, nproperties );
// read vertex attribute list elements
for ( j = 0; j < nelements; ++j ) {
sgReadUInt( fp, &nbytes );
buf.resize( nbytes );
buf.reset();
char *ptr = buf.get_ptr();
sgReadBytes( fp, nbytes, ptr );
int count = nbytes / (sizeof(float));
va_flt.reserve(count);
for ( k = 0; k < count; ++k ) {
va_flt.push_back( buf.readFloat() );
// read texcoord list elements
for ( j = 0; j < nelements; ++j ) {
sgReadUInt( fp, &nbytes );
buf.resize( nbytes );
buf.reset();
char *ptr = buf.get_ptr();
sgReadBytes( fp, nbytes, ptr );
int count = nbytes / (sizeof(float) * 2);
texcoords.reserve(count);
for ( k = 0; k < count; ++k ) {
texcoords.push_back( buf.readVec2f() );
}
}
}
} else if ( obj_type == SG_VA_INTEGER_LIST ) {
// read vertex attribute (integer) properties
read_properties( fp, nproperties );
} else if ( obj_type == SG_VA_FLOAT_LIST ) {
// read vertex attribute (float) properties
read_properties( fp, nproperties );
// read vertex attribute list elements
for ( j = 0; j < nelements; ++j ) {
sgReadUInt( fp, &nbytes );
buf.resize( nbytes );
buf.reset();
char *ptr = buf.get_ptr();
sgReadBytes( fp, nbytes, ptr );
int count = nbytes / (sizeof(unsigned int));
va_int.reserve(count);
for ( k = 0; k < count; ++k ) {
va_int.push_back( buf.readInt() );
// read vertex attribute list elements
for ( j = 0; j < nelements; ++j ) {
sgReadUInt( fp, &nbytes );
buf.resize( nbytes );
buf.reset();
char *ptr = buf.get_ptr();
sgReadBytes( fp, nbytes, ptr );
int count = nbytes / (sizeof(float));
va_flt.reserve(count);
for ( k = 0; k < count; ++k ) {
va_flt.push_back( buf.readFloat() );
}
}
}
} else if ( obj_type == SG_POINTS ) {
// read point elements
read_object( fp, SG_POINTS, nproperties, nelements,
pts_v, pts_n, pts_c, pts_tcs,
pts_vas, pt_materials );
} else if ( obj_type == SG_TRIANGLE_FACES ) {
// read triangle face properties
read_object( fp, SG_TRIANGLE_FACES, nproperties, nelements,
tris_v, tris_n, tris_c, tris_tcs,
tris_vas, tri_materials );
} else if ( obj_type == SG_TRIANGLE_STRIPS ) {
// read triangle strip properties
read_object( fp, SG_TRIANGLE_STRIPS, nproperties, nelements,
strips_v, strips_n, strips_c, strips_tcs,
strips_vas, strip_materials );
} else if ( obj_type == SG_TRIANGLE_FANS ) {
// read triangle fan properties
read_object( fp, SG_TRIANGLE_FANS, nproperties, nelements,
fans_v, fans_n, fans_c, fans_tcs,
fans_vas, fan_materials );
} else {
// unknown object type, just skip
read_properties( fp, nproperties );
} else if ( obj_type == SG_VA_INTEGER_LIST ) {
// read vertex attribute (integer) properties
read_properties( fp, nproperties );
// read elements
for ( j = 0; j < nelements; ++j ) {
sgReadUInt( fp, &nbytes );
// cout << "element size = " << nbytes << endl;
if ( nbytes > buf.get_size() ) { buf.resize( nbytes ); }
char *ptr = buf.get_ptr();
sgReadBytes( fp, nbytes, ptr );
// read vertex attribute list elements
for ( j = 0; j < nelements; ++j ) {
sgReadUInt( fp, &nbytes );
buf.resize( nbytes );
buf.reset();
char *ptr = buf.get_ptr();
sgReadBytes( fp, nbytes, ptr );
int count = nbytes / (sizeof(unsigned int));
va_int.reserve(count);
for ( k = 0; k < count; ++k ) {
va_int.push_back( buf.readInt() );
}
}
} else if ( obj_type == SG_POINTS ) {
// read point elements
read_object( fp, SG_POINTS, nproperties, nelements,
pts_v, pts_n, pts_c, pts_tcs,
pts_vas, pt_materials );
} else if ( obj_type == SG_TRIANGLE_FACES ) {
// read triangle face properties
read_object( fp, SG_TRIANGLE_FACES, nproperties, nelements,
tris_v, tris_n, tris_c, tris_tcs,
tris_vas, tri_materials );
} else if ( obj_type == SG_TRIANGLE_STRIPS ) {
// read triangle strip properties
read_object( fp, SG_TRIANGLE_STRIPS, nproperties, nelements,
strips_v, strips_n, strips_c, strips_tcs,
strips_vas, strip_materials );
} else if ( obj_type == SG_TRIANGLE_FANS ) {
// read triangle fan properties
read_object( fp, SG_TRIANGLE_FANS, nproperties, nelements,
fans_v, fans_n, fans_c, fans_tcs,
fans_vas, fan_materials );
} else {
// unknown object type, just skip
read_properties( fp, nproperties );
// read elements
for ( j = 0; j < nelements; ++j ) {
sgReadUInt( fp, &nbytes );
// cout << "element size = " << nbytes << endl;
if ( nbytes > buf.get_size() ) { buf.resize( nbytes ); }
char *ptr = buf.get_ptr();
sgReadBytes( fp, nbytes, ptr );
}
}
}
if ( sgReadError() ) {
throw sg_io_exception("Error while reading object", sg_location(file, i));
gzclose(fp);
fp = NULL;
} catch (std::exception&) {
if (fp) {
// close the file
gzclose(fp);
}
throw; // re-throw
}
// close the file
gzclose(fp);
return true;
}
@@ -984,112 +967,112 @@ bool SGBinObject::write_bin_file(const SGPath& file)
return false;
}
sgClearWriteError();
try {
SG_LOG(SG_IO, SG_DEBUG, "points size = " << pts_v.size()
<< " pt_materials = " << pt_materials.size() );
SG_LOG(SG_IO, SG_DEBUG, "triangles size = " << tris_v.size()
<< " tri_materials = " << tri_materials.size() );
SG_LOG(SG_IO, SG_DEBUG, "strips size = " << strips_v.size()
<< " strip_materials = " << strip_materials.size() );
SG_LOG(SG_IO, SG_DEBUG, "fans size = " << fans_v.size()
<< " fan_materials = " << fan_materials.size() );
SG_LOG(SG_IO, SG_DEBUG, "points size = " << pts_v.size()
<< " pt_materials = " << pt_materials.size() );
SG_LOG(SG_IO, SG_DEBUG, "triangles size = " << tris_v.size()
<< " tri_materials = " << tri_materials.size() );
SG_LOG(SG_IO, SG_DEBUG, "strips size = " << strips_v.size()
<< " strip_materials = " << strip_materials.size() );
SG_LOG(SG_IO, SG_DEBUG, "fans size = " << fans_v.size()
<< " fan_materials = " << fan_materials.size() );
SG_LOG(SG_IO, SG_DEBUG, "nodes = " << wgs84_nodes.size() );
SG_LOG(SG_IO, SG_DEBUG, "colors = " << colors.size() );
SG_LOG(SG_IO, SG_DEBUG, "normals = " << normals.size() );
SG_LOG(SG_IO, SG_DEBUG, "tex coords = " << texcoords.size() );
SG_LOG(SG_IO, SG_DEBUG, "nodes = " << wgs84_nodes.size() );
SG_LOG(SG_IO, SG_DEBUG, "colors = " << colors.size() );
SG_LOG(SG_IO, SG_DEBUG, "normals = " << normals.size() );
SG_LOG(SG_IO, SG_DEBUG, "tex coords = " << texcoords.size() );
version = 10;
bool shortMaterialsRanges =
(max_object_size(pt_materials) < VERSION_7_MATERIAL_LIMIT) &&
(max_object_size(fan_materials) < VERSION_7_MATERIAL_LIMIT) &&
(max_object_size(strip_materials) < VERSION_7_MATERIAL_LIMIT) &&
(max_object_size(tri_materials) < VERSION_7_MATERIAL_LIMIT);
version = 10;
bool shortMaterialsRanges =
(max_object_size(pt_materials) < VERSION_7_MATERIAL_LIMIT) &&
(max_object_size(fan_materials) < VERSION_7_MATERIAL_LIMIT) &&
(max_object_size(strip_materials) < VERSION_7_MATERIAL_LIMIT) &&
(max_object_size(tri_materials) < VERSION_7_MATERIAL_LIMIT);
if ((wgs84_nodes.size() < 0xffff) &&
(normals.size() < 0xffff) &&
(texcoords.size() < 0xffff) &&
shortMaterialsRanges) {
version = 7; // use smaller indices if possible
}
if ((wgs84_nodes.size() < 0xffff) &&
(normals.size() < 0xffff) &&
(texcoords.size() < 0xffff) &&
shortMaterialsRanges) {
version = 7; // use smaller indices if possible
}
// write header magic
// write header magic
/** Magic Number for our file format */
#define SG_FILE_MAGIC_NUMBER ( ('S'<<24) + ('G'<<16) + version )
/** Magic Number for our file format */
#define SG_FILE_MAGIC_NUMBER ( ('S'<<24) + ('G'<<16) + version )
sgWriteUInt( fp, SG_FILE_MAGIC_NUMBER );
time_t calendar_time = time(NULL);
sgWriteLong( fp, (int32_t)calendar_time );
sgWriteUInt( fp, SG_FILE_MAGIC_NUMBER );
time_t calendar_time = time(NULL);
sgWriteLong( fp, (int32_t)calendar_time );
// calculate and write number of top level objects
int nobjects = 5; // gbs, vertices, colors, normals, texcoords
nobjects += count_objects(pt_materials);
nobjects += count_objects(tri_materials);
nobjects += count_objects(strip_materials);
nobjects += count_objects(fan_materials);
// calculate and write number of top level objects
int nobjects = 5; // gbs, vertices, colors, normals, texcoords
nobjects += count_objects(pt_materials);
nobjects += count_objects(tri_materials);
nobjects += count_objects(strip_materials);
nobjects += count_objects(fan_materials);
SG_LOG(SG_IO, SG_DEBUG, "total top level objects = " << nobjects);
SG_LOG(SG_IO, SG_DEBUG, "total top level objects = " << nobjects);
if (version == 7) {
sgWriteUShort( fp, (uint16_t) nobjects );
} else {
sgWriteInt( fp, nobjects );
}
if (version == 7) {
sgWriteUShort( fp, (uint16_t) nobjects );
} else {
sgWriteInt( fp, nobjects );
}
// write bounding sphere
write_header( fp, SG_BOUNDING_SPHERE, 0, 1);
sgWriteUInt( fp, sizeof(double) * 3 + sizeof(float) ); // nbytes
sgWritedVec3( fp, gbs_center );
sgWriteFloat( fp, gbs_radius );
// write bounding sphere
write_header( fp, SG_BOUNDING_SPHERE, 0, 1);
sgWriteUInt( fp, sizeof(double) * 3 + sizeof(float) ); // nbytes
sgWritedVec3( fp, gbs_center );
sgWriteFloat( fp, gbs_radius );
// dump vertex list
write_header( fp, SG_VERTEX_LIST, 0, 1);
sgWriteUInt( fp, wgs84_nodes.size() * sizeof(float) * 3 ); // nbytes
for ( i = 0; i < (int)wgs84_nodes.size(); ++i ) {
sgWriteVec3( fp, toVec3f(wgs84_nodes[i] - gbs_center));
}
// dump vertex list
write_header( fp, SG_VERTEX_LIST, 0, 1);
sgWriteUInt( fp, wgs84_nodes.size() * sizeof(float) * 3 ); // nbytes
for ( i = 0; i < (int)wgs84_nodes.size(); ++i ) {
sgWriteVec3( fp, toVec3f(wgs84_nodes[i] - gbs_center));
}
// dump vertex color list
write_header( fp, SG_COLOR_LIST, 0, 1);
sgWriteUInt( fp, colors.size() * sizeof(float) * 4 ); // nbytes
for ( i = 0; i < (int)colors.size(); ++i ) {
sgWriteVec4( fp, colors[i]);
}
// dump vertex color list
write_header( fp, SG_COLOR_LIST, 0, 1);
sgWriteUInt( fp, colors.size() * sizeof(float) * 4 ); // nbytes
for ( i = 0; i < (int)colors.size(); ++i ) {
sgWriteVec4( fp, colors[i]);
}
// dump vertex normal list
write_header( fp, SG_NORMAL_LIST, 0, 1);
sgWriteUInt( fp, normals.size() * 3 ); // nbytes
char normal[3];
for ( i = 0; i < (int)normals.size(); ++i ) {
SGVec3f p = normals[i];
normal[0] = (unsigned char)((p.x() + 1.0) * 127.5);
normal[1] = (unsigned char)((p.y() + 1.0) * 127.5);
normal[2] = (unsigned char)((p.z() + 1.0) * 127.5);
sgWriteBytes( fp, 3, normal );
}
// dump vertex normal list
write_header( fp, SG_NORMAL_LIST, 0, 1);
sgWriteUInt( fp, normals.size() * 3 ); // nbytes
char normal[3];
for ( i = 0; i < (int)normals.size(); ++i ) {
SGVec3f p = normals[i];
normal[0] = (unsigned char)((p.x() + 1.0) * 127.5);
normal[1] = (unsigned char)((p.y() + 1.0) * 127.5);
normal[2] = (unsigned char)((p.z() + 1.0) * 127.5);
sgWriteBytes( fp, 3, normal );
}
// dump texture coordinates
write_header( fp, SG_TEXCOORD_LIST, 0, 1);
sgWriteUInt( fp, texcoords.size() * sizeof(float) * 2 ); // nbytes
for ( i = 0; i < (int)texcoords.size(); ++i ) {
sgWriteVec2( fp, texcoords[i]);
}
// dump texture coordinates
write_header( fp, SG_TEXCOORD_LIST, 0, 1);
sgWriteUInt( fp, texcoords.size() * sizeof(float) * 2 ); // nbytes
for ( i = 0; i < (int)texcoords.size(); ++i ) {
sgWriteVec2( fp, texcoords[i]);
}
write_objects(fp, SG_POINTS, pts_v, pts_n, pts_c, pts_tcs, pts_vas, pt_materials);
write_objects(fp, SG_TRIANGLE_FACES, tris_v, tris_n, tris_c, tris_tcs, tris_vas, tri_materials);
write_objects(fp, SG_TRIANGLE_STRIPS, strips_v, strips_n, strips_c, strips_tcs, strips_vas, strip_materials);
write_objects(fp, SG_TRIANGLE_FANS, fans_v, fans_n, fans_c, fans_tcs, fans_vas, fan_materials);
write_objects(fp, SG_POINTS, pts_v, pts_n, pts_c, pts_tcs, pts_vas, pt_materials);
write_objects(fp, SG_TRIANGLE_FACES, tris_v, tris_n, tris_c, tris_tcs, tris_vas, tri_materials);
write_objects(fp, SG_TRIANGLE_STRIPS, strips_v, strips_n, strips_c, strips_tcs, strips_vas, strip_materials);
write_objects(fp, SG_TRIANGLE_FANS, fans_v, fans_n, fans_c, fans_tcs, fans_vas, fan_materials);
// close the file
gzclose(fp);
if ( sgWriteError() ) {
cout << "Error while writing file " << file << endl;
// close the file
gzclose(fp);
fp = NULL;
} catch (std::exception&) {
if (fp) {
gzclose(fp);
}
return false;
}
return true;
}

View File

@@ -348,6 +348,9 @@ public:
~GZTarExtractor()
{
if (haveInitedZLib) {
inflateEnd(&zlibStream);
}
free(zlibOutput);
}

View File

@@ -619,6 +619,8 @@ void Catalog::setUserEnabled(bool b)
void Catalog::processAlternate(SGPropertyNode_ptr alt)
{
m_refreshRequest.reset();
std::string altId;
const auto idPtr = alt->getStringValue("id");
if (idPtr) {
@@ -694,8 +696,8 @@ void Catalog::processAlternate(SGPropertyNode_ptr alt)
SG_LOG(SG_GENERAL, SG_INFO, "Migrating catalog " << id() << " to new URL:" << altUrl);
setUrl(altUrl);
Downloader* dl = new Downloader(this, altUrl);
root()->makeHTTPRequest(dl);
m_refreshRequest = new Downloader(this, altUrl);
root()->makeHTTPRequest(m_refreshRequest);
}
int Catalog::markPackagesForInstallation(const string_list &packageIds) {

View File

@@ -166,7 +166,8 @@ int parseTest()
{
SGPath rootPath = simgear::Dir::current().path();
rootPath.append("testRoot");
pkg::Root* root = new pkg::Root(rootPath, "8.1.12");
pkg::RootRef root(new pkg::Root(rootPath, "8.1.2"));
root->setLocale("de");
pkg::CatalogRef cat = pkg::Catalog::createFromPath(root, SGPath(SRC_DIR "/catalogTest1"));
@@ -344,7 +345,6 @@ int parseTest()
SG_CHECK_EQUAL(urls.size(), 3);
SG_CHECK_EQUAL(urls.at(1), "http://localhost:2000/mirrorB/b737.tar.gz");
delete root;
return EXIT_SUCCESS;
}
@@ -953,7 +953,7 @@ int parseInvalidTest()
{
SGPath rootPath = simgear::Dir::current().path();
rootPath.append("testRoot");
pkg::Root* root = new pkg::Root(rootPath, "8.1.12");
pkg::RootRef root(new pkg::Root(rootPath, "8.1.12"));
pkg::CatalogRef cat = pkg::Catalog::createFromPath(root, SGPath(SRC_DIR "/catalogTestInvalid"));
SG_VERIFY(cat.valid());
@@ -1333,25 +1333,25 @@ int main(int argc, char* argv[])
testRefreshCatalog(&cl);
testInstallTarPackage(&cl);
testInstallArchiveType(&cl);
testDisableDueToVersion(&cl);
testOfflineMode(&cl);
testVersionMigrate(&cl);
updateInvalidToValid(&cl);
updateValidToInvalid(&cl);
updateInvalidToInvalid(&cl);
removeInvalidCatalog(&cl);
testVersionMigrateToId(&cl);
testInstallBadPackage(&cl);
testMirrorsFailure(&cl);
testMigrateInstalled(&cl);

View File

@@ -97,11 +97,13 @@ SGMaterial::SGMaterial( const SGReaderWriterOptions* options,
const SGPropertyNode *props,
SGPropertyNode *prop_root,
AreaList *a,
SGSharedPtr<const SGCondition> c)
SGSharedPtr<const SGCondition> c,
const std::string& n)
{
init();
areas = a;
condition = c;
region = n;
read_properties( options, props, prop_root );
buildEffectProperties(options);
}
@@ -110,12 +112,14 @@ SGMaterial::SGMaterial( const osgDB::Options* options,
const SGPropertyNode *props,
SGPropertyNode *prop_root,
AreaList *a,
SGSharedPtr<const SGCondition> c)
SGSharedPtr<const SGCondition> c,
const std::string& n)
{
osg::ref_ptr<SGReaderWriterOptions> opt;
opt = SGReaderWriterOptions::copyOrCreate(options);
areas = a;
condition = c;
region = n;
init();
read_properties(opt.get(), props, prop_root);
buildEffectProperties(opt.get());

View File

@@ -97,14 +97,16 @@ public:
const SGPropertyNode *props,
SGPropertyNode *prop_root,
AreaList *a,
SGSharedPtr<const SGCondition> c);
SGSharedPtr<const SGCondition> c,
const std::string& n);
SGMaterial(const simgear::SGReaderWriterOptions*,
const SGPropertyNode *props,
SGPropertyNode *prop_root,
AreaList *a,
SGSharedPtr<const SGCondition> c);
SGSharedPtr<const SGCondition> c,
const std::string& n);
/**
* Destructor.
@@ -123,6 +125,11 @@ public:
simgear::Effect* get_one_effect(int texIndex);
simgear::Effect* get_effect();
/**
* Get the region Name.
*/
const std::string get_region_name() const { return region; }
/**
* Get the Effect Name.
*/
@@ -487,6 +494,9 @@ private:
SGVec4f ambient, diffuse, specular, emission;
double shininess;
// region of this material
std::string region;
// effect for this material
std::string effect;

View File

@@ -128,12 +128,13 @@ bool SGMaterialLib::load( const SGPath &fg_root, const SGPath& mpath,
// Now build all the materials for this set of areas and conditions
const std::string region = node->getStringValue("name");
const simgear::PropertyList materials = node->getChildren("material");
simgear::PropertyList::const_iterator materials_iter = materials.begin();
for (; materials_iter != materials.end(); materials_iter++) {
const SGPropertyNode *node = materials_iter->get();
SGSharedPtr<SGMaterial> m =
new SGMaterial(options.get(), node, prop_root, arealist, condition);
new SGMaterial(options.get(), node, prop_root, arealist, condition, region);
std::vector<SGPropertyNode_ptr>names = node->getChildren("name");
for ( unsigned int j = 0; j < names.size(); j++ ) {

View File

@@ -187,6 +187,7 @@ void ParticlesGlobalManager::initFromMainThread()
std::lock_guard<std::mutex> g(d->_lock);
d->internalGetCommonRoot();
d->_commonRoot->addUpdateCallback(d.get());
d->_commonRoot->setCullingActive(false);
d->_commonRoot->addCullCallback(d->_cullCallback);
}

View File

@@ -1124,6 +1124,9 @@ void SGTerraSync::reinit()
SGPath sceneryRoot{_terraRoot->getStringValue("scenery-dir", "")};
_workerThread->setLocalDir(sceneryRoot.utf8Str());
if (sceneryRoot.exists()) {
writeWarningFile(sceneryRoot);
}
SGPath installPath(_terraRoot->getStringValue("installation-dir"));
_workerThread->setInstalledDir(installPath);
@@ -1362,6 +1365,23 @@ void SGTerraSync::reposition()
// stub, remove
}
void SGTerraSync::writeWarningFile(const SGPath& sceneryDir)
{
SGPath p = sceneryDir / "TerraSync-WARNING.txt";
if (p.exists())
return;
sg_ofstream os(p, std::ios::out | std::ios::trunc);
os << "This folder is managed by FlightGear's download system.\n";
os << "Any changes you make here or in sub-folders will be overwritten when TerraSync\n";
os << "downloads updates.\n";
os << "\n";
os << "To use custom scenery or data with FlightGear, put it in a differnet location\n";
os << "on your computer, then add the location using either the launcher 'Add-ons' page, or by\n";
os << "passing '--fg-scenery=<location>' on the command line.";
os << endl;
}
// Register the subsystem.
SGSubsystemMgr::Registrant<SGTerraSync> registrantSGTerraSync(

View File

@@ -90,6 +90,9 @@ protected:
class WorkerThread;
private:
void writeWarningFile(const SGPath& sceneryDir);
private:
WorkerThread* _workerThread;
SGPropertyNode_ptr _terraRoot;

View File

@@ -19,66 +19,65 @@ static ThrowCallback static_callback;
// Implementation of sg_location class.
////////////////////////////////////////////////////////////////////////
sg_location::sg_location ()
: _line(-1),
_column(-1),
_byte(-1)
sg_location::sg_location() noexcept
: _line(-1),
_column(-1),
_byte(-1)
{
_path[0] = '\0';
}
sg_location::sg_location (const std::string& path, int line, int column)
: _line(line),
_column(column),
_byte(-1)
sg_location::sg_location(const std::string& path, int line, int column) noexcept
: _line(line),
_column(column),
_byte(-1)
{
setPath(path.c_str());
}
sg_location::sg_location (const SGPath& path, int line, int column)
: _line(line),
_column(column),
_byte(-1)
sg_location::sg_location(const SGPath& path, int line, int column) noexcept
: _line(line),
_column(column),
_byte(-1)
{
setPath(path.utf8Str().c_str());
}
sg_location::sg_location (const char* path, int line, int column)
: _line(line),
_column(column),
_byte(-1)
sg_location::sg_location(const char* path, int line, int column) noexcept
: _line(line),
_column(column),
_byte(-1)
{
setPath(path);
}
void sg_location::setPath(const char *path) {
if (path) {
strncpy(_path, path, max_path);
_path[max_path -1] = '\0';
} else {
_path[0] = '\0';
}
void sg_location::setPath(const char* path) noexcept
{
if (path) {
strncpy(_path, path, max_path);
_path[max_path - 1] = '\0';
} else {
_path[0] = '\0';
}
}
const char *sg_location::getPath() const { return _path; }
const char* sg_location::getPath() const noexcept { return _path; }
int sg_location::getLine() const { return _line; }
int sg_location::getLine() const noexcept { return _line; }
int
sg_location::getColumn () const
int sg_location::getColumn() const noexcept
{
return _column;
}
int
sg_location::getByte () const
int sg_location::getByte() const noexcept
{
return _byte;
}
std::string
sg_location::asString () const
sg_location::asString() const noexcept
{
std::ostringstream out;
if (_path[0]) {
@@ -97,46 +96,48 @@ sg_location::asString () const
return out.str();
}
bool sg_location::isValid() const { return strlen(_path) > 0; }
bool sg_location::isValid() const noexcept { return strlen(_path) > 0; }
////////////////////////////////////////////////////////////////////////
// Implementation of sg_throwable class.
////////////////////////////////////////////////////////////////////////
sg_throwable::sg_throwable ()
sg_throwable::sg_throwable() noexcept
{
_message[0] = '\0';
_origin[0] = '\0';
}
sg_throwable::sg_throwable(const char *message, const char *origin,
const sg_location &loc) {
setMessage(message);
setOrigin(origin);
if (static_callback) {
static_callback(_message, _origin, loc);
}
}
sg_throwable::~sg_throwable ()
sg_throwable::sg_throwable(const char* message, const char* origin,
const sg_location& loc, bool report) noexcept : _location(loc)
{
setMessage(message);
setOrigin(origin);
if (static_callback && report) {
static_callback(_message, _origin, loc);
}
}
const char*
sg_throwable::getMessage () const
sg_throwable::getMessage() const noexcept
{
return _message;
}
const std::string
sg_throwable::getFormattedMessage () const
std::string
sg_throwable::getFormattedMessage() const noexcept
{
return std::string(getMessage());
std::string ret = getMessage();
const std::string loc = getLocation().asString();
if (loc.length()) {
ret += "\n at ";
ret += loc;
}
return ret;
}
void
sg_throwable::setMessage (const char* message)
void sg_throwable::setMessage(const char* message) noexcept
{
strncpy(_message, message, MAX_TEXT_LEN);
_message[MAX_TEXT_LEN - 1] = '\0';
@@ -144,13 +145,12 @@ sg_throwable::setMessage (const char* message)
}
const char*
sg_throwable::getOrigin () const
sg_throwable::getOrigin() const noexcept
{
return _origin;
}
void
sg_throwable::setOrigin (const char* origin)
void sg_throwable::setOrigin(const char* origin) noexcept
{
if (origin) {
strncpy(_origin, origin, MAX_TEXT_LEN);
@@ -170,27 +170,27 @@ const char* sg_throwable::what() const noexcept
}
}
sg_location sg_throwable::getLocation() const noexcept
{
return _location;
}
void sg_throwable::setLocation(const sg_location& location) noexcept
{
_location = location;
}
////////////////////////////////////////////////////////////////////////
// Implementation of sg_error class.
////////////////////////////////////////////////////////////////////////
sg_error::sg_error ()
: sg_throwable ()
sg_error::sg_error(const char* message, const char* origin, bool report) noexcept
: sg_throwable(message, origin, {}, report)
{
}
sg_error::sg_error (const char* message, const char *origin)
: sg_throwable(message, origin)
{
}
sg_error::sg_error(const std::string& message, const std::string& origin)
: sg_throwable(message.c_str(), origin.c_str())
{
}
sg_error::~sg_error ()
sg_error::sg_error(const std::string& message, const std::string& origin, bool report) noexcept
: sg_throwable(message.c_str(), origin.c_str(), {}, report)
{
}
@@ -198,121 +198,81 @@ sg_error::~sg_error ()
// Implementation of sg_exception class.
////////////////////////////////////////////////////////////////////////
sg_exception::sg_exception ()
: sg_throwable ()
{
}
sg_exception::sg_exception(const char* message, const char* origin,
const sg_location& loc, bool report) noexcept
: sg_throwable(message, origin, loc, report) {}
sg_exception::sg_exception(const char *message, const char *origin,
const sg_location &loc)
: sg_throwable(message, origin, loc) {}
sg_exception::sg_exception(const std::string& message,
const std::string& origin, const sg_location& loc,
bool report) noexcept
: sg_throwable(message.c_str(), origin.c_str(), loc, report) {}
sg_exception::sg_exception(const std::string &message,
const std::string &origin, const sg_location &loc)
: sg_throwable(message.c_str(), origin.c_str(), loc) {}
sg_exception::~sg_exception ()
{
}
////////////////////////////////////////////////////////////////////////
// Implementation of sg_io_exception.
////////////////////////////////////////////////////////////////////////
sg_io_exception::sg_io_exception ()
: sg_exception()
sg_io_exception::sg_io_exception(const char* message, const char* origin, bool report)
: sg_exception(message, origin, {}, report)
{
}
sg_io_exception::sg_io_exception (const char* message, const char* origin)
: sg_exception(message, origin)
sg_io_exception::sg_io_exception(const char* message,
const sg_location& location,
const char* origin,
bool report)
: sg_exception(message, origin, location, report) {}
sg_io_exception::sg_io_exception(const std::string& message,
const std::string& origin,
bool report)
: sg_exception(message, origin, {}, report)
{
}
sg_io_exception::sg_io_exception(const char *message,
const sg_location &location,
const char *origin)
: sg_exception(message, origin, location), _location(location) {}
sg_io_exception::sg_io_exception( const std::string& message,
const std::string& origin )
: sg_exception(message, origin)
{
}
sg_io_exception::sg_io_exception(const std::string &message,
const sg_location &location,
const std::string &origin)
: sg_exception(message, origin, location), _location(location) {}
sg_io_exception::~sg_io_exception ()
{
}
const std::string
sg_io_exception::getFormattedMessage () const
{
std::string ret = getMessage();
std::string loc = getLocation().asString();
if (loc.length()) {
ret += "\n at ";
ret += loc;
}
return ret;
}
const sg_location &
sg_io_exception::getLocation () const
{
return _location;
}
void
sg_io_exception::setLocation (const sg_location &location)
{
_location = location;
}
sg_io_exception::sg_io_exception(const std::string& message,
const sg_location& location,
const std::string& origin,
bool report)
: sg_exception(message, origin, location, report) {}
////////////////////////////////////////////////////////////////////////
// Implementation of sg_format_exception.
////////////////////////////////////////////////////////////////////////
sg_format_exception::sg_format_exception ()
: sg_exception()
sg_format_exception::sg_format_exception() noexcept
: sg_exception()
{
_text[0] = '\0';
}
sg_format_exception::sg_format_exception (const char* message,
const char* text,
const char* origin)
: sg_exception(message, origin)
sg_format_exception::sg_format_exception(const char* message,
const char* text,
const char* origin,
bool report)
: sg_exception(message, origin, {}, report)
{
setText(text);
}
sg_format_exception::sg_format_exception( const std::string& message,
const std::string& text,
const std::string& origin )
: sg_exception(message, origin)
sg_format_exception::sg_format_exception(const std::string& message,
const std::string& text,
const std::string& origin,
bool report)
: sg_exception(message, origin, {}, report)
{
setText(text.c_str());
}
sg_format_exception::~sg_format_exception ()
{
}
const char*
sg_format_exception::getText () const
sg_format_exception::getText() const noexcept
{
return _text;
}
void
sg_format_exception::setText (const char* text)
void sg_format_exception::setText(const char* text) noexcept
{
if (text) {
strncpy(_text, text, MAX_TEXT_LEN);
@@ -328,26 +288,19 @@ sg_format_exception::setText (const char* text)
// Implementation of sg_range_exception.
////////////////////////////////////////////////////////////////////////
sg_range_exception::sg_range_exception ()
: sg_exception()
{
}
sg_range_exception::sg_range_exception (const char* message,
const char* origin)
: sg_exception(message, origin)
sg_range_exception::sg_range_exception(const char* message,
const char* origin, bool report)
: sg_exception(message, origin, {}, report)
{
}
sg_range_exception::sg_range_exception(const std::string& message,
const std::string& origin)
: sg_exception(message, origin)
const std::string& origin,
bool report)
: sg_exception(message, origin, {}, report)
{
}
sg_range_exception::~sg_range_exception ()
{
}
////////////////////////////////////////////////////////////////////////

View File

@@ -28,23 +28,23 @@ class sg_location
{
public:
enum {max_path = 1024};
sg_location ();
sg_location(const std::string& path, int line = -1, int column = -1);
sg_location(const SGPath& path, int line = -1, int column = -1);
explicit sg_location(const char* path, int line = -1, int column = -1);
sg_location() noexcept;
sg_location(const std::string& path, int line = -1, int column = -1) noexcept;
sg_location(const SGPath& path, int line = -1, int column = -1) noexcept;
explicit sg_location(const char* path, int line = -1, int column = -1) noexcept;
~sg_location() = default;
const char *getPath() const;
int getLine() const;
int getColumn() const;
int getByte() const;
const char* getPath() const noexcept;
int getLine() const noexcept;
int getColumn() const noexcept;
int getByte() const noexcept;
std::string asString() const;
bool isValid() const;
std::string asString() const noexcept;
bool isValid() const noexcept;
private:
void setPath(const char *p);
private:
void setPath(const char* p) noexcept;
char _path[max_path];
int _line;
@@ -60,20 +60,26 @@ class sg_throwable : public std::exception
{
public:
enum {MAX_TEXT_LEN = 1024};
sg_throwable ();
sg_throwable(const char *message, const char *origin = 0,
const sg_location &loc = {});
sg_throwable() noexcept;
sg_throwable(const char* message, const char* origin = 0,
const sg_location& loc = {}, bool report = true) noexcept;
virtual ~sg_throwable ();
virtual const char* getMessage () const;
virtual const std::string getFormattedMessage () const;
virtual void setMessage (const char* message);
virtual const char* getOrigin () const;
virtual void setOrigin (const char *origin);
virtual ~sg_throwable() noexcept = default;
virtual const char* getMessage() const noexcept;
std::string getFormattedMessage() const noexcept;
virtual void setMessage(const char* message) noexcept;
virtual const char* getOrigin() const noexcept;
virtual void setOrigin(const char* origin) noexcept;
virtual const char* what() const noexcept;
private:
sg_location getLocation() const noexcept;
void setLocation(const sg_location& location) noexcept;
private:
char _message[MAX_TEXT_LEN];
char _origin[MAX_TEXT_LEN];
sg_location _location;
};
@@ -90,10 +96,10 @@ private:
class sg_error : public sg_throwable
{
public:
sg_error ();
sg_error (const char* message, const char* origin = 0);
sg_error(const std::string &message, const std::string &origin = {});
virtual ~sg_error ();
sg_error() noexcept = default;
sg_error(const char* message, const char* origin = 0, bool report = true) noexcept;
sg_error(const std::string& message, const std::string& origin = {}, bool report = true) noexcept;
virtual ~sg_error() noexcept = default;
};
@@ -114,12 +120,12 @@ public:
class sg_exception : public sg_throwable
{
public:
sg_exception ();
sg_exception(const char *message, const char *origin = 0,
const sg_location &loc = {});
sg_exception(const std::string &message, const std::string & = {},
const sg_location &loc = {});
virtual ~sg_exception ();
sg_exception() noexcept = default;
sg_exception(const char* message, const char* origin = 0,
const sg_location& loc = {}, bool report = true) noexcept;
sg_exception(const std::string& message, const std::string& = {},
const sg_location& loc = {}, bool report = true) noexcept;
virtual ~sg_exception() noexcept = default;
};
@@ -137,20 +143,15 @@ public:
class sg_io_exception : public sg_exception
{
public:
sg_io_exception ();
sg_io_exception (const char* message, const char* origin = 0);
sg_io_exception (const char* message, const sg_location &location,
const char* origin = 0);
sg_io_exception (const std::string &message, const std::string &origin = "");
sg_io_exception (const std::string &message, const sg_location &location,
const std::string &origin = "");
sg_io_exception() noexcept = default;
sg_io_exception(const char* message, const char* origin = 0, bool report = true);
sg_io_exception(const char* message, const sg_location& location,
const char* origin = 0, bool report = true);
sg_io_exception(const std::string& message, const std::string& origin = {}, bool report = true);
sg_io_exception(const std::string& message, const sg_location& location,
const std::string& origin = {}, bool report = true);
virtual ~sg_io_exception ();
virtual const std::string getFormattedMessage () const;
virtual const sg_location &getLocation () const;
virtual void setLocation (const sg_location &location);
private:
sg_location _location;
virtual ~sg_io_exception() noexcept = default;
};
@@ -168,14 +169,15 @@ private:
class sg_format_exception : public sg_exception
{
public:
sg_format_exception ();
sg_format_exception (const char* message, const char* text,
const char* origin = 0);
sg_format_exception (const std::string& message, const std::string& text,
const std::string& origin = "");
virtual ~sg_format_exception ();
virtual const char* getText () const;
virtual void setText (const char* text);
sg_format_exception() noexcept;
sg_format_exception(const char* message, const char* text,
const char* origin = 0, bool report = true);
sg_format_exception(const std::string& message, const std::string& text,
const std::string& origin = {}, bool report = true);
const char* getText() const noexcept;
void setText(const char* text) noexcept;
private:
char _text[MAX_TEXT_LEN];
};
@@ -193,12 +195,14 @@ private:
class sg_range_exception : public sg_exception
{
public:
sg_range_exception ();
sg_range_exception (const char* message,
const char* origin = 0);
sg_range_exception (const std::string& message,
const std::string& origin = "");
virtual ~sg_range_exception ();
sg_range_exception() noexcept = default;
sg_range_exception(const char* message,
const char* origin = 0,
bool report = true);
sg_range_exception(const std::string& message,
const std::string& origin = {},
bool report = true);
virtual ~sg_range_exception() noexcept = default;
};
using ThrowCallback = std::function<void(

View File

@@ -1 +1 @@
2020.3.7
2020.3.8