Beispiel #1
0
/*#
   @function set Dictionary
   @brief Stores a value in a dictionary
   @param key The key to be found.
   @param value The key to be set.
   @return True if the value was overwritten, false if it has been inserted anew.
   
   @note This method bypassess setIndex__ override in blessed (POOP) dictionaries.

   @see oob
*/
FALCON_FUNC  mth_dictSet( ::Falcon::VMachine *vm )
{
   Item *i_dict, *i_key, *i_value;
   
   if( vm->self().isMethodic() )
   {
      i_dict = &vm->self();
      i_key = vm->param(0);
      i_value = vm->param(1);
   }
   else {
      i_dict = vm->param(0);
      i_key = vm->param(1);
      i_value = vm->param(2);
   }
   
   if( i_dict == 0  || ! i_dict->isDict() || i_key == 0 || i_value == 0 ) 
   {
      throw new ParamError( ErrorParam( e_inv_params, __LINE__ )
            .origin( e_orig_runtime )
            .extra( vm->self().isMethodic() ? "X,X" : "D,X,X" ) );
   }

   CoreDict *dict = i_dict->asDict();
   Item *value = dict->find( *i_key );
   if ( value == 0 )
   {
      vm->regA().setBoolean( false );
      dict->put( *i_key, *i_value );
   }
   else {
      vm->regA().setBoolean( true );
      *value = *i_value;
   }
}
Beispiel #2
0
/*# @method setFields URI
   @brief Sets query fields for this uri.
   @param fields A dictionary of fields or nil to clear the query.
   @raise ParamError if the input dictionary contains non-string values.
*/
FALCON_FUNC  URI_setFields ( ::Falcon::VMachine *vm )
{
   UriObject *self = dyncast<UriObject*>( vm->self().asObject() );
   URI &uri = self->uri();

   Item *p0 = vm->param(0);

   if ( ( p0 == 0 ) || ( ! p0->isDict() ) )
   {
      throw new ParamError( ErrorParam( e_inv_params, __LINE__ ).
         origin( e_orig_runtime ).extra( "S" ) );
      return;
   }

   CoreDict *dict = p0->asDict();
   Iterator iter( &dict->items() );

   while( iter.hasCurrent() )
   {
      if ( ( !iter.getCurrentKey().isString()) || (! iter.getCurrent().isString() ) )
      {
         throw new ParamError( ErrorParam( e_inv_params, __LINE__ ).
            origin( e_orig_runtime ).extra( "S" ) );
         return;
      }

      uri.setField( *iter.getCurrentKey().asString(), *iter.getCurrent().asString() );
      iter.next();
   }

   uri.makeQuery();
}
Beispiel #3
0
FALCON_FUNC  Dictionary_do ( ::Falcon::VMachine *vm )
{
	Item* i_func = vm->param(0);

   if ( i_func == 0 || ! i_func->isCallable() )
   {
      throw new ParamError( ErrorParam( e_inv_params, __LINE__ )
         .extra( "C, ..." ) );
   }

   // Save the parameters as the stack may change greatly.
   CoreDict* dict = vm->self().asDict();
   if ( dict->empty() )
   {
   	vm->retnil();
   	return;
   }


   Iterator* iter = new Iterator(&dict->items());
   vm->addLocals(1);
   *vm->local(0) = new GarbagePointer(iter);
   vm->returnHandler( Dictionary_do_next );

   // do the first call.
   vm->pushParam( iter->getCurrentKey() );
	vm->pushParam( iter->getCurrent() );
	vm->callFrame( *vm->param(0), 2 );
}
Beispiel #4
0
FALCON_FUNC  Dictionary_comp ( ::Falcon::VMachine *vm )
{
   if ( vm->param(0) == 0 )
   {
      throw new ParamError( ErrorParam( e_inv_params, __LINE__ )
         .extra( "R|A|C|Sequence, [C]" ) );
   }

   // Save the parameters as the stack may change greatly.
   CoreDict* dict = vm->self().asDict();

   Item i_gen = *vm->param(0);
   Item i_check = vm->param(1) == 0 ? Item(): *vm->param(1);

   // if this is a blessed dictionary, we must use the append method.
   if ( dict->isBlessed() )
   {
      // this will throw if dict has not "append"
      PoopSeq *seq = new PoopSeq( vm, dict );
      vm->pushParam( new GarbagePointer( seq ) );
      seq->comprehension_start( vm, dict, i_check );
   }
   else {
      dict->items().comprehension_start( vm, dict, i_check );
   }

   vm->pushParam( i_gen );
}
Beispiel #5
0
FALCON_FUNC  Dictionary_mfcomp ( ::Falcon::VMachine *vm )
{
	Item* i_func = vm->param(0);

   if ( i_func == 0 )
   {
      throw new ParamError( ErrorParam( e_inv_params, __LINE__ )
         .extra( "C, ..." ) );
   }

   // Save the parameters as the stack may change greatly.
   CoreDict* dict = vm->self().asDict();
   StackFrame* current = vm->currentFrame();

   Item i_check = *i_func;

   // if this is a blessed dictionary, we must use the append method.
   if ( dict->isBlessed() )
   {
      // this will throw if dict has not "append"
      PoopSeq *seq = new PoopSeq( vm, dict );
      vm->pushParam( new GarbagePointer( seq ) );
      seq->comprehension_start( vm, dict, i_check );
   }
   else {
      dict->items().comprehension_start( vm, dict, i_check );
   }

   for( uint32 i = 1; i < current->m_param_count; ++i )
   {
      vm->pushParam( current->m_params[i] );
   }
}
Beispiel #6
0
FALCON_FUNC  mth_dictValues( ::Falcon::VMachine *vm )
{
   Item *i_dict;
   
   if( vm->self().isMethodic() )
   {
      i_dict = &vm->self();
   }
   else {
      i_dict = vm->param(0);
      if( i_dict == 0  || ! i_dict->isDict() ) 
      {
         throw new ParamError( ErrorParam( e_inv_params, __LINE__ )
               .origin( e_orig_runtime )
               .extra( "D" ) );
      }
   }

   CoreDict *dict = i_dict->asDict();
   CoreArray *array = new CoreArray;
   array->reserve( dict->length() );
   Iterator iter( &dict->items() );

   while( iter.hasCurrent() )
   {
      array->append( iter.getCurrent() );
      iter.next();
   }

   vm->retval( array );
}
Beispiel #7
0
/*#
   @method get Dictionary
   @brief Retreives a value associated with the given key
   @param key The key to be found.
   @return The value associated with a key, or an out-of-band nil if not found.

   Return the value associated with the key, if present, or one of the
   values if more than one key matching the given one is present. If
   not present, the value returned will be nil. Notice that nil may be also
   returned if the value associated with a given key is exactly nil. In
   case the key cannot be found, the returned value will be marked as OOB.
   
   @note This method bypassess getIndex__ override in blessed (POOP) dictionaries.

   @see oob
*/
FALCON_FUNC  mth_dictGet( ::Falcon::VMachine *vm )
{
   Item *i_dict, *i_key;
   
   if( vm->self().isMethodic() )
   {
      i_dict = &vm->self();
      i_key = vm->param(0);
   }
   else {
      i_dict = vm->param(0);
      i_key = vm->param(1);
   }
   
   if( i_dict == 0  || ! i_dict->isDict() || i_key == 0 ) 
   {
      throw new ParamError( ErrorParam( e_inv_params, __LINE__ )
            .origin( e_orig_runtime )
            .extra( vm->self().isMethodic() ? "X" : "D,X" ) );
   }

   CoreDict *dict = i_dict->asDict();
   Item *value = dict->find( *i_key );
   if ( value == 0 )
   {
      vm->retnil();
      vm->regA().setOob();
   }
   else
      vm->retval( *value );
}
Beispiel #8
0
/*# @method getFields URI
   @brief Returns fields contained in the query element into a dictionary.
   @return The fields as a dictionary of nil if the query part contains no element.
   @raise ParamError if the string is not a valid URI/URL encoded string.
*/
FALCON_FUNC  URI_getFields ( ::Falcon::VMachine *vm )
{
   UriObject *self = dyncast<UriObject*>( vm->self().asObject() );
   URI &uri = self->uri();

   if ( uri.query().size() == 0 )
   {
      vm->retnil();
      return;
   }

   if( uri.fieldCount() == 0 )
   {
      // we have a query but no fields; this means we still have to parse it.
      if ( ! uri.parseQuery( true ) )
      {
         // todo: better signalation
         throw new ParamError( ErrorParam( e_inv_params, __LINE__ ).
            origin( e_orig_runtime ).extra( vm->moduleString( rtl_invalid_uri ) ) );
         return;
      }

      // really nothing to parse?
      if ( uri.fieldCount() == 0 )
      {
         vm->retnil();
         return;
      }
   }

   // ok, build our dictionary
   uint32 count = uri.fieldCount();
   CoreDict *dict = new CoreDict( new LinearDict( count ) );
   CoreString *key = new CoreString;
   CoreString *value = new CoreString;
   uri.firstField( *key, *value );
   count--;
   dict->put( key, value );
   while( count > 0 )
   {
      key = new CoreString;
      value = new CoreString;
      uri.nextField( *key, *value );
      count --;
      dict->put( key, value );
   }

   vm->retval( dict );
}
Beispiel #9
0
/*#
   @function dictFront
   @brief Returns the first item in the dictionary.
   @param dict The dictionary on which to operate.
   @optparam remove If true, remove the dictionary entry too.
   @optparam key If true, return the key instead of the value.
   @return The first value (or key) in the dictionary.
   @raise AccessError if the dictionary is empty
*/
FALCON_FUNC  mth_dictFront( ::Falcon::VMachine *vm )
{
   CoreDict* dict; 
   bool bKey; 
   bool bRemove;
   
   process_dictFrontBackParams( vm, dict, bKey, bRemove );
   Iterator iter( &dict->items() );
   if ( bKey )
      vm->retval( iter.getCurrentKey() );
   else
      vm->retval( iter.getCurrent() );
   
   if ( bRemove )
      iter.erase();
}
Beispiel #10
0
/*#
   @method clear Dictionary
   @brief Removes all the items from this dictionary.
*/
FALCON_FUNC  mth_dictClear ( ::Falcon::VMachine *vm )
{
   Item *dict;
   
   if( vm->self().isMethodic() )
   {
      dict = &vm->self();
   }
   else {
      dict = vm->param(0);
      if( dict == 0  || ! dict->isDict() ) 
      {
         throw new ParamError( ErrorParam( e_inv_params, __LINE__ )
               .origin( e_orig_runtime )
               .extra( "D"  ) );
      }
   }

   CoreDict *d = dict->asDict();
   d->clear();
}
Beispiel #11
0
/*#
   @method fill Dictionary
   @brief Fills the array with the given element.
   @param item The item to be replicated.
   @return This dictionary.

   This method allows to clear all the values in this dictionary, 
   resetting all the elements to a default value.
*/
FALCON_FUNC  mth_dictFill ( ::Falcon::VMachine *vm )
{
   Item *i_dict;
   Item *i_item;
   
   if ( vm->self().isMethodic() )
   {
      i_dict = &vm->self();
      i_item = vm->param(0);
   }
   else
   {
      i_dict = vm->param(0);
      i_item = vm->param(1);
   }

   if ( i_dict == 0 || ! i_dict->isDict() 
         || i_item == 0 )
   {
      throw new ParamError( ErrorParam( e_inv_params, __LINE__ )
         .origin( e_orig_runtime )
         .extra( vm->self().isMethodic() ? "X" : "D,X" ) );
   }

   CoreDict *dict = i_dict->asDict();
   Iterator iter( &dict->items() );

   while( iter.hasCurrent() )
   {
      if ( i_item->isString() )
         iter.getCurrent() = new CoreString( *i_item->asString() );
      else
         iter.getCurrent() = *i_item;
      
      iter.next();
   }
   
   vm->retval( dict );
}
Beispiel #12
0
FALCON_FUNC  Dictionary_mcomp ( ::Falcon::VMachine *vm )
{
   // Save the parameters as the stack may change greatly.
   CoreDict* dict = vm->self().asDict();
   StackFrame* current = vm->currentFrame();

   // if this is a blessed dictionary, we must use the append method.
   if ( dict->isBlessed() )
   {
      // this will throw if dict has not "append"
      PoopSeq *seq = new PoopSeq( vm, dict );
      vm->pushParam( new GarbagePointer( seq ) );
      seq->comprehension_start( vm, dict, Item() );
   }
   else {
      dict->items().comprehension_start( vm, dict, Item() );
   }

   for( uint32 i = 0; i < current->m_param_count; ++i )
   {
      vm->pushParam( current->m_params[i] );
   }
}
Beispiel #13
0
FALCON_FUNC  mth_dictFind( ::Falcon::VMachine *vm )
{
   Item *i_dict, *i_key;
   
   if( vm->self().isMethodic() )
   {
      i_dict = &vm->self();
      i_key = vm->param(0);
   }
   else {
      i_dict = vm->param(0);
      i_key = vm->param(1);
   }
   
   if( i_dict == 0  || ! i_dict->isDict() || i_key == 0 ) 
   {
      throw new ParamError( ErrorParam( e_inv_params, __LINE__ )
            .origin( e_orig_runtime )
            .extra( vm->self().isMethodic() ? "X" : "D,X" ) );
   }

   CoreDict *dict = i_dict->asDict();
   Iterator iter( &dict->items() );

   if ( ! dict->findIterator( *i_key, iter ) )
      vm->retnil();
   else 
   {
      // find the iterator class, we'll need it
      Item *i_iclass = vm->findWKI( "Iterator" );
      fassert( i_iclass != 0 );
      
      CoreObject *ival = i_iclass->asClass()->createInstance( new Iterator( iter ) );
      ival->setProperty( "_origin", *i_dict );
      vm->retval( ival );
   }
}
Beispiel #14
0
/*#
   @method remove Dictionary
   @brief Removes a given key from the dictionary.
   @param key The key to be removed
   @return True if the key is found and removed, false otherwise.

   If the given key is found, it is removed from the dictionary,
   and the function returns true. If it's not found, it returns false.
*/
FALCON_FUNC  mth_dictRemove ( ::Falcon::VMachine *vm )
{
   Item *dict, *key;
   
   if( vm->self().isMethodic() )
   {
      dict = &vm->self();
      key = vm->param(0);
   }
   else {
      dict = vm->param(0);
      key = vm->param(1);
   }
   
   if( dict == 0  || ! dict->isDict() || key == 0 ) 
   {
      throw new ParamError( ErrorParam( e_inv_params, __LINE__ )
            .origin( e_orig_runtime )
            .extra( vm->self().isMethodic() ? "X" : "D,X" ) );
   }

   CoreDict *d = dict->asDict();
   vm->regA().setBoolean( d->remove( *key ) );
}
Beispiel #15
0
static void describe_internal( VMachine *vm, String &tgt, const Item *elem, int32 level, int32 maxLevel, int32 maxSize )
{
   uint32 count;

   // return if we reached the maximum level.
   if ( maxLevel >= 0 && level > maxLevel )
   {
      tgt += "...";
      return;
   }

   switch( elem->type() )
   {
      case FLC_ITEM_NIL:
         tgt += "Nil";
      break;

      case FLC_ITEM_UNB:
         tgt += "_";
      break;


      case FLC_ITEM_BOOL:
         tgt += elem->asBoolean() ? "true" : "false";
      break;


      case FLC_ITEM_INT:
         tgt.writeNumber( elem->asInteger() );
      break;

      case FLC_ITEM_NUM:
         tgt.writeNumber( elem->asNumeric(), "%g" );
      break;

      case FLC_ITEM_RANGE:
         elem->toString(tgt);
      break;

      case FLC_ITEM_STRING:
         tgt += "\"";
         if ( maxSize < 0 || elem->asString()->length() < (uint32) maxSize )
         {
            tgt += *elem->asString();
            tgt += "\"";
         }
         else {
            tgt += elem->asString()->subString(0, maxSize );
            tgt += " ... \"";
         }
      break;

      case FLC_ITEM_LBIND:
         tgt += "&";
         tgt += *elem->asLBind();
         if (elem->isFutureBind())
         {
            tgt +="|";
            describe_internal( vm, tgt, &elem->asFutureBind(), level+1, maxLevel, maxSize );
         }
      break;

      case FLC_ITEM_MEMBUF:
      {
         MemBuf *mb = elem->asMemBuf();
         tgt += "MB(";
         tgt.writeNumber( (int64) mb->length() );
         tgt += ",";
         tgt.writeNumber( (int64) mb->wordSize() );
         tgt += ")";

         tgt += " [";

         String fmt;
         int limit = 0;
         switch ( mb->wordSize() )
         {
            case 1: fmt = "%02" LLFMT "X"; limit = 24; break;
            case 2: fmt = "%04" LLFMT "X"; limit = 12; break;
            case 3: fmt = "%06" LLFMT "X"; limit = 9; break;
            case 4: fmt = "%08" LLFMT "X"; limit = 6; break;
         }

         uint32 max = maxSize < 0 || mb->length() < (uint32) maxSize ? mb->length() : (uint32) maxSize;
         for( count = 0; count < max; count++ )
         {
            tgt.writeNumber( (int64)  mb->get( count ), fmt );
            tgt += " ";
         }
         if ( count == (uint32) maxSize )
            tgt += " ...";
         tgt += "]";
      }
      break;

      case FLC_ITEM_ARRAY:
      {
         CoreArray *arr = elem->asArray();
         tgt += "[";

         if ( level == maxLevel )
         {
            tgt += "...]";
            break;
         }

         for( count = 0; count < arr->length(); count++ ) {
            if ( count == 0 ) tgt += " ";

            describe_internal( vm, tgt, & ((*arr)[count]), level + 1, maxLevel, maxSize );

            if ( count + 1 < arr->length() )
               tgt += ", ";
         }

         tgt +="]";
      }
      break;

      case FLC_ITEM_DICT:
      {
         CoreDict *dict = elem->asDict();
         if( dict->isBlessed() )
            tgt += "*";

         tgt += "[";

         if ( level == maxLevel )
         {
            tgt += "...=>...]";
            break;
         }

         if ( dict->length() == 0 )
         {
            tgt += "=>]";
            break;
         }

         Item key, value;
         Iterator iter( &dict->items() );

         // separate the first loop to be able to add ", "
         describe_internal( vm, tgt, &iter.getCurrentKey(), level + 1, maxLevel, maxSize );
         tgt += " => ";
         describe_internal( vm, tgt, &iter.getCurrent(), level + 1, maxLevel, maxSize );
         iter.next();
         while( iter.hasCurrent() )
         {
            tgt += ", ";
            describe_internal( vm, tgt, &iter.getCurrentKey(), level + 1, maxLevel, maxSize );
            tgt += " => ";
            describe_internal( vm, tgt, &iter.getCurrent(), level + 1, maxLevel, maxSize );
            iter.next();
         }

         tgt += "]";
      }
      break;

      case FLC_ITEM_OBJECT:
      {
         CoreObject *arr = elem->asObjectSafe();
         tgt += arr->generator()->symbol()->name() + "(){ ";

         if ( level == maxLevel )
         {
            tgt += "...}";
            break;
         }

         const PropertyTable &pt = arr->generator()->properties();

         for( count = 0; count < pt.added() ; count++ )
         {
            const String &propName = *pt.getKey( count );
			
			// write only?
			if ( pt.getEntry( count ).isWriteOnly() )
			{
				tgt.A( "(" ).A( propName ).A(")");
			}
			else
			{
				Item dummy;
				arr->getProperty( propName, dummy );

				// in describe skip methods.
				if ( dummy.isFunction() || dummy.isMethod() )
				   continue;
				
				tgt += propName + " = ";

				describe_internal( vm, tgt, &dummy, level + 1, maxLevel, maxSize );
			}

            if (count+1 < pt.added())
            {
               tgt += ", ";
            }
         }

         tgt += "}";
      }
      break;

      case FLC_ITEM_CLASS:
         tgt += "Class " + elem->asClass()->symbol()->name();
      break;

      case FLC_ITEM_METHOD:
      {
         tgt += "(";
         Item itemp;
         elem->getMethodItem( itemp );
         describe_internal( vm, tgt, &itemp, level + 1, maxLevel, maxSize );
         tgt += ").";
         tgt += elem->asMethodFunc()->name() + "()";
      }
      break;

      case FLC_ITEM_CLSMETHOD:
         tgt += "Class ";
         tgt += elem->asMethodClassOwner()->generator()->symbol()->name();
         tgt += "." + elem->asMethodClass()->symbol()->name() + "()";
      break;

      case FLC_ITEM_FUNC:
      {
         const Symbol *funcSym = elem->asFunction()->symbol();
         tgt += funcSym->name() + "()";
      }
      break;

      case FLC_ITEM_REFERENCE:
         tgt += "->";
         describe_internal( vm, tgt, elem->dereference(), level + 1, maxLevel, maxSize );
      break;

      default:
         tgt += "?";
   }
}
Beispiel #16
0
void inspect_internal( VMachine *vm, const Item *elem, int32 level, int32 maxLevel, int32 maxSize, Item* i_stream, bool add, bool addline )
{

   uint32 count;
   int32 i;
   Stream *stream = i_stream != 0 ?
         dyncast<Stream*>(i_stream->asObjectSafe()->getFalconData()) :
         vm->stdErr();

   // return if we reached the maximum level.
   if ( maxLevel >= 0 && level > maxLevel )
   {
      stream->writeString( "..." );
      if ( addline )
         stream->writeString( "\n" );
      return;
   }

   if ( stream == 0 )
   {
      stream = vm->stdOut();
      if ( stream == 0 )
         return;
   }

   if ( add )
      for ( i = 0; i < level*3; i ++ )
      {
         stream->put( 0x20 ); // space
      }

   if ( elem == 0 ) {
      stream->writeString( "Nothing" );
      if ( addline )
         stream->writeString( "\n" );
      return;
   }

   String temp;

   switch( elem->type() )
   {
      case FLC_ITEM_NIL:
         stream->writeString( "Nil" );
      break;

      case FLC_ITEM_UNB:
            stream->writeString( "_" );
      break;

      case FLC_ITEM_BOOL:
         stream->writeString( elem->asBoolean() ? "true" : "false" );
      break;


      case FLC_ITEM_INT:
         temp.writeNumber( elem->asInteger() );
         stream->writeString( "int(" );
         stream->writeString( temp );
         stream->writeString( ")" );
      break;

      case FLC_ITEM_NUM:
         temp.writeNumber( elem->asNumeric(), "%g" );
         stream->writeString( "num(" );
         stream->writeString( temp );
         stream->writeString( ")" );
      break;

      case FLC_ITEM_RANGE:
         elem->toString(temp);
         stream->writeString( temp );
      break;

      case FLC_ITEM_STRING:
         stream->writeString( "\"" );
         if ( maxSize < 0 || elem->asString()->length() < (uint32) maxSize )
         {
            stream->writeString( *elem->asString() );
            stream->writeString( "\"" );
         }
         else {
            stream->writeString( elem->asString()->subString(0, maxSize ) );
            stream->writeString( " ... \"" );
         }
      break;

      case FLC_ITEM_LBIND:
         stream->writeString( "&" );
         stream->writeString( *elem->asLBind() );
      break;

      case FLC_ITEM_MEMBUF:
      {
         MemBuf *mb = elem->asMemBuf();
         temp = "MemBuf(";
         temp.writeNumber( (int64) mb->length() );
         temp += ",";
         temp.writeNumber( (int64) mb->wordSize() );
         temp += ")";

         if ( maxSize == 0 )
            stream->writeString( temp );
         else {
            temp += " [\n";

            String fmt;
            int limit = 0;
            switch ( mb->wordSize() )
            {
               case 1: fmt = "%02" LLFMT "X"; limit = 24; break;
               case 2: fmt = "%04" LLFMT "X"; limit = 12; break;
               case 3: fmt = "%06" LLFMT "X"; limit = 9; break;
               case 4: fmt = "%08" LLFMT "X"; limit = 6; break;
            }

            int written = 0;
            uint32 max = maxSize < 0 || mb->length() < (uint32) maxSize ? mb->length() : (uint32) maxSize;
            for( count = 0; count < max; count++ )
            {
               temp.writeNumber( (int64)  mb->get( count ), fmt );
               temp += " ";
               written ++;
               if ( written == limit )
               {
                  temp += "\n";
                  written = 0;
               }
               stream->writeString( temp );
               temp = "";
            }
            if ( count == (uint32) maxSize )
               stream->writeString( " ... " );
            stream->writeString( "]" );
         }
      }
      break;

      case FLC_ITEM_ARRAY:
      {
         CoreArray *arr = elem->asArray();
         temp = "Array[";
         temp.writeNumber( (int64) arr->length() );
         temp += "]";
         stream->writeString( temp );

         if ( level == maxLevel )
         {
            stream->writeString( "{...}" );
            break;
         }

         stream->writeString( "{\n" );

         for( count = 0; count < arr->length(); count++ ) {
            inspect_internal( vm, & ((*arr)[count]), level + 1, maxLevel, maxSize, i_stream, true, true );
         }

         for ( i = 0; i < level; i ++ )
         {
            stream->writeString( "   " );
         }
         stream->writeString( "}" );
      }
      break;

      case FLC_ITEM_DICT:
      {
         CoreDict *dict = elem->asDict();
         temp = "Dict[";
         temp.writeNumber( (int64) dict->length() );
         temp += "]";
         stream->writeString( temp );

         if ( level == maxLevel )
         {
            stream->writeString( "{...}" );
            break;
         }

         stream->writeString( "{\n" );

         Iterator iter( &dict->items() );
         while( iter.hasCurrent() )
         {
            inspect_internal( vm, &iter.getCurrentKey(), level + 1, maxLevel, maxSize, i_stream, true, false );
            stream->writeString( " => " );
            inspect_internal( vm, &iter.getCurrent(), level + 1, maxLevel, maxSize, i_stream, false, true );
            iter.next();
         }
         for ( i = 0; i < level; i ++ )
         {
            stream->writeString("   ");
         }
         stream->writeString( "}" );
      }
      break;

      case FLC_ITEM_OBJECT:
      {
         CoreObject *arr = elem->asObjectSafe();
         stream->writeString( "Object of class " + arr->generator()->symbol()->name() );
         if ( level == maxLevel )
         {
            stream->writeString( "{...}" );
            break;
         }

         stream->writeString( " {\n" );
         const PropertyTable &pt = arr->generator()->properties();

         for( count = 0; count < pt.added() ; count++ )
         {
            for ( i = 0; i < (level+1); i ++ )
            {
               stream->writeString("   ");
            }
            const String &propName = *pt.getKey( count );
			
			if ( pt.getEntry(count).isWriteOnly() )
			{
				stream->writeString( "(" );
				stream->writeString( propName + ")\n" );
			}
			else 
			{
				stream->writeString( propName + " => " );
				Item dummy;
				arr->getProperty( propName, dummy);
				inspect_internal( vm, &dummy, level + 1, maxLevel, maxSize, i_stream, false, true );
			}
         }
         for ( i = 0; i < level; i ++ )
         {
            stream->writeString("   ");
         }
         stream->writeString( "}" );
      }
      break;

      case FLC_ITEM_CLASS:
         stream->writeString( "Class " + elem->asClass()->symbol()->name() );
      break;

      case FLC_ITEM_METHOD:
      {
         temp = "Method ";
         temp += "->" + elem->asMethodFunc()->name();
         stream->writeString( temp );

         Item itemp;
         elem->getMethodItem( itemp );

         inspect_internal( vm, &itemp, level + 1, maxLevel, maxSize, i_stream, true, true );
         for ( i = 0; i < level; i ++ )
         {
            stream->writeString("   ");
         }
         stream->writeString( "}" );
      }
      break;

      case FLC_ITEM_CLSMETHOD:
         temp = "Cls.Method 0x";
         temp.writeNumberHex( (uint64) elem->asMethodClassOwner() );
         temp += "->" + elem->asMethodClass()->symbol()->name();
         stream->writeString( temp );
      break;

      case FLC_ITEM_FUNC:
      {
         const Symbol *funcSym = elem->asFunction()->symbol();

         if ( funcSym->isExtFunc() )
         {
            stream->writeString( "Ext. Function " + funcSym->name() );
         }
         else {
            stream->writeString( "Function " + funcSym->name() );

            FuncDef *def = funcSym->getFuncDef();
            uint32 itemId = def->onceItemId();
            if ( itemId != FuncDef::NO_STATE )
            {
               if ( elem->asFunction()->liveModule()->globals()[ itemId ].isNil() )
                  stream->writeString( "{ not called }");
               else
                  stream->writeString( "{ called }");
            }
         }
      }
      break;

      case FLC_ITEM_REFERENCE:
         stream->writeString( "Ref to " );
         inspect_internal( vm, elem->dereference(), level + 1, maxLevel, maxSize, i_stream, false, true );
      break;

      default:
         stream->writeString( "Invalid type");
   }
   if ( addline )
      stream->writeString( "\n" );

   stream->flush();
}
Beispiel #17
0
static void internal_record_fetch( VMachine* vm, DBIRecordset* dbr, Item& target )
{
   int count = dbr->getColumnCount();

   if( target.isArray() )
   {
      CoreArray* aret = target.asArray();
      aret->resize( count );
      for ( int i = 0; i < count; i++ )
      {
         dbr->getColumnValue( i, aret->items()[i] );
      }
      vm->retval( aret );
   }
   else if( target.isDict() )
   {
      CoreDict* dret = target.asDict();
      for ( int i = 0; i < count; i++ )
      {
         String fieldName;
         dbr->getColumnName( i, fieldName );
         Item* value = dret->find( Item(&fieldName) );
         if( value == 0 )
         {
            Item v;
            dbr->getColumnValue( i, v );
            CoreString* key = new CoreString(fieldName);
            key->bufferize();
            dret->put( key, v );
         }
         else
         {
            dbr->getColumnValue( i, *value );
         }
      }
      vm->retval( dret );
   }
   /*
   else
   {
      CoreTable* tbl = dyncast<CoreTable*>(target.asObject()->getFalconData());
      ItemArray iaCols( count );

      if( tbl->order() == CoreTable::noitem )
      {
         String* fieldName = new String[count];
         for( int i = 0; i < count; ++ i )
         {
            dbr->getColumnName( i, fieldName[i] );
            iaCols.append( fieldName );
         }

         if( ! tbl->setHeader( iaCols ) )
         {
            delete[] fieldName;
            throw new DBIError( ErrorParam( FALCON_DBI_ERROR_FETCH, __LINE__ )
                  .extra("Incompatible table columns" ) );
         }

         delete[] fieldName;
      }
      else
      {
         if( tbl->order() != (unsigned) count )
         {
            throw new DBIError( ErrorParam( FALCON_DBI_ERROR_FETCH, __LINE__ )
                              .extra("Incompatible table columns" ) );
         }
      }

      // put in the values
      do {
         CoreArray* row = new CoreArray();
         row->resize( count );

         for( int i = 0; i < count; ++ i )
         {
            dbr->getColumnValue( i, row->at( i ) );
         }
         tbl->insertRow( row );
      }
      while( dbr->fetchRow() );

      vm->retval( target );
   }
   */
}
Beispiel #18
0
Item::e_sercode Item::serialize( Stream *file, bool bLive ) const
{
   if( file->bad() )
      return sc_ferror;

   switch( this->type() )
   {
      case FLC_ITEM_BOOL:
      {
         byte type = FLC_ITEM_BOOL;
         file->write((byte *) &type, 1 );

         byte bval = this->asBoolean() ? 1 : 0;
         file->write( (byte *) &bval, sizeof( bval ) );
      }
      break;

      case FLC_ITEM_INT:
      {
         byte type = FLC_ITEM_INT;
         file->write((byte *) &type, 1 );

         int64 val = endianInt64( this->asInteger() );
         file->write( (byte *) &val, sizeof( val ) );
      }
      break;

      case FLC_ITEM_RANGE:
      {
         byte type = FLC_ITEM_RANGE;
         file->write((byte *) &type, 1 );

         int64 val1 = endianInt64(this->asRangeStart());
         int64 val2 = endianInt64(this->asRangeEnd());
         int64 val3 = endianInt64(this->asRangeStep());
         //byte isOpen = this->asRangeIsOpen() ? 1 : 0;

         file->write( (byte *) &val1, sizeof( val1 ) );
         file->write( (byte *) &val2, sizeof( val2 ) );
         file->write( (byte *) &val3, sizeof( val3 ) );
         //file->write( (byte *) &isOpen, sizeof( isOpen ) );
      }
      break;

      case FLC_ITEM_NUM:
      {
         byte type = FLC_ITEM_NUM;
         file->write((byte *) &type, 1 );

         numeric val = endianNum( this->asNumeric() );
         file->write( (byte *) &val, sizeof( val ) );
      }
      break;

      case FLC_ITEM_STRING:
      {
         byte type = FLC_ITEM_STRING;
         file->write((byte *) &type, 1 );
         this->asString()->serialize( file );
      }
      break;

      case FLC_ITEM_LBIND:
      {
         byte type = FLC_ITEM_LBIND;
         file->write((byte *) &type, 1 );
         // Future bindings are temporary items; as such, their future
         // value is not to be serialized.
         asLBind()->serialize( file );
      }
      break;

      case FLC_ITEM_MEMBUF:
      {
         byte type = FLC_ITEM_MEMBUF;
         if ( bLive )
         {
            type |= 0x80;
            file->write( &type, 1 );
            MemBuf* mb = asMemBuf();
            file->write( &mb, sizeof(mb) );
         }
         else {
            file->write( &type, 1 );
            this->asMemBuf()->serialize( file, bLive );
         }
      }
      break;

      case FLC_ITEM_ARRAY:
      {
         byte type = FLC_ITEM_ARRAY;
         file->write((byte *) &type, 1 );

         CoreArray &array = *this->asArray();
         int32 len = endianInt32( array.length() );
         file->write( (byte *) &len, sizeof( len ) );
         for( uint32 i = 0; i < array.length(); i ++ ) {
            array[i].serialize( file, bLive );
            if( ! file->good() )
               return sc_ferror;
         }
      }
      break;

      case FLC_ITEM_DICT:
      {
         byte type = FLC_ITEM_DICT;
         file->write( &type, 1 );

         CoreDict *dict = this->asDict();
         type = dict->isBlessed() ? 1:0;
         file->write( &type, 1 );

         int32 len = endianInt32( dict->length() );
         file->write( (byte *) &len, sizeof( len ) );

         Iterator iter( &dict->items() );
         while( iter.hasCurrent() )
         {
            iter.getCurrentKey().serialize( file, bLive );
            if( ! file->good() )
               return sc_ferror;
            iter.getCurrent().serialize( file, bLive );
            if( ! file->good() )
               return sc_ferror;

            iter.next();
         }
      }
      break;

      case FLC_ITEM_FUNC:
         serialize_function( file, this->asFunction(), bLive );
      break;

      case FLC_ITEM_METHOD:
      {
         byte type = FLC_ITEM_METHOD;
         file->write( &type, 1 );

         e_sercode sc = asMethodItem().serialize( file, bLive );
         if( sc != sc_ok )
            return sc;

         CallPoint* cp = this->asMethodFunc();
         if ( cp->isFunc() )
         {
            serialize_function( file, static_cast<CoreFunc*>(cp), bLive );
         }
         else
         {
            SafeItem arr( static_cast<CoreArray*>(cp) );
            arr.serialize(file, bLive );
         }
      }
      break;

      case FLC_ITEM_OBJECT:
         serialize_object( file, this->asObjectSafe(), bLive );
      break;

      case FLC_ITEM_REFERENCE:
         asReference()->origin().serialize( file, bLive );
      break;

      case FLC_ITEM_CLASS:
         serialize_class( file, this->asClass() );
      break;

      case FLC_ITEM_CLSMETHOD:
         serialize_class( file, this->asMethodClass() );
         serialize_function( file, this->asFunction(), bLive );
      break;

      case FLC_ITEM_UNB:
      {
         byte type = FLC_ITEM_UNB;
         file->write((byte *) &type, 1 );
      }
      break;

      default:
      {
         byte type = FLC_ITEM_NIL;
         file->write((byte *) &type, 1 );
      }
   }

   return file->bad() ? sc_ferror : sc_ok;
}
Beispiel #19
0
Item::e_sercode Item::deserialize( Stream *file, VMachine *vm )
{
   byte type = FLC_ITEM_NIL;
   if ( file->read((byte *) &type, 1 ) == 0 )
      return sc_eof;

   if( ! file->good() )
      return sc_ferror;

   switch( type )
   {
      case FLC_ITEM_NIL:
         setNil();
      return sc_ok;

      case FLC_ITEM_UNB:
         setUnbound();
         return sc_ok;

      case FLC_ITEM_BOOL:
      {
         byte bval;
         file->read( (byte *) &bval, sizeof( bval ) );
         if ( file->good() ) {
            setBoolean( bval != 0 );
            return sc_ok;
         }
         return sc_ferror;
      }
      return sc_ok;

      case FLC_ITEM_INT:
      {
         int64 val;
         file->read( (byte *) &val, sizeof( val ) );
         if ( file->good() ) {
            setInteger(endianInt64(val) );
            return sc_ok;
         }
         return sc_ferror;
      }
      break;

      case FLC_ITEM_RANGE:
      {
         int64 val1;
         int64 val2;
         int64 val3;
         //byte isOpen;

         file->read( (byte *) &val1, sizeof( val1 ) );
         file->read( (byte *) &val2, sizeof( val2 ) );
         file->read( (byte *) &val3, sizeof( val3 ) );
         //file->read( (byte *) &isOpen, sizeof( isOpen ) );

         val1 = endianInt64( val1 );
         val2 = endianInt64( val2 );
         val3 = endianInt64( val3 );

         if ( file->good() ) {
            setRange( new CoreRange( val1, val2, val3 ) );
            return sc_ok;
         }
         return sc_ferror;
      }
      break;

      case FLC_ITEM_NUM:
      {
         numeric val;
         file->read( (byte *) &val, sizeof( val ) );
         if ( file->good() ) {
            setNumeric( endianNum( val ) );
            return sc_ok;
         }
         return sc_ferror;
      }
      break;

      case FLC_ITEM_LBIND:
      {
         int32 id;
         file->read( (byte*) &id, sizeof(id) );
         String name;
         if ( ! name.deserialize( file ) )
            return file->bad() ? sc_ferror : sc_invformat;

         setLBind( new CoreString( name ) );
      }
      break;

      case FLC_ITEM_STRING:
      {
         CoreString *cs = new CoreString;
         setString( cs );

         if ( ! cs->deserialize( file ) )
         {
            return file->bad() ? sc_ferror : sc_invformat;
         }

         if ( file->good() ) {
            return sc_ok;
         }

         return sc_ferror;
      }
      break;

      case FLC_ITEM_MEMBUF |0x80:
      {
         // get the function pointer in the stream
         /*MemBuf *(*deserializer)( VMachine *, Stream * );
         file->read( &deserializer, sizeof( deserializer ) );
         if ( ! file->good() ) {
            return sc_ferror;
         }

         MemBuf *mb = deserializer( vm, file );
         if( mb == 0 )
         {
            return sc_invformat;
         }*/

         MemBuf* mb;
         if( file->read( &mb, sizeof( mb ) ) == sizeof(mb) )
         {
            setMemBuf( mb );
            return sc_ok;
         }
         return sc_eof;
      }

      case FLC_ITEM_MEMBUF:
      {
         MemBuf *mb = MemBuf::deserialize( vm, file );
         if ( file->good() && mb != 0 ) {
            setMemBuf( mb );
            return sc_ok;
         }

         return sc_ferror;
      }
      break;


      case FLC_ITEM_ARRAY:
      {
         int32 val;
         file->read( (byte *) &val, sizeof( val ) );
         e_sercode retval = sc_ok;

         if ( file->good() )
         {
            val = endianInt32(val);
            CoreArray *array = new CoreArray();
            array->resize(val);

            for( int i = 0; i < val; i ++ )
            {
               retval = array->items()[i].deserialize( file, vm );
               if( retval != sc_ok ) {
                  break;
               }

            }

            if ( retval == sc_ok ) {
               setArray( array );
               return sc_ok;
            }

            return retval;
         }
      }
      break;

      case FLC_ITEM_DICT:
      {
         byte blessed;
         file->read( &blessed, 1 );

         int32 val;
         file->read( (byte *) &val, sizeof( val ) );

         if ( file->good() )
         {
            val = endianInt32(val);
            LinearDict *dict = new LinearDict( val );
            LinearDictEntry *elems = dict->entries();
            e_sercode retval = sc_ok;
            for( int i = 0; i < val; i ++ ) {
               LinearDictEntry *entry = elems + i;
               retval = entry->key().deserialize( file, vm );
               if( retval == sc_ok )
                    retval = entry->value().deserialize( file, vm );

               if ( retval != sc_ok )
                  break;
               dict->length( i + 1 );
            }

            if( retval == sc_ok ) {
               CoreDict* cdict = new CoreDict( dict );
               cdict->bless( blessed ? true : false );
               setDict( cdict );

               return sc_ok;
            }
            else
               delete dict;

            return retval;
         }
      }
      break;

      case FLC_ITEM_FUNC | 0x80:
      case FLC_ITEM_FUNC:
      {
         if( vm == 0 )
            return sc_missvm;

         return deserialize_function( file, vm );
      }
     break;

      case FLC_ITEM_METHOD:
      {
         if( vm == 0 )
            return sc_missvm;

         Item obj;
         Item func;
         e_sercode sc;
         sc = obj.deserialize( file, vm );
         if ( sc != sc_ok )
            return sc;

         sc = func.deserialize( file, vm );
         if ( sc != sc_ok )
            return sc;
         if ( func.isFunction() )
            setMethod( obj, func.asMethodFunc() );
         else if ( func.isArray() && func.isCallable() )
         {
            setMethod( obj, func.asArray() );
         }
         else
            return sc_invformat;

         return sc_ok;
      }


      case FLC_ITEM_OBJECT | 0x80:
      case FLC_ITEM_OBJECT:
      {
         bool bLive = type != FLC_ITEM_OBJECT;

         if( vm == 0 )
            return sc_missvm;

         // read the module name
         Symbol *sym;
         LiveModule *lmod;
         e_sercode sc = deserialize_symbol( file, vm, &sym, &lmod );
         if ( sc != sc_ok  )
            return sc;

         Item *clitem = &lmod->globals()[ sym->itemId() ];

         // Create the core object, but don't fill attribs.
         CoreObject *object = clitem->dereference()->asClass()->createInstance(0, true);
         if ( ! object->deserialize( file, bLive ) )
         {
            return sc_missclass;
         }

         setObject( object );
         return file->good() ? sc_ok : sc_ferror;
      }
      break;

      case FLC_ITEM_CLASS:
         return deserialize_class( file, vm );


       case FLC_ITEM_CLSMETHOD:
       {
         e_sercode sc = deserialize_class( file, vm );
         if ( sc != sc_ok )
            return sc;
         return deserialize_function( file, vm );
      }
      break;

      default:
         return sc_invformat;
   }

   return sc_ferror;
}