Listing 3: PerlStream.h

class PerlEvalError: public exception {
private:
    string errstr;

public:
    PerlEvalError(const string& _errstr) : errstr(_errstr) {}
    virtual ~PerlEvalError() {}
    virtual const char* what() const { return errstr.c_str(); }
};
// ... other exception classes

class PerlValue { // line 12
public:
  class ptr;            // return for array_iter.operator->()
  class hash_value_ptr; // return for hash_iter.operator->()
  class array_iter;     // iterator over a Perl array
  class hash_iter;      // iterator over a Perl hash

private:
  SV* value;
  unsigned int exception_flags;

public:
  // A constructor
  PerlValue(SV* _value, unsigned int flags=0)
    : value(_value), exception_flags(flags) {}

  // Functions to get info about the object
  bool isInt() const;
  // ...

  // Conversion operators
  int Int() const;
  operator int() const { return Int(); }
  // ...
  
  // Access arrays and hashes
  PerlValue operator[](int array_index) const;
  PerlValue operator[](const char* hash_key) const;
  PerlValue operator[](const string& hash_key) const;

  // Functions for iterating over arrays and hashes
  array_iter array_begin() const;
  array_iter array_end() const;
  hash_iter hash_begin() const;
  hash_iter hash_end() const;
};
    
class PerlValue::ptr {
private:
  PerlValue value;

public:
  ptr(const PerlValue& _value) : value(_value) {}
  PerlValue* operator->() { return &value; }
};

class PerlValue::hash_value_ptr {
private:
  pair<string,PerlValue> value;
  // ... just like PerlValue::ptr
};

class PerlValue::array_iter {
  // ...
  PerlValue operator*() const;
  PerlValue::ptr operator->() const {return ptr(operator*());
  // ...
};

class PerlValue::hash_iter {
  // ...
  pair<string,PerlValue> operator*() const;
  hash_value_ptr operator->() const
  {return hash_value_ptr(operator*());
  // ...
};
class PerlStreamBuf : public streambuf {
private:
  vector<SV*> mRtnVals;
  string mBuffer;
  unsigned int mContext;
  unsigned int mExceptionFlags;

public:
  PerlStreamBuf(unsigned int exception_flags);
  virtual int overflow(int c);
  virtual streamsize xsputn(const char* s, streamsize nchars);
  bool execute();
  PerlValue operator[](int index);
  // ...
private:
  void freePerlValues();
};

class PerlStream : public ostream { // line 96
protected:
  PerlStreamBuf buf;

public:
  enum {eEvalFail=0x01, eBadCast=0x02, eArrayOutOfBounds=0x04,
    eHashOutOfBounds=0x08, eAll=~0};
  PerlStream(unsigned int flags=0): ostream(&buf), buf(flags) {}
  // ... wrappers around PerlStreamBuf
};

inline ostream& perl_execute(ostream& o) // line 107
{
  PerlStream* pso = dynamic_cast<PerlStream*>(&o);
  if (pso) return pso->execute();
  else     return o;  // do nothing if used on another ostream
}
— End of Listing —