Exemple #1
0
InputNodeVisitor InputStructure::openTag( const InputNodeVisitor& nv, const types::Variant& tag)
{
	if (m_done)
	{
		throw std::runtime_error( "tags not balanced in input (open tag after final close)");
	}
	InputNodeVisitor rt = createChildNode( nv);
	InputNode*nd = node( rt);

	if (tag.type() == types::Variant::String)
	{
		std::string tagstr( tag.tostring());
		nd->m_tag = (int)m_tagmap->find( tagstr);
		if (nd->m_tag == 0) nd->m_tag = (int)m_tagmap->unused();
		nd->m_tagstr = (int)m_privatetagmap.get( tagstr);
	}
	else
	{
		try
		{
			nd->m_arrayindex = (int)tag.toint();
		}
		catch (const std::runtime_error& e)
		{
			throw std::runtime_error( std::string("array index cannot be converted to integer at '") + nodepath(nv) + "'");
		}
		if (nd->m_arrayindex < 0)
		{
			throw std::runtime_error( std::string( "array index is negative at '") + nodepath(nv) + "'");
		}
	}
	return rt;
}
types::Variant TrimNormalizeFunction::execute( const types::Variant& inp) const
{
	if (inp.type() == types::Variant::String)
	{
		std::string str( inp.tostring());
		std::string::const_iterator ii = str.begin(), ee = str.end();
		while (ii != ee && (unsigned char)*ii <= 32) ++ii;
		std::string::const_iterator ti = ii, te = ii;
		for (; ii != ee; ++ii)
		{
			if ((unsigned char)*ii > 32) te = ii+1;
		}
		if (ti == str.begin() && te == str.end())
		{
			return str;
		}
		else
		{
			return std::string( ti, te);
		}
	}
	else
	{
		return inp;
	}
}
void StructureBuilder::setValue( const types::Variant& value_)
{
	LOG_DATA << "[mylang structure builder] set value '" << value_.tostring() << "'";
	if (!m_stk.back().get())
	{
		m_stk.back().reset( new Structure());
	}
	if (!value_.defined()) throw std::runtime_error("set undefined value");
	if (m_stk.back()->m_value.defined()) throw std::runtime_error("value already defined");
	if (!m_stk.back()->m_struct.empty()) throw std::runtime_error("setValue for atomic value called for a structure");
	m_stk.back()->m_value = value_;
}
	types::Variant execute( const types::Variant& i) const
	{
		const CustomDataValue* cv = i.customref();
		const CustomDataType* dt = cv->type();
		CustomDataType::CustomDataValueMethod method = dt->getMethod( m_name);
		if (!method) throw std::logic_error( "internal: calling undefined method");
		return method( *cv, m_arg);
	}
	/// \brief Implementation of types::NormalizeFunction::execute(const types::Variant&)const
	types::Variant execute( const types::Variant& i) const
	{
		types::Variant rt( m_type, m_initializer);
		if (i.defined())
		{
			rt.data().value.Custom->assign( i);
		}
		return rt;
	}
 virtual types::Variant execute( const types::Variant& i) const
     {return types::Variant( i.toint());}
void Object::constructor( const types::Variant& val)
{
	switch (val.type())
	{
		case types::Variant::Custom:
		{
			types::Variant baseval;
			try
			{
				if (val.customref()->getBaseTypeValue( baseval)
				&&  baseval.type() != types::Variant::Custom)
				{
					constructor( baseval);
					break;
				}
			}
			catch (const std::runtime_error& e)
			{
				throw std::runtime_error( std::string("cannot convert value to base type for binding: ") + e.what());
			}
			constructor( val.tostring());
		}
		case types::Variant::Timestamp:
		{
			types::DateTime dt( val.totimestamp());
			if (dt.subtype() == types::DateTime::YYYYMMDD)
			{
				m_obj = PyDate_FromDate( dt.year(), dt.month(), dt.day());
				if (!m_obj) THROW_ON_ERROR( "failed to convert to python Date");
			}
			else
			{
				m_obj = PyDateTime_FromDateAndTime( dt.year(), dt.month(), dt.day(), dt.hour(), dt.minute(), dt.second(), dt.usecond());
				if (!m_obj) THROW_ON_ERROR( "failed to convert to python DateTime");
			}
			break;
		}
		case types::Variant::BigNumber:
		{
			std::string strval = val.tostring();
			if (val.bignumref()->scale() <= 0)
			{
				char* end = 0;
				m_obj = PyLong_FromString( const_cast<char*>(strval.c_str()), &end, 10);
				if (!m_obj) THROW_ON_ERROR( "failed to convert to big number (Long)");
				else if (end != strval.c_str()+strval.size())
				{
					Py_DECREF( m_obj);
					throw std::runtime_error( "superfluous characters at end of big number string");
				}
			}
			else
			{
				m_obj = PyBytes_FromStringAndSize( strval.c_str(), strval.size());
				if (!m_obj) THROW_ON_ERROR( "failed to convert to big number (fixed point number) as string");
			}
			break;
		}
		case types::Variant::Null:
			m_obj = Py_None;
			Py_INCREF( m_obj);
		break;
		case types::Variant::Int:
			m_obj = PyLong_FromLong( val.toint());
			if (!m_obj) THROW_ON_ERROR( "failed to convert to python long integer");
		break;
		case types::Variant::UInt:
			m_obj = PyLong_FromUnsignedLong( val.touint());
			if (!m_obj) THROW_ON_ERROR( "failed to convert to python unsigned long integer");
		break;
		case types::Variant::Bool:
			m_obj = PyBool_FromLong( val.tobool()?1:0);
		break;
		case types::Variant::Double:
			m_obj = PyFloat_FromDouble( val.todouble());
			if (!m_obj) THROW_ON_ERROR( "failed to convert to python double precision floating point value");
		break;
		case types::Variant::String:
			m_obj = PyUnicode_FromStringAndSize( val.charptr(), val.charsize());
			if (!m_obj) THROW_ON_ERROR( "failed to convert to python unicode string");
		break;
		default:
			throw std::runtime_error("try to get object for non atomic value");
	}
}
void SQLiteStatement::bindVariant( const unsigned int idx, const types::Variant &value )
{
	switch (value.type())
	{
		case types::Variant::Null:
			m_rc = wrap_sqlite3_bind_null( m_stm, (int)idx);
			break;
			
		case types::Variant::Bool:
			m_rc = wrap_sqlite3_bind_int( m_stm, (int)idx, value.tobool());
			break;
			
		case types::Variant::Int:
			if( value.data( ).value.Int <= std::numeric_limits<signed int>::max( ) && value.data( ).value.Int >= std::numeric_limits<signed int>::min( ) ) {
				m_rc = wrap_sqlite3_bind_int( m_stm, (int)idx, (signed int)value.toint());
			} else {
				m_rc = wrap_sqlite3_bind_int64( m_stm, (int)idx, value.toint());
			}
			break;
			
		case types::Variant::UInt:
			if( value.data( ).value.UInt <= (unsigned int)std::numeric_limits<signed int>::max( ) ) {
				m_rc = wrap_sqlite3_bind_int( m_stm, (int)idx, (signed int)value.toint());
			} else if ( value.data( ).value.UInt <= (_WOLFRAME_UINTEGER)std::numeric_limits<sqlite3_int64>::max( ) ) {
				m_rc = wrap_sqlite3_bind_int64( m_stm, (int)idx, value.toint());
			} else {
				m_data.push_back( value.tostring());
				m_rc = wrap_sqlite3_bind_text( m_stm, (int)idx, m_data.back().c_str(), m_data.back().size(), SQLITE_STATIC);
			}
			break;
			
		case types::Variant::Double:
			m_rc = wrap_sqlite3_bind_double( m_stm, (int)idx, value.todouble());
			break;
			
		case types::Variant::String:
			m_rc = wrap_sqlite3_bind_text( m_stm, (int)idx, value.charptr(), value.charsize(), SQLITE_STATIC);
			break;
			
		case types::Variant::Timestamp:
		{
			m_data.push_back( types::DateTime( value.totimestamp()).tostring( types::DateTime::StringFormat::ExtendedISOdateTime));
			m_rc = wrap_sqlite3_bind_text( m_stm, (int)idx, m_data.back().c_str(), m_data.back().size(), SQLITE_STATIC);
			break;
		}
		case types::Variant::BigNumber:
		{
			m_data.push_back( value.tostring());
			m_rc = wrap_sqlite3_bind_text( m_stm, (int)idx, m_data.back().c_str(), m_data.back().size(), SQLITE_STATIC);
			break;
		}
		case types::Variant::Custom:
		{
			types::Variant baseval;
			try
			{
				if (value.customref()->getBaseTypeValue( baseval)
				&&  baseval.type() != types::Variant::Custom)
				{
					bindVariant( idx, baseval);
					break;
				}
			}
			catch (const std::runtime_error& e)
			{
				throw std::runtime_error( std::string("cannot convert value to base type for binding: ") + e.what());
			}
			bindVariant( idx, value.tostring());
			break;
		}
		default:
			throw std::logic_error( "Binding unknown type '" + std::string( value.typeName( ) ) + "'" );
	}
}