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

📄 xpackfile.cpp

📁 lua脚本语言调用allegro游戏程序库的接口-跨平台
💻 CPP
字号:

#include <stdio.h>
#include <string.h>
#include <allegro.h>

#include "queue.h"

//-------------------------------------------------------------------------------------------
#define max(a,b)  (((a) > (b)) ? (a) : (b))
#define min(a,b)  (((a) < (b)) ? (a) : (b))
//-------------------------------------------------------------------------------------------


#define MEMFILE_ID 0x544D454DL

#define MEMFILE_READ  1
#define MEMFILE_WRITE 2


typedef struct { int ID,filetype; Queue oq; void* input; long input_size;long file_pos; void** output; long* output_size; } mem_packfile;


//--------------------------------------------------------------------------------------
extern "C" {
PACKFILE* mem_fopen_read_buffer(void* p_input,long p_input_size);
PACKFILE* mem_fopen_write_buffer(void** p_output,long* p_output_size);

int  mem_fclose(void* userdata);
int  mem_fgetc(void* userdata);
int  mem_ungetc(int c,void* userdata);
long mem_fread(void* p, long n, void* userdata);
int  mem_putc(int c, void* userdata);
long mem_fwrite(AL_CONST void *p, long n, void *userdata);
int  mem_fseek(void* userdata,int offset);
int  mem_feof(void* userdata);
int  mem_ferror(void* userdata);


const struct PACKFILE_VTABLE memp_vtable=
{
   &mem_fclose,
   &mem_fgetc,
   &mem_ungetc,
   &mem_fread,
   &mem_putc,
   &mem_fwrite,
   &mem_fseek,
   &mem_feof,
   &mem_ferror
};


//--------------------------------------------------------------------------------------
PACKFILE* mem_fopen_read_buffer(void* p_input,long p_input_size)
{
   PACKFILE* result=NULL;

   if ( p_input==NULL || p_input_size<=0 ) return NULL;

   mem_packfile* mp= new mem_packfile;

   if (!mp) return NULL;

   mp->ID=           MEMFILE_ID;
   mp->filetype=     MEMFILE_READ;
   mp->input=        p_input;
   mp->input_size=   p_input_size;
   mp->file_pos=     0;
   mp->output=       NULL;
   mp->output_size=  NULL;

   result = pack_fopen_vtable( &memp_vtable, (void*) mp );
   
   if (!result) delete mp;

   return result;
}



//--------------------------------------------------------------------------------------
// output and output_size are filled when memfile is closed by calling mem_fclose
PACKFILE* mem_fopen_write_buffer(void** p_output,long* p_output_size)
{
   PACKFILE* result=NULL;

   if (p_output==NULL || p_output_size==NULL) return NULL;

   mem_packfile* mp= new mem_packfile;

   if (!mp) return NULL;


   mp->ID=           MEMFILE_ID;
   mp->filetype=     MEMFILE_WRITE;
   mp->input=        NULL;
   mp->input_size=   0;
   mp->file_pos=     0;
   mp->output=       p_output;
   mp->output_size=  p_output_size;

   result = pack_fopen_vtable( &memp_vtable, (void*) mp );
   
   if (!result) delete mp;

   return result;
}


//--------------------------------------------------------------------------------------
int  mem_fclose(void* userdata)
{
   mem_packfile* mp= (mem_packfile*) userdata;
   if (mp->ID!=MEMFILE_ID) return EOF;

   if (mp->filetype==MEMFILE_READ) 
   {
      delete mp;
      return 0; 
   }
   else
   if (mp->filetype==MEMFILE_WRITE) 
   {
      int total_bytes=    mp->oq.GetLength();
      int bytes_written=  0;
      void* buffer=       NULL;

      if (total_bytes>0)
      {
         buffer= malloc(total_bytes);
         if (buffer)
         {
            bytes_written = mp->oq.Read(buffer,total_bytes);
            (*mp->output)=       buffer;   //user is responsible to release the buffer
            (*mp->output_size)=  bytes_written;
         }
      }

      if (!buffer)
      {
         (*mp->output)=       NULL;
         (*mp->output_size)=  0;
      }
      
      delete mp;
      return 0; 
   }

return EOF;
}


//--------------------------------------------------------------------------------------
int  mem_fgetc(void* userdata)
{
   mem_packfile* mp= (mem_packfile*) userdata;
   if (mp->ID!=MEMFILE_ID || mp->filetype!=MEMFILE_READ) return EOF;
   
   unsigned char* buffer= (unsigned char*) mp->input;
   int result;
   
   if ( mp->file_pos < mp->input_size && mp->file_pos>=0 )
   {
      result= buffer[mp->file_pos];
      mp->file_pos++;
   }
   else
      result=EOF;

   return result;
}

//--------------------------------------------------------------------------------------
int  mem_ungetc(int c,void* userdata)
{
   mem_packfile* mp= (mem_packfile*) userdata;
   if (mp->ID!=MEMFILE_ID || mp->filetype!=MEMFILE_READ) return EOF;

   if (mp->file_pos>0) mp->file_pos--;

   return c;
}

//--------------------------------------------------------------------------------------
long mem_fread(void* p, long n, void* userdata)
{
   mem_packfile* mp= (mem_packfile*) userdata;
   if (mp->ID!=MEMFILE_ID || mp->filetype!=MEMFILE_READ) return EOF;
   
   unsigned char* buffer= (unsigned char*) mp->input;

   int bytes_to_read= max(0,min(n, (mp->input_size - mp->file_pos) ) ); 
   
   if ( bytes_to_read>0)
   {
      memcpy(p,(buffer+mp->file_pos),bytes_to_read);
      mp->file_pos+=bytes_to_read;
   }
   return bytes_to_read;
}

//--------------------------------------------------------------------------------------
int  mem_putc(int c, void* userdata)
{
   mem_packfile* mp= (mem_packfile*) userdata;
   if (mp->ID!=MEMFILE_ID || mp->filetype!=MEMFILE_WRITE) return EOF;

   mp->oq.Write(&c,1);

   return c;
}

//--------------------------------------------------------------------------------------
long mem_fwrite(AL_CONST void *p, long n, void *userdata)
{
   mem_packfile* mp= (mem_packfile*) userdata;
   if (mp->ID!=MEMFILE_ID || mp->filetype!=MEMFILE_WRITE) return EOF;

   int written=mp->oq.Write((void*) p,n);

   return written;
}

//--------------------------------------------------------------------------------------
int mem_fseek(void* userdata,int relative_offset)
{
   mem_packfile* mp= (mem_packfile*) userdata;
   
   if (mp->ID!=MEMFILE_ID || mp->filetype!=MEMFILE_READ) return EOF;

   if (relative_offset<0) return EOF;

   if ( (mp->file_pos + relative_offset)> mp->input_size ) return EOF;

   mp->file_pos += relative_offset;

   return 0;
}

//--------------------------------------------------------------------------------------
int mem_feof(void* userdata)
{
   mem_packfile* mp= (mem_packfile*) userdata;
   if (mp->ID!=MEMFILE_ID || mp->filetype!=MEMFILE_READ) return EOF;
   
   if (mp->file_pos < mp->input_size) 
      return 0;
   else 
      return 1;
}

//--------------------------------------------------------------------------------------
int mem_ferror(void* userdata)
{
   //not yet implemented
   return 0;
}


}

⌨️ 快捷键说明

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