bool PerlValue::isInt() const // line 1
{ return SvIOK(value); }
int PerlValue::Int() const // line 4
{
if (SvIOK(value) || SvNOK(value) || SvPOK(value)) {
return SvIV(value);
} else if (exception_flags & PerlStream::eBadCast) {
string errstr = string("Casting from a Perl ") + typeStr() +
" to an int";
throw PerlBadCast(errstr);
}
return 0; // Not a valid value, so make it 0
}
// ... Lots of other PerlValue functions
PerlStreamBuf::PerlStreamBuf(unsigned int flags)
: streambuf(), mContext(eScalar), mExceptionFlags(flags) {}
PerlStreamBuf::~PerlStreamBuf()
{ freePerlValues(); }
int PerlStreamBuf::overflow(int c) // line 23
{ mBuffer += static_cast<char>(c); return c; }
streamsize PerlStreamBuf::xsputn(const char* s, streamsize n) // line 26
{ mBuffer.append(s, n); return n; }
bool PerlStreamBuf::execute() // line 29
{
string err;
dSP;
I32 ax;
freePerlValues(); // Free values from the previous eval
if (mBuffer.length() == 0) return true;
ENTER;
SAVETMPS;
PUSHMARK(sp);
// Create the string we want to send to Perl, and send it
sv_setsv(ERRSV, &PL_sv_undef);
PUTBACK;
SV *code = sv_2mortal(newSVpv(mBuffer.data(),mBuffer.size()));
I32 nstackvals = perl_eval_sv(code, mContext|G_KEEPERR);
// Now get the response
SPAGAIN;
if (SvTRUE(ERRSV)) {
err = "Eval failed: " + mBuffer + ": " + SvPV(ERRSV, PL_na);
for (I32 i = 0; i < nstackvals; ++i)
POPs;
} else {
// Get the return values from the Perl stack.
mRtnVals.resize(nstackvals);
for (I32 i = nstackvals-1; i >= 0; --i) {
SV* val = POPs;
SvREFCNT_inc(val);
mRtnVals[i] = val;
}
}
PUTBACK;
FREETMPS;
LEAVE;
// Initialize things for the next go around
mBuffer.erase();
mContext = eScalar;
if (!errstr.empty()) {
if (mExceptionFlags & PerlStream::eEvalFail)
throw PerlEvalError(err);
return false;
} else {
return true;
}
}
void PerlStreamBuf::freePerlValues()
{
vector<SV*>::iterator p;
for (p = mRtnVals.begin(); p != mRtnVals.end(); ++p)
if (*p) { SvREFCNT_dec(*p); *p = 0; }
mRtnVals.clear();
}
End of Listing