Beispiel #1
0
DOUBLE                            /*{ ret - sinhd(x)      }*/
sinhd
(
  DOUBLE x                        /*{ (i) - input value x }*/
)
{
    DOUBLE y, w, z;
    DOUBLE f, xnum, xden;
    DOUBLE result;
    DOUBLE sign = 1.0;

    /*{ y = |x| }*/
    y = x;
    /*{ sign = 1.0 }*/
    /*{ if x < 0, sign = -sign }*/
    if (x < (DOUBLE)0.0)
    {
        y = -y;
        sign = -sign;
    }

    /*{ if (y > 1.0) }*/
    if (y > (DOUBLE)1.0)
    {
        /*{ if (y > XDOUBLE_MAX_EXP) }*/
        if (y > XDOUBLE_MAX_EXP)
        {
            /*{ w = y - ln(v) }*/
            w = SUBD(y, LN_V);

            /*{ if w > XDOUBLE_MAX_EXP }*/
            if (w > XDOUBLE_MAX_EXP)
            {
                /*{ result = +1.7e308 }*/
                result = LDBL_MAX;
                /*{ if sign < 0, result = -result }*/
                if (sign < 0.0)
                {
                    result = -result;
                }
                /*{ return result }*/
                return result;
            }

            /*{ z = exp(w) }*/
            z = expd(w);

            /*{ result = (v/2) * z }*/
            /* using higher precision computation */
            result = MPYD(V_2_MINUS1, z);
            result = ADDD(result, z);
        }
        /*{ else y <= XDOUBLE_MAX_EXP }*/
        else
        {
            /*{ z = exp(y) }*/
            z = expd(y);

            /*{ result = ((z - 1 / z) / 2 }*/
            result = DIVD(-0.5, z);
            z = MPYD(0.5, z);
            result = ADDD(z, result);
        }

     }
    /*{ else y <= 1.0 }*/
    else
    {
        /*{ if y < eps, result = y }*/
        if (y < LDBL_EPSILON)
        {
            result = y;
        }
        else
        {
            /*{ result = y + y * R(x^2) }*/
            /*{!INDENT}*/
            /*{ R(f) = f*P(f)/Q(f) }*/

            /*{ f = x * x }*/
            f = MPYD(x, x);

            /*{ P(f) = ((p3 * f + p2) * f + p1) * f + p0 }*/
            xnum = MPYD(SINHDP_COEF3, f);
            xnum = ADDD(xnum, SINHDP_COEF2);
            xnum = MPYD(xnum, f);
            xnum = ADDD(xnum, SINHDP_COEF1);
            xnum = MPYD(xnum, f);
            xnum = ADDD(xnum, SINHDP_COEF0);

            /*{ Q(f) = ((f + q2) *f + q1) * f + q0 }*/
            xden = ADDD(f, SINHDQ_COEF2);
            xden = MPYD(xden, f);
            xden = ADDD(xden, SINHDQ_COEF1);
            xden = MPYD(xden, f);
            xden = ADDD(xden, SINHDQ_COEF0);
            /*{!OUTDENT}*/

            result = DIVD(xnum, xden);
            result = MPYD(result, f);
            result = MPYD(result, y);
            result = ADDD(result, y);
        }
    }

    /*{ if sign < 0, result = -result }*/
    if (sign < 0.0)
    {
        result = -result;
    }
 
    /*{ return result }*/
    return result;
}
Beispiel #2
0
DOUBLE                            /*{ ret - tanhd(x)      }*/
tanhd
(
  DOUBLE x                        /*{ (i) - input value x }*/
)
{
    DOUBLE f, g, xnum, xden;
    DOUBLE result;
    DOUBLE sign = 1.0;

    /*{ f = |x| }*/
    f = x;
    /*{ sign = 1 }*/
    /*{ if x < 0, sign = -sign }*/
    if (x < (DOUBLE)0.0)
    {
        f = -f;
        sign = -sign;
    }

    /*{ if f > TANHDOUBLE_BIGNUM, return sign }*/
    if (f > TANHDOUBLE_BIGNUM)
    {
        return sign;
    }

    /*{ if f > ln(3)/2 }*/
    if (f > LN3_2)
    {
        /*{ result = 1 - 2/(exp(2f) + 1) }*/
        result = ADDD(f, f);
        result = expd(result);
        result = ADDD(1.0, result);
        result = DIVD(2.0, result);
        result = SUBD(1.0, result);
    }
    /*{ else f <= ln(3)/2 }*/
    else
    {
        /*{ if f < EPS, return x }*/
        if (f < LDBL_EPSILON)
        {
            result = x;
            return result;
        }

        /*{ g = f * f }*/
        g = MPYD(f, f);

        /*{ R(g) = g * P(g)/Q(g) }*/
        /*{!INDENT}*/
        /*{ P(g) = (p2 * g + p1) * g + p0 }*/
        xnum = MPYD(TANHDP_COEF2, g);
        xnum = ADDD(xnum, TANHDP_COEF1);
        xnum = MPYD(xnum, g);
        xnum = ADDD(xnum, TANHDP_COEF0);

        /*{ Q(g) = ((g + q2) * g + q1) * g + q0 }*/
        xden = ADDD(TANHDQ_COEF2, g);
        xden = MPYD(xden, g);
        xden = ADDD(xden, TANHDQ_COEF1);
        xden = MPYD(xden, g);
        xden = ADDD(xden, TANHDQ_COEF0);
        /*{!OUTDENT}*/

        /*{ result = f + f * R(g) }*/
        result = DIVD(xnum, xden);
        result = MPYD(result, g);
        result = MPYD(result, f);
        result = ADDD(result, f);

    }

    /*{ if sign < 0, result = -result }*/
    if (sign < (DOUBLE)0.0)
    {
        result = -result;
    }

    /*{ return result }*/
    return result;
}
Beispiel #3
0
void do_c_map(int iwalker,
              int nrow, 
              int ncol, 
              float cenrow,
              float cencol,
              float idet,
              float irr,
              float irc,
              float icc,
              float *data, 
              float *image)
{
    for (int row=0; row<nrow; row++) {
        for (int col=0; col<ncol; col++) {

            float imval=image[row*ncol + col];

            int idx=iwalker*nrow*ncol + row*ncol + col;

            float u = row-cenrow;
            float v = col-cencol;
            float chi2=icc*u*u + irr*v*v - 2.0*irc*u*v;
            float tmp=0;
            chi2 *= idet;
            tmp = expd( -0.5*chi2 );

            u = row-1.1*cenrow;
            v = col-1.1*cencol;
            chi2=1.01*icc*u*u + 0.98*irr*v*v - .999*2.0*irc*u*v;
            chi2 *= idet;
            tmp += expd( -0.5*chi2 );

            u = row-0.99*cenrow;
            v = col-0.99*cencol;
            chi2=1.1*icc*u*u + .979*irr*v*v - 1.001*2.0*irc*u*v;
            chi2 *= idet;
            tmp += expd( -0.5*chi2 );

            u = row-0.97*cenrow;
            v = col-0.93*cencol;
            chi2=1.1*icc*u*u + .979*irr*v*v - 1.001*2.0*irc*u*v;
            chi2 *= idet;
            tmp += expd( -0.5*chi2 );

 
            u = row-1.01*cenrow;
            v = col-1.03*cencol;
            chi2=1.1*icc*u*u + .979*irr*v*v - 1.001*2.0*irc*u*v;
            chi2 *= idet;
            tmp += expd( -0.5*chi2 );


            u = row-0.9991*cenrow;
            v = col-1.0009*cencol;
            chi2=1.1*icc*u*u + .979*irr*v*v - 1.001*2.0*irc*u*v;
            chi2 *= idet;
            tmp += expd( -0.5*chi2 );

            u = row-0.983*cenrow;
            v = col-1.31*cencol;
            chi2=1.1*icc*u*u + .979*irr*v*v - 1.001*2.0*irc*u*v;
            chi2 *= idet;
            tmp += expd( -0.5*chi2 );

            u = row-0.993*cenrow;
            v = col-0.99999*cencol;
            chi2=1.1*icc*u*u + .979*irr*v*v - 1.001*2.0*irc*u*v;
            chi2 *= idet;
            tmp += expd( -0.5*chi2 );

            u = row-1.11*cenrow;
            v = col-1.14*cencol;
            chi2=1.1*icc*u*u + .979*irr*v*v - 1.001*2.0*irc*u*v;
            chi2 *= idet;
            tmp += expd( -0.5*chi2 );

            u = row-0.975*cenrow;
            v = col-1.00*cencol;
            chi2=1.1*icc*u*u + .979*irr*v*v - 1.001*2.0*irc*u*v;
            chi2 *= idet;
            tmp += expd( -0.5*chi2 );

            tmp = tmp-imval;
            data[idx] = -0.5*tmp*tmp;

        }
    }
}
Beispiel #4
0
void calculate(double *photoperiod,
	       double *mean_air_temp,
	       double *daily_precipitation,
	       double *popdens,
	       double *param,
	       double *n0,
	       double *n10,
	       double *n1,
	       double *n2,
	       double *n3,
	       double *n4fj,
	       double *n4f,
	       double *nBS,
	       double *K,
	       double *d4,
	       double *d4s,
	       double *F4,
	       double *egg,
	       double *percent_strong,
	       int    TIME) {
  double par[2];

  if (TIME==-1) {
    (*n0) = param[alpha_dp_egg];
    (*n10) = 0.0;
    (*n1) = param[alpha_0];
    (*n2) = param[alpha_1];
    (*n3) = param[alpha_2];
    (*n4fj) = 0.0;
    (*n4f) = param[alpha_3];
    (*nBS) = 0.0;
    (*K) = 0.0;
    (*d4) = 0.0;
    (*d4s) = 0.0;
    (*F4) = 0.0;
    (*egg) = (*n0) + (*n10) + (*n1);
    (*percent_strong) = 0.0;

    if ((*n10) > 0) incubator_add(&conn10,(*n10),0.0);
    if ((*n1) > 0) incubator_add(&conn1,(*n1),0.0);
    if ((*n2) > 0) incubator_add(&conn2,(*n2),0.0);
    if ((*n3) > 0) incubator_add(&conn3,(*n3),0.0);
    if ((*n4f) > 0) incubator_add(&conn4,(*n4f),0.0);

    return;
  }

  // ---------------------
  // modelDelayAalbopictus
  // ---------------------

  double deltaT = param[alpha_deltaT];

  double Ta = mean_air_temp[TIME];
  
  double Tw = Ta+deltaT;

  // Number of breeding sites
  (*nBS) = param[alpha_BS_pdens]*(*popdens) + param[alpha_BS_dprec]*daily_precipitation[TIME] + param[alpha_BS_nevap]*(*nBS);
  (*K) = param[alpha_BS_nevap]==1.0 ? (*nBS)/(TIME+1.0) : (*nBS)*(param[alpha_BS_nevap]-1.0)/(pow(param[alpha_BS_nevap],(TIME+1))-1.0);

  // Density of the immature stages
  // Assume uniform distribution across all breeding sites
  double n23dens = ((incubator_sum(conn2)+incubator_sum(conn3))/(*K));

  // Fecundity
  double bigF4 = poly(Ta,param[alpha_F4_1],param[alpha_F4_2],param[alpha_F4_3]);
  (*F4) = bigF4;

  double densd = expd(n23dens,param[alpha_n23_surv]);
  // Egg survival (diapausing eggs)
  double p0_Ta  = flin(Ta,param[alpha_p0_1],param[alpha_p0_2]);
  // Egg survival (non-diapausing eggs)
  double p1_Tw = dsig(Tw,param[alpha_p1_1],param[alpha_p1_2],param[alpha_p1_3]);
  // Larval survival
  double p2_Tw = dsig(Tw,param[alpha_p2_1],param[alpha_p2_2],param[alpha_p2_3])*densd;
  // Pupal survival
  double p3_Tw = dsig(Tw,param[alpha_p3_1],param[alpha_p3_2],param[alpha_p3_3])*densd;

  double densdev = fpow(n23dens,param[alpha_n23_1],param[alpha_n23_2]*poly(Tw,param[alpha_n23_3],param[alpha_n23_4],param[alpha_n23_5]));
  // Egg development time
  double d1 = poly(Tw,param[alpha_d1_1],param[alpha_d1_2],param[alpha_d1_3]);
  // Larval development time
  double d2 = poly(Tw,param[alpha_d2_1],param[alpha_d2_2],param[alpha_d2_3])*densdev;
  // Pupal development time
  double d3 = poly(Tw,param[alpha_d3_1],param[alpha_d3_2],param[alpha_d3_3])*densdev;
  // Time to first blood meal
  double alpha_blood = poly(Ta,param[alpha_tbm_1],param[alpha_tbm_2],param[alpha_tbm_3]);
  // Adult lifetime (from emergence)
  double dd4 = dsig2(Ta,param[alpha_d4_1],param[alpha_d4_2],param[alpha_d4_3]);
  double dd4s = gamma_matrix_sd*dd4;
  (*d4) = dd4;
  (*d4s) = dd4s;

  // Update development times and survival proportions
  // of the immature stages and juvenile adults
  //
  // Diapausing eggs
  (*n0) = p0_Ta*(*n0);
  //
  // Normal and tagged eggs
  par[0] = p1_Tw; par[1] = 1.0/max(1.0,d1);
  incubator_update(conn1,update,par);
  incubator_update(conn10,update,par);
  //
  // Larvae
  par[0] = p2_Tw; par[1] = 1.0/max(1.0,d2);
  incubator_update(conn2,update,par);
  //
  // Pupae
  par[0] = p3_Tw; par[1] = 1.0/max(1.0,d3);
  incubator_update(conn3,update,par);
  //
  // Adult females
  incubator_develop_survive(&conn4,-1,0,dd4,dd4s,alpha_blood,n4fj,n4f,0,gamma_mode);
  //
  // Check if it is winter or summer
  char short_days = photoperiod[TIME] < param[alpha_dp_thr];
  char cold_days = Ta < param[alpha_ta_thr];
  //
  // Lay eggs
  (*egg) = bigF4*(*n4f); // Total number of eggs that will be laid that day
  double hatch = 0;
  //
  if (short_days && cold_days) { // DIAPAUSE
    // The fraction of tagged eggs increases linearly
    (*percent_strong) = min(1.0,(*percent_strong)+param[alpha_rate_strong]);
    //
    incubator_add(&conn10,bigF4*(*n4f)*(*percent_strong),0.0); // Tagged eggs
    incubator_add(&conn1,bigF4*(*n4f)*(1.0-(*percent_strong)),0.0); // Normal eggs
    //
  } else { // NO DIAPAUSE
    if (!short_days && !cold_days) { // EXIT FROM DIAPAUSE
      // Prepare diapausing eggs for hatching
      double vn0_n10 = (*n0)*param[alpha_rate_normal];
      (*n0) -= vn0_n10; // Diapausing eggs
      hatch += vn0_n10; // Eggs to hatch
    }
    // Lay normal eggs
    incubator_add(&conn1,bigF4*(*n4f),0.0); // Normal eggs
    //
    (*percent_strong) = 0.0;
  }
  // Develop
  double nn1;
  double nn2;
  double nn3;
  incubator_remove(&conn3,&nn3);
  incubator_remove(&conn2,&nn2); incubator_add(&conn3,nn2,0.0);
  incubator_remove(&conn1,&nn1); hatch += nn1;
  // Harvest developed tagged eggs
  double vn10_hn0;
  incubator_remove(&conn10,&vn10_hn0);
  // Tagged eggs always become diapausing eggs
  (*n0) = (*n0) + vn10_hn0;
  // All eggs, which are ready to hatch, become larvae
  incubator_add(&conn2,hatch,0.0);
  //
  // Update immature stage counts
  (*n3) = incubator_sum(conn3);
  (*n2) = incubator_sum(conn2);
  (*n1) = incubator_sum(conn1) + incubator_sum(conn10);
  //
  // Add newly developed females to adults
  nn3 *= 0.5;
  incubator_add(&conn4,nn3,0.0);
  (*n4f) += nn3;
}
Beispiel #5
0
bool assemblekeybif(char *fname, uint8 **mem, uint32 *size)
{
	int pr;
	std::string bfname, rfname, resref;
	std::vector<uint8 *> datas;
	uint16 drives=0;
	uint32 asize;
	uint64 tmp;
	NWNFileType restype=NWN_FILE_UNDEFINED;
	bool newbif=true, withCd=false, exploded=false;
	XMLFile xml;
	KEYFile key;
	BIFFile bif;

	if(xml.open(fname))
	{
		std::cerr << "Error opening file \"" << fname << "\": ";
		std::cerr << xml.getStrError() << "\n";
		return false;
	}
	while((pr = xml.parse()) >= 0)
	{
		switch(pr)
		{
			case 0:
				if(!mem && (xml.section == ".key.filename"))
					key.filename = xml.value;
				else if(xml.section == ".key.filetype")
				{
					if((key.type = key.getFileResTypeByExt(xml.value)) == -1)
						return printxmlerr(xml, "Unknown filetype");
					if(!key.typeIsCorrect()) return printxmlerr(xml, "No KEY type");
				}
				else if(xml.section == ".key.buildyear")
				{
					sscanf(xml.value.c_str(), S_UINT64, &tmp);
					key.buildyear = (uint32) (tmp - 1900);
				}
				else if(xml.section == ".key.buildday")
				{
					sscanf(xml.value.c_str(), S_UINT64, &tmp);
					key.buildday = (uint32) tmp;
				}
				else if(xml.section == ".key.bif.filename")
					bfname = xml.value;
				else if(xml.section == ".key.bif.drives")
				{
					sscanf(xml.value.c_str(), S_UINT64, &tmp);
					drives = (uint16) tmp;
				}
				else if(xml.section == ".key.bif.variable.resource.resref")
					resref = xml.value;
				else if(xml.section == ".key.bif.variable.resource.filename")
					rfname = xml.value;
				else if(xml.section == ".key.bif.variable.resource.restype")
				{
					if((restype = key.getFileResTypeByExt(xml.value)) == -1)
						return printxmlerr(xml, "Unknown filetype");
				}
				else if(xml.section == ".key.bif.variable.resource.withCd")
				{
					sscanf(xml.value.c_str(), S_UINT64, &tmp);
					withCd = (bool) tmp;
				}
				else if(xml.section == ".key.bif.variable.resource.exploded")
				{
					sscanf(xml.value.c_str(), S_UINT64, &tmp);
					exploded = (bool) tmp;
				}
				break;
			case 1:
				if(xml.section == ".bif.fixed")
					return printxmlerr(xml, "Fixed resources aren't supported");
				else if((xml.section != ".?xml") && (xml.section != ".key") &&
				   (getpos(validkeybiftags, KEYBIFTAGS, xml.section) == -1))
					return printxmlerr(xml, "Invalid tag");
				break;
			case 2:
				if(xml.value == ".key.bif")
				{
					bfname = bif.filename;
					if(bif.endwrite()) return printxmlerr(xml, bif.getStrError());
					if(bif.open(bfname)) return printxmlerr(xml, bif.getStrError());
					key.fsizes[key.bifcount-1] = bif.getFileSize();
					bif.deInit();
					newbif = true;
					bfname.clear();
					drives = 0;
				}
				else if(xml.value == ".key.bif.variable.resource")
				{
					if(newbif)
					{
						if(bfname.empty()) return printxmlerr(xml, "Missing filename");
						if(key.addBif(bfname, drives, 0))
							return printxmlerr(xml, key.getStrError());
						if(bif.beginWrite(getbasename((char*)bfname.c_str())))
							return printxmlerr(xml, bif.getStrError());
						bif.type = NWN_FILE_BIF;
						newbif = false;
					}
					if(resref.empty()) return printxmlerr(xml, "Missing resref");
					if(rfname.empty()) return printxmlerr(xml, "Missing filename");
					if(restype == NWN_FILE_UNDEFINED)
						return printxmlerr(xml, "Missing restype");
					if(exploded)
					{
						datas.resize((tmp=datas.size())+1);
						if(!(datas[tmp] = expd(xml, bif.getBaseType(restype), rfname, asize)))
							return false;
						if(bif.writeData(restype, withCd, true, datas[tmp], asize, false))
							return printxmlerr(xml, bif.getStrError());
					}
					else
						if(bif.writeData(restype, withCd, true, rfname))
							return printxmlerr(xml, bif.getStrError());
					if(key.addResource(key.bifcount-1, resref, restype, bif.vrescount-1))
						return printxmlerr(xml, key.getStrError());
					resref.clear();
					rfname.clear();
					restype = NWN_FILE_UNDEFINED;
					withCd = exploded = false;
				}
				break;
		}
	}
	if(pr != -6) return printxmlerr(xml, xml.getStrError());

	xml.close();
	if(!mem)
	{
		if(key.filename.empty()) return printxmlerr(xml, "Missing filename");
		else if(key.write(key.filename)) return printnwnerr(key);
	}
	else if(key.write(mem, size)) return printnwnerr(key);
	for(uint32 i=0;i<datas.size();i++) free(datas[i]);
	return true;
}
Beispiel #6
0
bool assemblebif(char *fname, uint8 **mem, uint32 *size)
{
	int pr;
	uint32 asize;
	uint64 tmp;
	std::vector<uint8 *> datas;
	std::string filename;
	bool opened=false, exploded=false, withCd=false;
	NWNFileType restype=NWN_FILE_UNDEFINED;
	XMLFile xml;
	BIFFile bif;

	if(xml.open(fname))
	{
		std::cerr << "Error opening file \"" << fname << "\": ";
		std::cerr << xml.getStrError() << "\n";
		return false;
	}
	while((pr = xml.parse()) >= 0)
	{
		switch(pr)
		{
			case 0:
				if(!mem && (xml.section == ".bif.filename"))
				{
					if(bif.beginWrite(xml.value))
						return printxmlerr(xml, bif.getStrError());
				}
				else if(xml.section == ".bif.filetype")
				{
					if((bif.type = bif.getFileResTypeByExt(xml.value)) == -1)
						return printxmlerr(xml, "Unknown filetype");
					if(!bif.typeIsCorrect()) return printxmlerr(xml, "No BIF type");
				}
				else if(xml.section == ".bif.variable.resource.filename")
					filename = xml.value;
				else if(xml.section == ".bif.variable.resource.restype")
				{
					if((restype = bif.getFileResTypeByExt(xml.value)) == -1)
						return printxmlerr(xml, "Unknown filetype");
				}
				else if(xml.section == ".bif.variable.resource.exploded")
				{
					sscanf(xml.value.c_str(), S_UINT64, &tmp);
					exploded = (bool) tmp;
				}
				else if(xml.section == ".bif.variable.resource.withCd")
				{
					sscanf(xml.value.c_str(), S_UINT64, &tmp);
					withCd = (bool) tmp;
				}
				break;
			case 1:
				if(xml.section == ".bif.fixed")
					return printxmlerr(xml, "Fixed resources aren't supported");
				else if((xml.section != ".?xml") && (xml.section != ".bif") &&
				        (getpos(validbiftags, BIFTAGS, xml.section) == -1))
					return printxmlerr(xml, "Invalid tag");
				break;
			case 2:
				if(xml.value == ".bif.variable.resource")
				{
					if(!opened)
					{
						if(!mem)
						{
							if(bif.filename.empty())
								return printxmlerr(xml, "Missing filename");
						}
						else
							if(bif.beginWrite()) return printxmlerr(xml, bif.getStrError());
						opened = true;
					}
					if(filename.empty()) return printxmlerr(xml, "Missing filename");
					if(restype == NWN_FILE_UNDEFINED)
						return printxmlerr(xml, "Missing restype");
					if(exploded)
					{
						datas.resize((tmp=datas.size())+1);
						if(!(datas[tmp] = expd(xml, bif.getBaseType(restype), filename, asize)))
							return false;
						if(bif.writeData(restype, withCd, true, datas[tmp], asize, false))
							return printxmlerr(xml, bif.getStrError());
					}
					else
						if(bif.writeData(restype, withCd, true, filename))
							return printxmlerr(xml, bif.getStrError());
					filename.clear();
					exploded = withCd = false;
					restype=NWN_FILE_UNDEFINED;
				}
				break;
		}
	}
	if(pr != -6) return printxmlerr(xml, xml.getStrError());

	xml.close();
	if(bif.endwrite(mem, size)) return printxmlerr(xml, bif.getStrError());
	for(uint32 i=0;i<datas.size();i++) free(datas[i]);
	return true;
}
Beispiel #7
0
bool assembleerf(char *fname, uint8 **mem, uint32 *size)
{
	int pr;
	uint32 asize;
	uint64 tmp;
	std::vector<uint8 *> datas;
	bool opened=false, exploded=false;
	std::string resref, filename;
	NWNFileType restype=NWN_FILE_UNDEFINED;
	XMLFile xml;
	ERFFile erf;

	if(xml.open(fname))
	{
		std::cerr << "Error opening file \"" << fname << "\": ";
		std::cerr << xml.getStrError() << "\n";
		return false;
	}
	while((pr = xml.parse()) >= 0)
	{
		switch(pr)
		{
			case 0:
				if(!mem && (xml.section == ".erf.filename"))
				{
					if(erf.beginWrite(xml.value))
						return printxmlerr(xml, erf.getStrError());
				}
				else if(xml.section == ".erf.filetype")
				{
					if((erf.type = erf.getFileResTypeByExt(xml.value)) == -1)
						return printxmlerr(xml, "Unknown filetype");
					if(!erf.typeIsCorrect()) return printxmlerr(xml, "No ERF type");
				}
				else if(xml.section == ".erf.buildyear")
				{
					sscanf(xml.value.c_str(), S_UINT64, &tmp);
					erf.buildyear = (uint32) (tmp - 1900);
				}
				else if(xml.section == ".erf.buildday")
				{
					sscanf(xml.value.c_str(), S_UINT64, &tmp);
					erf.buildday = (uint32) tmp;
				}
				else if(xml.section == ".erf.resource.resref")
					resref = xml.value;
				else if(xml.section == ".erf.resource.filename")
					filename = xml.value;
				else if(xml.section == ".erf.resource.restype")
				{
					if((restype = erf.getFileResTypeByExt(xml.value)) == -1)
						return printxmlerr(xml, "Unknown filetype");
				}
				else if(xml.section == ".erf.resource.exploded")
				{
					sscanf(xml.value.c_str(), S_UINT64, &tmp);
					exploded = (bool) tmp;
				}
				break;
			case 1:
				if(xml.section == ".erf.description") {
					if(!assembleerfdesc(xml, erf)) return false;
				} else if((xml.section != ".?xml") && (xml.section != ".erf") &&
				        (getpos(validerftags, ERFTAGS, xml.section) == -1))
					return printxmlerr(xml, "Invalid tag");
				break;
			case 2:
				if(xml.value == ".erf.resource")
				{
					if(!opened)
					{
						if(!mem)
						{
							if(erf.filename.empty())
								return printxmlerr(xml, "Missing filename");
						}
						else
							if(erf.beginWrite()) return printxmlerr(xml, erf.getStrError());
						opened = true;
					}
					if(resref.empty()) return printxmlerr(xml, "Missing resref");
					if(filename.empty()) return printxmlerr(xml, "Missing filename");
					if(restype == NWN_FILE_UNDEFINED)
						return printxmlerr(xml, "Missing restype");
					if(exploded)
					{
						datas.resize((tmp=datas.size())+1);
						if(!(datas[tmp] = expd(xml, erf.getBaseType(restype), filename, asize)))
							return false;
						if(erf.writeData(resref, restype, datas[tmp], asize, false))
							return printxmlerr(xml, erf.getStrError());
					}
					else
						if(erf.writeData(resref, restype, filename))
							return printxmlerr(xml, erf.getStrError());
					resref.clear();
					filename.clear();
					exploded = false;
					restype=NWN_FILE_UNDEFINED;
				}
				break;
		}
	}
	if(pr != -6) return printxmlerr(xml, xml.getStrError());

	xml.close();
	if(erf.endwrite(mem, size)) return printxmlerr(xml, erf.getStrError());
	for(uint32 i=0;i<datas.size();i++) free(datas[i]);
	return true;
}