⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ftsystem.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 2 页
字号:
    FreeMem ( sysfile, sizeof ( struct SysFile ));

    stream->descriptor.pointer = NULL;
    stream->size               = 0;
    stream->base               = 0;
  }


  /*************************************************************************/
  /*                                                                       */
  /* <Function>                                                            */
  /*    ft_amiga_stream_io                                                 */
  /*                                                                       */
  /* <Description>                                                         */
  /*    The function to open a stream.                                     */
  /*                                                                       */
  /* <Input>                                                               */
  /*    stream :: A pointer to the stream object.                          */
  /*                                                                       */
  /*    offset :: The position in the data stream to start reading.        */
  /*                                                                       */
  /*    buffer :: The address of buffer to store the read data.            */
  /*                                                                       */
  /*    count  :: The number of bytes to read from the stream.             */
  /*                                                                       */
  /* <Return>                                                              */
  /*    The number of bytes actually read.                                 */
  /*                                                                       */
  FT_CALLBACK_DEF( unsigned long )
  ft_amiga_stream_io( FT_Stream       stream,
                      unsigned long   offset,
                      unsigned char*  buffer,
                      unsigned long   count )
  {
    struct SysFile* sysfile;
    unsigned long   read_bytes;

    if ( count != 0 )
    {
      sysfile = STREAM_FILE( stream );

      /* handle the seek */
      if ( (offset < sysfile->iobuf_start) || (offset + count > sysfile->iobuf_end) )
      {
        /* requested offset implies we need a buffer refill */
        if ( !sysfile->iobuf_end || offset != sysfile->iobuf_end )
        {
          /* a physical seek is necessary */
          Seek( sysfile->file, offset, OFFSET_BEGINNING );
        }
        sysfile->iobuf_start = offset;
        sysfile->iobuf_end = 0; /* trigger a buffer refill */
      }

      /* handle the read */
      if ( offset + count <= sysfile->iobuf_end )
      {
        /* we have buffer and requested bytes are all inside our buffer */
        CopyMem( &sysfile->iobuf[offset - sysfile->iobuf_start], buffer, count );
        read_bytes = count;
      }
      else
      {
        /* (re)fill buffer */
        if ( count <= IOBUF_SIZE )
        {
          /* requested bytes is a subset of the buffer */
          read_bytes = Read( sysfile->file, sysfile->iobuf, IOBUF_SIZE );
          if ( read_bytes == -1UL )
          {
            /* error */
            read_bytes = 0;
          }
          else
          {
            sysfile->iobuf_end = offset + read_bytes;
            CopyMem( sysfile->iobuf, buffer, count );
            if ( read_bytes > count )
            {
              read_bytes = count;
            }
          }
        }
        else
        {
          /* we actually need more than our buffer can hold, so we decide
          ** to do a single big read, and then copy the last IOBUF_SIZE
          ** bytes of that to our internal buffer for later use */
          read_bytes = Read( sysfile->file, buffer, count );
          if ( read_bytes == -1UL )
          {
            /* error */
            read_bytes = 0;
          }
          else
          {
            ULONG bufsize;

            bufsize = ( read_bytes > IOBUF_SIZE ) ? IOBUF_SIZE : read_bytes;
            sysfile->iobuf_end = offset + read_bytes;
            sysfile->iobuf_start = sysfile->iobuf_end - bufsize;
            CopyMem( &buffer[read_bytes - bufsize] , sysfile->iobuf, bufsize );
          }
        }
      }
    }
    else
    {
      read_bytes = 0;
    }

    return read_bytes;
  }


  /* documentation is in ftobjs.h */

  FT_BASE_DEF( FT_Error )
  FT_Stream_Open( FT_Stream    stream,
                  const char*  filepathname )
  {
    struct FileInfoBlock*  fib;
    struct SysFile*        sysfile;


    if ( !stream )
      return FT_Err_Invalid_Stream_Handle;

#ifdef __amigaos4__
    sysfile = AllocMem ( sizeof (struct SysFile ), MEMF_SHARED );
#else
    sysfile = AllocMem ( sizeof (struct SysFile ), MEMF_PUBLIC );
#endif
    if ( !sysfile )
    {
      FT_ERROR(( "FT_Stream_Open:" ));
      FT_ERROR(( " could not open `%s'\n", filepathname ));

      return FT_Err_Cannot_Open_Resource;
    }
    sysfile->file = Open( (STRPTR)filepathname, MODE_OLDFILE );
    if ( !sysfile->file )
    {
      FreeMem ( sysfile, sizeof ( struct SysFile ));
      FT_ERROR(( "FT_Stream_Open:" ));
      FT_ERROR(( " could not open `%s'\n", filepathname ));

      return FT_Err_Cannot_Open_Resource;
    }

    fib = AllocDosObject( DOS_FIB, NULL );
    if ( !fib )
    {
      Close ( sysfile->file );
      FreeMem ( sysfile, sizeof ( struct SysFile ));
      FT_ERROR(( "FT_Stream_Open:" ));
      FT_ERROR(( " could not open `%s'\n", filepathname ));

      return FT_Err_Cannot_Open_Resource;
    }
    if ( !( ExamineFH( sysfile->file, fib ) ) )
    {
      FreeDosObject( DOS_FIB, fib );
      Close ( sysfile->file );
      FreeMem ( sysfile, sizeof ( struct SysFile ));
      FT_ERROR(( "FT_Stream_Open:" ));
      FT_ERROR(( " could not open `%s'\n", filepathname ));

      return FT_Err_Cannot_Open_Resource;
    }
    stream->size = fib->fib_Size;
    FreeDosObject( DOS_FIB, fib );

    stream->descriptor.pointer = (void *)sysfile;
    stream->pathname.pointer   = (char*)filepathname;
    sysfile->iobuf_start       = 0;
    sysfile->iobuf_end         = 0;
    stream->pos                = 0;

    stream->read  = ft_amiga_stream_io;
    stream->close = ft_amiga_stream_close;

    FT_TRACE1(( "FT_Stream_Open:" ));
    FT_TRACE1(( " opened `%s' (%ld bytes) successfully\n",
                filepathname, stream->size ));

    return FT_Err_Ok;
  }


#ifdef FT_DEBUG_MEMORY

  extern FT_Int
  ft_mem_debug_init( FT_Memory  memory );

  extern void
  ft_mem_debug_done( FT_Memory  memory );

#endif


  /* documentation is in ftobjs.h */

  FT_BASE_DEF( FT_Memory )
  FT_New_Memory( void )
  {
    FT_Memory  memory;


#ifdef __amigaos4__
    memory = (FT_Memory)AllocVec( sizeof ( *memory ), MEMF_SHARED );
#else
    memory = (FT_Memory)AllocVec( sizeof ( *memory ), MEMF_PUBLIC );
#endif
    if ( memory )
    {
#ifdef __amigaos4__
      memory->user = CreatePool( MEMF_SHARED, 16384, 16384 );
#else
      memory->user = CreatePool( MEMF_PUBLIC, 16384, 16384 );
#endif
      if ( memory->user == NULL )
      {
        FreeVec( memory );
        memory = NULL;
      }
      else
      {
        memory->alloc   = ft_alloc;
        memory->realloc = ft_realloc;
        memory->free    = ft_free;
#ifdef FT_DEBUG_MEMORY
        ft_mem_debug_init( memory );
#endif
      }
    }

    return memory;
  }


  /* documentation is in ftobjs.h */

  FT_BASE_DEF( void )
  FT_Done_Memory( FT_Memory  memory )
  {
#ifdef FT_DEBUG_MEMORY
    ft_mem_debug_done( memory );
#endif

    DeletePool( memory->user );
    FreeVec( memory );
  }

/*
Local Variables:
coding: latin-1
End:
*/
/* END */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -