Example #1
0
long file_length(filetype *fp)
{
	long cur, length;
	
	cur = file_getpos(fp);
	file_setpos(fp, 0, seek_end);
	length = file_getpos(fp);
	file_setpos(fp, cur, seek_set);
	
	return length;
}
Example #2
0
void vm_process(VM *vm) {
  int a, b, opcode;
  opcode = vm->image[vm->ip];

  switch(opcode) {
    case VM_NOP:
         break;
    case VM_LIT:
         vm->sp++;
         vm->ip++;
         TOS = vm->image[vm->ip];
         break;
    case VM_DUP:
         vm->sp++;
         vm->data[vm->sp] = NOS;
         break;
    case VM_DROP:
         DROP
         break;
    case VM_SWAP:
         a = TOS;
         TOS = NOS;
         NOS = a;
         break;
    case VM_PUSH:
         vm->rsp++;
         TORS = TOS;
         DROP
         break;
    case VM_POP:
         vm->sp++;
         TOS = TORS;
         vm->rsp--;
         break;
    case VM_CALL:
         vm->ip++;
         vm->rsp++;
         TORS = vm->ip;
         vm->ip = vm->image[vm->ip] - 1;
         if (vm->ip < 0)
           vm->ip = IMAGE_SIZE;
         else {
           if (vm->image[vm->ip+1] == 0)
             vm->ip++;
           if (vm->image[vm->ip+1] == 0)
             vm->ip++;
         }
         break;
    case VM_JUMP:
         vm->ip++;
         vm->ip = vm->image[vm->ip] - 1;
         if (vm->ip < 0)
           vm->ip = IMAGE_SIZE;
         else {
           if (vm->image[vm->ip+1] == 0)
             vm->ip++;
           if (vm->image[vm->ip+1] == 0)
             vm->ip++;
         }
         break;
    case VM_RETURN:
         vm->ip = TORS;
         vm->rsp--;
         break;
    case VM_GT_JUMP:
         vm->ip++;
         if(NOS > TOS)
           vm->ip = vm->image[vm->ip] - 1;
         DROP DROP
         break;
    case VM_LT_JUMP:
         vm->ip++;
         if(NOS < TOS)
           vm->ip = vm->image[vm->ip] - 1;
         DROP DROP
         break;
    case VM_NE_JUMP:
         vm->ip++;
         if(TOS != NOS)
           vm->ip = vm->image[vm->ip] - 1;
         DROP DROP
         break;
    case VM_EQ_JUMP:
         vm->ip++;
         if(TOS == NOS)
           vm->ip = vm->image[vm->ip] - 1;
         DROP DROP
         break;
    case VM_FETCH:
         TOS = vm->image[TOS];
         break;
    case VM_STORE:
         vm->image[TOS] = NOS;
         DROP DROP
         break;
    case VM_ADD:
         NOS += TOS;
         DROP
         break;
    case VM_SUB:
         NOS -= TOS;
         DROP
         break;
    case VM_MUL:
         NOS *= TOS;
         DROP
         break;
    case VM_DIVMOD:
         a = TOS;
         b = NOS;
         TOS = b / a;
         NOS = b % a;
         break;
    case VM_AND:
         a = TOS;
         b = NOS;
         DROP
         TOS = a & b;
         break;
    case VM_OR:
         a = TOS;
         b = NOS;
         DROP
         TOS = a | b;
         break;
    case VM_XOR:
         a = TOS;
         b = NOS;
         DROP
         TOS = a ^ b;
         break;
    case VM_SHL:
         a = TOS;
         b = NOS;
         DROP
         TOS = b << a;
         break;
    case VM_SHR:
         a = TOS;
         b = NOS;
         DROP
         TOS = b >>= a;
         break;
    case VM_ZERO_EXIT:
         if (TOS == 0) {
           DROP
           vm->ip = TORS;
           vm->rsp--;
         }
         break;
    case VM_INC:
         TOS += 1;
         break;
    case VM_DEC:
         TOS -= 1;
         break;
    case VM_IN:
         a = TOS;
         TOS = vm->ports[a];
         vm->ports[a] = 0;
         break;
    case VM_OUT:
         vm->ports[0] = 0;
         vm->ports[TOS] = NOS;
         DROP DROP
         break;
    case VM_WAIT:
         if (vm->ports[0] == 1)
           break;

         /* Input */
         if (vm->ports[0] == 0 && vm->ports[1] == 1) {
           vm->ports[1] = dev_getch();
           vm->ports[0] = 1;
         }

         /* Output (character generator) */
         if (vm->ports[2] == 1) {
           dev_putch(TOS); DROP
           vm->ports[2] = 0;
           vm->ports[0] = 1;
         }

         if (vm->ports[4] != 0) {
           vm->ports[0] = 1;
           switch (vm->ports[4]) {
             case  1: vm_save_image(vm, vm->filename);
                      vm->ports[4] = 0;
                      break;
             case  2: file_add(vm);
                      vm->ports[4] = 0;
                      break;
             case -1: vm->ports[4] = file_handle(vm);
                      break;
             case -2: vm->ports[4] = file_readc(vm);
                      break;
             case -3: vm->ports[4] = file_writec(vm);
                      break;
             case -4: vm->ports[4] = file_closehandle(vm);
                      break;
             case -5: vm->ports[4] = file_getpos(vm);
                      break;
             case -6: vm->ports[4] = file_seek(vm);
                      break;
             case -7: vm->ports[4] = file_size(vm);
                      break;
             default: vm->ports[4] = 0;
           }
         }

         /* Capabilities */
         if (vm->ports[5] != 0) {
           vm->ports[0] = 1;
           switch(vm->ports[5]) {
             case -1:  vm->ports[5] = IMAGE_SIZE;
                       break;
             case -2:  vm->ports[5] = 0;
                       break;
             case -3:  vm->ports[5] = 0;
                       break;
             case -4:  vm->ports[5] = 0;
                       break;
             case -5:  vm->ports[5] = vm->sp;
                       break;
             case -6:  vm->ports[5] = vm->rsp;
                       break;
             case -7:  vm->ports[5] = 0;
                       break;
             case -8:  vm->ports[5] = time(NULL);
                       break;
             case -9:  vm->ports[5] = 0;
                       vm->ip = IMAGE_SIZE;
                       break;
             default:  vm->ports[5] = 0;
           }
         }

         if (vm->ports[8] != 0) {
           vm->ports[0] = 1;
           switch (vm->ports[8]) {
             case -1: rsocket(vm);
                      vm->ports[8] = 0;
                      break;
             case -2: rbind(vm);
                      vm->ports[8] = 0;
                      break;
             case -3: rlisten(vm);
                      vm->ports[8] = 0;
                      break;
             case -4: raccept(vm);
                      vm->ports[8] = 0;
                      break;
             case -5: rclose(vm);
                      vm->ports[8] = 0;
                      break;
             case -6: rsend(vm);
                      vm->ports[8] = 0;
                      break;
             case -7: rrecv(vm);
                      vm->ports[8] = 0;
                      break;
             case -8: rconnect(vm);
                      vm->ports[8] = 0;
                      break;
             default: vm->ports[8] = 0;
           }
           vm->ports[8] = 0;
         }
         break;
    default:
         vm->rsp++;
         TORS = vm->ip;
         vm->ip = vm->image[vm->ip] - 1;

         if (vm->ip < 0)
           vm->ip = IMAGE_SIZE;
         else {
           if (vm->image[vm->ip+1] == 0)
             vm->ip++;
           if (vm->image[vm->ip+1] == 0)
             vm->ip++;
         }
         break;
  }
  vm->ports[3] = 1;
}
Example #3
0
//! This function read the playlist's entry at a specific position
//!
//! @param u16_position Position in play list.
//! @param sz_path      The address of the string where is stored the information.
//! @param u16_size_line  The length of the path.
//!
bool pl_nav_readentry(uint16_t u16_position, FS_STRING *sz_path, uint16_t *u16_size_line )
{
  uint8_t nav_id_save;
  uint16_t u16_current_pos;
  uint32_t u32_file_pos;

  // Set output to NULL to specify if there is an error
  *sz_path = NULL;

  // Position out of range
  if ((0 == u16_position)
   || (pl_g_u16_list_size < u16_position))
  {
     fs_g_status = FS_ERR_PL_OUT_LST;
     return false;
  }

  // Go to play list file navigator
  nav_id_save = nav_get();
  nav_select(FS_NAV_ID_PLAYLIST);

  // Save current file position
  u32_file_pos = file_getpos();

  if (pl_g_u16_list_sel > u16_position)
  {
    // Go to the beginning of the text file
    reader_txt_beg();
    u16_current_pos = 0;
  }
  else
  {
    u16_current_pos = pl_g_u16_list_sel;
  }

  while(u16_current_pos != u16_position)
  {
    if (file_eof())
    {
      // Restore file position
      file_seek(u32_file_pos, FS_SEEK_SET);
      // Reselect the previous navigator
      nav_select(nav_id_save);
      return false;
    }
    if (u16_current_pos+1 == u16_position)
    {
      if (pl_main_readline(PL_MAIN_READLINE_OPT_GOTOPATH, nav_id_save, sz_path, u16_size_line))
        break;
    }
    else if (pl_main_readline(PL_MAIN_READLINE_OPT_CHECKLINE, 0, NULL, NULL))
      u16_current_pos++; // Add a file
  }

  // Restore file position
  file_seek(u32_file_pos, FS_SEEK_SET);
  // Reselect the previous navigator
  nav_select(nav_id_save);

  return true;
}
Example #4
0
//! This function reads and checks the next line
//!
//! @param opt         PL_MAIN_READLINE_OPT_CHECKLINE to check the next line in the file.\n
//!                     PL_MAIN_READLINE_OPT_READSTRING to read the string in the text file.\n
//!                     PL_MAIN_READLINE_OPT_GOTOPATH to read, check and goto the path.
//! @param id_nav       ID navigator to update with the selected file (ignore if b_gotopatch == false)
//! @param sz_path      Address of the string returned. It is used only if PL_MAIN_READLINE_OPT_READSTRING or
//!                     PL_MAIN_READLINE_OPT_GOTOPATH options are specified.
//! @param u16_size_line  The length of the path. If this parameter is NULL, then the length is not returned.
//!
//! @return    true  if a line with a correct path
//!            false line ignored or end of file
//!
bool  pl_main_readline( readline_opt_t opt, uint8_t id_nav, FS_STRING *sz_path, uint16_t *u16_size_line )
{
   uint16_t line_beg[8];           // Contains first characters of the line
   uint32_t u32_file_pos;
   uint16_t u16_alt_length = 0;
   uint8_t  u8_pos_path_in_line = 0;

   // Set output to NULL to specify if there is an error
   *sz_path = NULL;

   // Read the 3 first char in the line
   u32_file_pos = file_getpos();
   if( E_PL_M3U == pl_g_list_type )
   {
      // M3U path lines = "path\file"
      // M3U comment lines = "#..."
      u16_alt_length = reader_txt_get_line( true, (FS_STRING)line_beg, 2 );
      if( (2 > u16_alt_length)   // The line size is not correct
      ||  ('#' == line_beg[0]) ) // It is a comment line
      {
         return false;
      }
      u8_pos_path_in_line=0;
   }
   if( (E_PL_PLS == pl_g_list_type) || (E_PL_SMP == pl_g_list_type) )
   {
      // PLS path lines = "Filexxx=path\file"
      // SMP path lines = "File=path\file"
      u16_alt_length = reader_txt_get_line( true, (FS_STRING)line_beg, 8 );
      if(6 > u16_alt_length)     // The line size can't contain a path line
         return false;
      // Check if it is a path line
      if( ('F' != line_beg[0])
      ||  ('i' != line_beg[1])
      ||  ('l' != line_beg[2])
      ||  ('e' != line_beg[3]) )
      {
         return false;
      }
      u8_pos_path_in_line=5;
      if('=' != line_beg[4])
      {
         u8_pos_path_in_line++;
         if('=' != line_beg[5])
         {
            u8_pos_path_in_line++;
            if('=' != line_beg[6])
            {
               u8_pos_path_in_line++;
               if('=' != line_beg[7])
                  return false;
            }
         }
      }
   }
   // Here, the line contains a path

   // Store the length of the line if a buffer is set
   if (u16_size_line)
     *u16_size_line = u16_alt_length - u8_pos_path_in_line;
   if (opt == PL_MAIN_READLINE_OPT_CHECKLINE)
      return true;
   // else go to path

   // Read all characters in line
   file_seek( u32_file_pos, FS_SEEK_SET );
   *sz_path = PLAYLIST_BUF_ALLOC( u16_alt_length * (Is_unicode? 2 : 1 ) );
   if( NULL == *sz_path )
      return false;   // no enough memory, impossible to store the path but path present in line
   if( 0 == reader_txt_get_line( (FS_UNICODE==true), *sz_path, u16_alt_length ) )
      return false;  // Error during the read
   if( 0 != u8_pos_path_in_line )
   {
      // Shift the path to the beginning of the buffer
      memmove(*sz_path, *sz_path + u8_pos_path_in_line * ((FS_UNICODE==true) ? 2 : 1),
              (u16_alt_length - u8_pos_path_in_line) * ((FS_UNICODE==true) ? 2 : 1));
   }
   if (opt == PL_MAIN_READLINE_OPT_READSTRING)
     return true;

   // Update the navigator with the path of play list file, because the path is relative at this one
   nav_copy( id_nav );
   nav_select( id_nav );
   // Go to the path included in the line
   if( !nav_setcwd( (FS_STRING) *sz_path , false, false ) )
   {
      // path no found then path is dead -> reset list to deselect a file
      nav_filelist_reset();
   }
   nav_select( FS_NAV_ID_PLAYLIST );

   return true;
}
Example #5
0
//! This function read the playlist's entry at a specific position.\n
//! It is implemented as a non-blocking function.
//!
//! @param data         This data has to be set to 0 if non-caching options are
//!                     used.
//! @param u16_position Position in play list.
//! @param sz_path      The address of the string where is stored the information.
//! @param u16_size_line  The length of the path.
//! @param u16_n        The number of line to read at one time
//!
bool pl_nav_readentry_non_blocking(pl_nav_readentry_context_t *data, uint16_t u16_position, FS_STRING *sz_path, uint16_t *u16_size_line, uint16_t u16_n)
{
  ai_async_context_t ctx;
  uint16_t u16_current_n;
  typedef enum
  {
    STATE_INITIALIZATION = 0,
    STATE_SET_POS,
    STATE_READ_ENTRY
  } state_t;
  bool b_update;

  // If false, means it is the first call
  if (!ai_async_context_pop(&ctx))
    ctx.state = (state_t) STATE_INITIALIZATION;
  // By default set the status to DONE
  ctx.status = CMD_DONE;

  switch((state_t) ctx.state)
  {
  // Initialization
  case STATE_INITIALIZATION:
    // Set output to NULL to specify if there is an error
    *sz_path = NULL;
    // Position out of range
    if (u16_position == 0)
    {
      fs_g_status = FS_ERR_PL_OUT_LST;
      return false;
    }
    // Go to play list file navigator
    data->nav_id_saved = nav_get();
    nav_select(FS_NAV_ID_PLAYLIST);
    // Save current file position
    data->u32_file_pos_saved = file_getpos();

    // In this case it means the context data is already filled with entry
    // information for this specific playlist. That is the reason why it is
    // important to fill this structure with zeros if non-caching options are
    // used.
    b_update = true;
    if (data->fs_entry.u8_open_mode)
    {
      if (data->u16_current_pos + 1 <= u16_position)
        b_update = false;
    }
    if (b_update)
    {
      // Go to the beginning of the text file
      reader_txt_beg();
      data->u16_current_pos = 0;
      // Store the info of the entry
      memcpy(&(data->fs_entry), &fs_g_nav_entry, sizeof(data->fs_entry));
    }
    ctx.status = CMD_EXECUTING;
    ctx.state = (state_t) STATE_SET_POS;
    break;

  case STATE_SET_POS:
    nav_select(FS_NAV_ID_PLAYLIST);
    // Restore the info of the entry
    memcpy(&fs_g_nav_entry, &(data->fs_entry), sizeof(fs_g_nav_entry));
    // Look for the "u16_n"th next lines on the file
    u16_current_n = 0;
    while ((data->u16_current_pos + 1 != u16_position) &&
           !file_eof() &&
           u16_current_n < u16_n)
    {
      if (pl_main_readline(PL_MAIN_READLINE_OPT_CHECKLINE, 0, NULL, NULL))
        data->u16_current_pos++;
      u16_current_n++;
    }
    // If end of file
    if (file_eof())
    {
      // Restore file position
      file_seek(data->u32_file_pos_saved, FS_SEEK_SET);
      // Reselect the previous navigator
      nav_select(data->nav_id_saved);
      return false;
    }
    // If the file has been found
    ctx.status = CMD_EXECUTING;
    if (data->u16_current_pos + 1 == u16_position)
      ctx.state = (state_t) STATE_READ_ENTRY;
    // Else continue seeking...
    // Store the info of the entry
    memcpy(&(data->fs_entry), &fs_g_nav_entry, sizeof(data->fs_entry));
    break;

  case STATE_READ_ENTRY:
    nav_select(FS_NAV_ID_PLAYLIST);
    u16_current_n = 0;
    b_update = false;
    while (!file_eof() && u16_current_n < u16_n)
    {
      if ((b_update = pl_main_readline(PL_MAIN_READLINE_OPT_GOTOPATH, data->nav_id_saved, sz_path, u16_size_line)))
        break;
      u16_current_n++;
    }
    // Need to retry
    if (u16_current_n >= u16_n)
    {
      ctx.status = CMD_EXECUTING;
      break;
    }
    // If it is the end of the file
    if (file_eof() && !b_update)
    {
      // Restore file position
      file_seek(data->u32_file_pos_saved, FS_SEEK_SET);
      // Reselect the previous navigator
      nav_select(data->nav_id_saved);
      return false;
    }

    // Store positions
    data->u16_current_pos = u16_position;
    // Store the info of the entry
    memcpy(&(data->fs_entry), &fs_g_nav_entry, sizeof(data->fs_entry));

    // Restore file position
    file_seek(data->u32_file_pos_saved, FS_SEEK_SET);
    // Reselect the previous navigator
    nav_select(data->nav_id_saved);
    break;
  }

  if (ctx.status == CMD_EXECUTING)
  {
    if (!ai_async_context_push(&ctx))
      return false;
  }

  return true;
}