// ---------------------------------------------------------------------------
// - Importer.cpp -
// - afnix:sps module - sps objects importer class implementation -
// ---------------------------------------------------------------------------
// - This program is free software; you can redistribute it and/or modify -
// - it provided that this copyright notice is kept intact. -
// - -
// - This program is distributed in the hope that it will be useful, but -
// - without any warranty; without even the implied warranty of -
// - merchantability or fitness for a particular purpose. In no event shall -
// - the copyright holder be liable for any direct, indirect, incidental or -
// - special damages arising in any way out of the use of this software. -
// ---------------------------------------------------------------------------
// - copyright (c) 1999-2007 amaury darsch -
// ---------------------------------------------------------------------------
#include "Reader.hpp"
#include "Importer.hpp"
#include "Runnable.hpp"
#include "QuarkZone.hpp"
namespace afnix {
// -------------------------------------------------------------------------
// - class section (record importer) -
// -------------------------------------------------------------------------
// create a default record importer
Recording::Recording (void) {
p_ircd = nilp;
setrcd (new Record);
}
// create a record importer with a record
Recording::Recording (Record* rcd) {
p_ircd = nilp;
setrcd (rcd);
}
// destroy this record importer
Recording::~Recording (void) {
Object::dref (p_ircd);
}
// return the object name
String Recording::repr (void) const {
return "Recording";
}
// return the importation record
Record* Recording::getrcd (void) const {
rdlock ();
Record* result = p_ircd;
unlock ();
return result;
}
// set the record to import
void Recording::setrcd (Record* rcd) {
wrlock ();
Object::dref (p_ircd);
Object::iref (p_ircd = rcd);
unlock ();
}
// import a list of literal into the record
void Recording::import (Cons* cons) {
if (cons == nilp) return;
wrlock ();
try {
// iterate in the cons cell
while (cons != nilp) {
// get the object and reduce it
Object* car = cons->getcar ();
Object* obj = (car == nilp) ? nilp : car->mini ();
p_ircd->add (obj);
cons = cons->getcdr ();
}
} catch (...) {
unlock ();
throw;
}
}
// import stream data into the record
void Recording::import (Input* is) {
if (is == nilp) return;
wrlock ();
// create a new reader
Reader rd (is);
wrlock ();
Form* form = nilp;
try {
// parse with the reader
while (true) {
form = rd.parse ();
if (form == nilp) break;
import (form);
}
} catch (Exception& e) {
if (form == nilp) {
e.setlnum (rd.getlnum ());
} else {
e.setlnum (form->getlnum ());
Object::cref (form);
}
unlock ();
throw;
} catch (...) {
unlock ();
throw;
}
}
// -------------------------------------------------------------------------
// - object section (record importer) -
// -------------------------------------------------------------------------
// the quark zone
static const long QUARK_RZON_LENGTH = 3;
static QuarkZone rzon (QUARK_RZON_LENGTH);
// the object supported quarks
static const long QUARK_SETRCD = rzon.intern ("set-record");
static const long QUARK_GETRCD = rzon.intern ("get-record");
static const long QUARK_RIMPORT = rzon.intern ("import");
// create a new object in a generic way
Object* Recording::mknew (Vector* argv) {
// get number of arguments
long argc = (argv == nilp) ? 0 : argv->length ();
// check for 0 argument
if (argc == 0) return new Recording;
// check for 1 argument
if (argc == 1) {
Object* obj = argv->get (0);
Record* rcd = dynamic_cast <Record*> (obj);
if (rcd != nilp) {
return new Recording (rcd);
}
throw Exception ("type-error", "invalid argument with record import");
}
throw Exception ("argument-error", "too many argument with record import");
}
// return true if the given quark is defined
bool Recording::isquark (const long quark, const bool hflg) const {
rdlock ();
if (rzon.exists (quark) == true) {
unlock ();
return true;
}
bool result = hflg ? Object::isquark (quark, hflg) : false;
unlock ();
return result;
}
// apply this object with a set of arguments and a quark
Object* Recording::apply (Runnable* robj, Nameset* nset, const long quark,
Vector* argv) {
// get the number of arguments
long argc = (argv == nilp) ? 0 : argv->length ();
// dispatch 0 argument
if (argc == 0) {
if (quark == QUARK_GETRCD) {
rdlock ();
Record* rcd = getrcd ();
robj->post (rcd);
unlock ();
return rcd;
}
}
// dispatch 1 argument
if (argc == 1) {
if (quark == QUARK_SETRCD) {
Object* obj = argv->get (0);
Record* rcd = dynamic_cast <Record*> (obj);
if (rcd == nilp)
throw Exception ("type-error", "invalid object for set-record ",
Object::repr (obj));
setrcd (rcd);
return nilp;
}
if (quark == QUARK_RIMPORT) {
Object* obj = argv->get (0);
// check for an input stream
Input* is = dynamic_cast <Input*> (obj);
if (is != nilp) {
import (is);
return nilp;
}
// check for a cons cell
Cons* cons = dynamic_cast <Cons*> (obj);
if (cons != nilp) {
import (cons);
return nilp;
}
throw Exception ("type-error", "invalid object for import ",
Object::repr (obj));
}
}
// call the object method
return Object::apply (robj, nset, quark, argv);
}
// -------------------------------------------------------------------------
// - object section (sheet importer) -
// -------------------------------------------------------------------------
// create a default sheet importer
Sheeting::Sheeting (void) {
p_isht = nilp;
setsht (new Sheet);
}
// create a sheet importer with a sheet
Sheeting::Sheeting (Sheet* rcd) {
p_isht = nilp;
setsht (rcd);
}
// destroy this sheet importer
Sheeting::~Sheeting (void) {
Object::dref (p_isht);
}
// return the object name
String Sheeting::repr (void) const {
return "Sheeting";
}
// return the importation sheet
Sheet* Sheeting::getsht (void) const {
rdlock ();
Sheet* result = p_isht;
unlock ();
return result;
}
// set the sheet to import
void Sheeting::setsht (Sheet* sht) {
wrlock ();
Object::dref (p_isht);
Object::iref (p_isht = sht);
unlock ();
}
// import a list of literal into the sheet
void Sheeting::import (Cons* cons) {
if (cons == nilp) return;
wrlock ();
Record* rcd = new Record;
try {
// iterate in the cons cell
while (cons != nilp) {
// get the object and reduce it
Object* car = cons->getcar ();
Object* obj = (car == nilp) ? nilp : car->mini ();
rcd->add (obj);
cons = cons->getcdr ();
}
p_isht->add (rcd);
} catch (...) {
Object::cref (rcd);
unlock ();
throw;
}
}
// import stream data into the sheet
void Sheeting::import (Input* is) {
if (is == nilp) return;
wrlock ();
// create a new reader
Reader rd (is);
wrlock ();
Form* form = nilp;
try {
// parse with the reader
while (true) {
form = rd.parse ();
if (form == nilp) break;
import (form);
}
} catch (Exception& e) {
if (form == nilp) {
e.setlnum (rd.getlnum ());
} else {
e.setlnum (form->getlnum ());
Object::cref (form);
}
unlock ();
throw;
} catch (...) {
unlock ();
throw;
}
}
// -------------------------------------------------------------------------
// - object section (sheet importer) -
// -------------------------------------------------------------------------
// the quark zone
static const long QUARK_SZON_LENGTH = 3;
static QuarkZone szon (QUARK_SZON_LENGTH);
// the object supported quarks
static const long QUARK_SETSHT = szon.intern ("set-sheet");
static const long QUARK_GETSHT = szon.intern ("get-sheet");
static const long QUARK_SIMPORT = szon.intern ("import");
// create a new object in a generic way
Object* Sheeting::mknew (Vector* argv) {
// get number of arguments
long argc = (argv == nilp) ? 0 : argv->length ();
// check for 0 argument
if (argc == 0) return new Sheeting;
// check for 1 argument
if (argc == 1) {
Object* obj = argv->get (0);
Sheet* sht = dynamic_cast <Sheet*> (obj);
if (sht != nilp) {
return new Sheeting (sht);
}
throw Exception ("type-error", "invalid argument with sheet import");
}
throw Exception ("argument-error", "too many argument with sheet import");
}
// return true if the given quark is defined
bool Sheeting::isquark (const long quark, const bool hflg) const {
rdlock ();
if (szon.exists (quark) == true) {
unlock ();
return true;
}
bool result = hflg ? Object::isquark (quark, hflg) : false;
unlock ();
return result;
}
// apply this object with a set of arguments and a quark
Object* Sheeting::apply (Runnable* robj, Nameset* nset, const long quark,
Vector* argv) {
// get the number of arguments
long argc = (argv == nilp) ? 0 : argv->length ();
// dispatch 0 argument
if (argc == 0) {
if (quark == QUARK_GETSHT) {
rdlock ();
Sheet* sht = getsht ();
robj->post (sht);
unlock ();
return sht;
}
}
// dispatch 1 argument
if (argc == 1) {
if (quark == QUARK_SETSHT) {
Object* obj = argv->get (0);
Sheet* sht = dynamic_cast <Sheet*> (obj);
if (sht == nilp)
throw Exception ("type-error", "invalid object for set-sheet ",
Object::repr (obj));
setsht (sht);
return nilp;
}
if (quark == QUARK_SIMPORT) {
Object* obj = argv->get (0);
// check for an input stream
Input* is = dynamic_cast <Input*> (obj);
if (is != nilp) {
import (is);
return nilp;
}
// check for a cons cell
Cons* cons = dynamic_cast <Cons*> (obj);
if (cons != nilp) {
import (cons);
return nilp;
}
throw Exception ("type-error", "invalid object for import ",
Object::repr (obj));
}
}
// call the object method
return Object::apply (robj, nset, quark, argv);
}
}
syntax highlighted by Code2HTML, v. 0.9.1