winebuild: Add helper functions for writing binary data to a file.
This commit is contained in:
parent
b935cc210c
commit
47497cb26a
|
@ -270,11 +270,23 @@ extern const char *input_buffer_filename;
|
||||||
extern const unsigned char *input_buffer;
|
extern const unsigned char *input_buffer;
|
||||||
extern size_t input_buffer_pos;
|
extern size_t input_buffer_pos;
|
||||||
extern size_t input_buffer_size;
|
extern size_t input_buffer_size;
|
||||||
|
extern unsigned char *output_buffer;
|
||||||
|
extern size_t output_buffer_pos;
|
||||||
|
extern size_t output_buffer_size;
|
||||||
|
|
||||||
extern void init_input_buffer( const char *file );
|
extern void init_input_buffer( const char *file );
|
||||||
|
extern void init_output_buffer(void);
|
||||||
|
extern void flush_output_buffer(void);
|
||||||
extern unsigned char get_byte(void);
|
extern unsigned char get_byte(void);
|
||||||
extern unsigned short get_word(void);
|
extern unsigned short get_word(void);
|
||||||
extern unsigned int get_dword(void);
|
extern unsigned int get_dword(void);
|
||||||
|
extern void put_data( const void *data, size_t size );
|
||||||
|
extern void put_byte( unsigned char val );
|
||||||
|
extern void put_word( unsigned short val );
|
||||||
|
extern void put_dword( unsigned int val );
|
||||||
|
extern void put_qword( unsigned int val );
|
||||||
|
extern void put_pword( unsigned int val );
|
||||||
|
extern void align_output( unsigned int align );
|
||||||
|
|
||||||
/* global variables */
|
/* global variables */
|
||||||
|
|
||||||
|
|
|
@ -80,9 +80,6 @@ struct res_tree
|
||||||
unsigned int nb_types; /* total number of types */
|
unsigned int nb_types; /* total number of types */
|
||||||
};
|
};
|
||||||
|
|
||||||
static unsigned char *file_out_pos; /* current position in output resource file */
|
|
||||||
static unsigned char *file_out_end; /* end of output buffer */
|
|
||||||
|
|
||||||
/* size of a resource directory with n entries */
|
/* size of a resource directory with n entries */
|
||||||
#define RESOURCE_DIR_SIZE (4 * sizeof(unsigned int))
|
#define RESOURCE_DIR_SIZE (4 * sizeof(unsigned int))
|
||||||
#define RESOURCE_DIR_ENTRY_SIZE (2 * sizeof(unsigned int))
|
#define RESOURCE_DIR_ENTRY_SIZE (2 * sizeof(unsigned int))
|
||||||
|
@ -152,25 +149,6 @@ static void get_string( struct string_id *str )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* put a word into the resource file */
|
|
||||||
static void put_word( unsigned short val )
|
|
||||||
{
|
|
||||||
if (byte_swapped) val = (val << 8) | (val >> 8);
|
|
||||||
*(unsigned short *)file_out_pos = val;
|
|
||||||
file_out_pos += sizeof(unsigned short);
|
|
||||||
assert( file_out_pos <= file_out_end );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* put a dword into the resource file */
|
|
||||||
static void put_dword( unsigned int val )
|
|
||||||
{
|
|
||||||
if (byte_swapped)
|
|
||||||
val = ((val << 24) | ((val << 8) & 0x00ff0000) | ((val >> 8) & 0x0000ff00) | (val >> 24));
|
|
||||||
*(unsigned int *)file_out_pos = val;
|
|
||||||
file_out_pos += sizeof(unsigned int);
|
|
||||||
assert( file_out_pos <= file_out_end );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* put a string into the resource file */
|
/* put a string into the resource file */
|
||||||
static void put_string( const struct string_id *str )
|
static void put_string( const struct string_id *str )
|
||||||
{
|
{
|
||||||
|
@ -516,26 +494,15 @@ static unsigned int get_resource_header_size( const struct resource *res )
|
||||||
/* output the resources into a .o file */
|
/* output the resources into a .o file */
|
||||||
void output_res_o_file( DLLSPEC *spec )
|
void output_res_o_file( DLLSPEC *spec )
|
||||||
{
|
{
|
||||||
unsigned int i, total_size;
|
unsigned int i;
|
||||||
unsigned char *data;
|
|
||||||
char *res_file = NULL;
|
char *res_file = NULL;
|
||||||
int fd, err;
|
int fd, err;
|
||||||
|
|
||||||
if (!spec->nb_resources) fatal_error( "--resources mode needs at least one resource file as input\n" );
|
if (!spec->nb_resources) fatal_error( "--resources mode needs at least one resource file as input\n" );
|
||||||
if (!output_file_name) fatal_error( "No output file name specified\n" );
|
if (!output_file_name) fatal_error( "No output file name specified\n" );
|
||||||
|
|
||||||
total_size = 32; /* header */
|
|
||||||
|
|
||||||
for (i = 0; i < spec->nb_resources; i++)
|
|
||||||
{
|
|
||||||
total_size += (get_resource_header_size( &spec->resources[i] ) + 3) & ~3;
|
|
||||||
total_size += (spec->resources[i].data_size + 3) & ~3;
|
|
||||||
}
|
|
||||||
data = xmalloc( total_size );
|
|
||||||
|
|
||||||
byte_swapped = 0;
|
byte_swapped = 0;
|
||||||
file_out_pos = data;
|
init_output_buffer();
|
||||||
file_out_end = data + total_size;
|
|
||||||
|
|
||||||
put_dword( 0 ); /* ResSize */
|
put_dword( 0 ); /* ResSize */
|
||||||
put_dword( 32 ); /* HeaderSize */
|
put_dword( 32 ); /* HeaderSize */
|
||||||
|
@ -557,34 +524,30 @@ void output_res_o_file( DLLSPEC *spec )
|
||||||
put_dword( (header_size + 3) & ~3 );
|
put_dword( (header_size + 3) & ~3 );
|
||||||
put_string( &spec->resources[i].type );
|
put_string( &spec->resources[i].type );
|
||||||
put_string( &spec->resources[i].name );
|
put_string( &spec->resources[i].name );
|
||||||
if ((unsigned long)file_out_pos & 2) put_word( 0 );
|
align_output( 4 );
|
||||||
put_dword( 0 );
|
put_dword( 0 );
|
||||||
put_word( spec->resources[i].mem_options );
|
put_word( spec->resources[i].mem_options );
|
||||||
put_word( spec->resources[i].lang );
|
put_word( spec->resources[i].lang );
|
||||||
put_dword( 0 );
|
put_dword( 0 );
|
||||||
put_dword( 0 );
|
put_dword( 0 );
|
||||||
memcpy( file_out_pos, spec->resources[i].data, spec->resources[i].data_size );
|
put_data( spec->resources[i].data, spec->resources[i].data_size );
|
||||||
file_out_pos += spec->resources[i].data_size;
|
align_output( 4 );
|
||||||
while ((unsigned long)file_out_pos & 3) *file_out_pos++ = 0;
|
|
||||||
}
|
}
|
||||||
assert( file_out_pos == file_out_end );
|
|
||||||
|
|
||||||
/* if the output file name is a .res too, don't run the results through windres */
|
/* if the output file name is a .res too, don't run the results through windres */
|
||||||
if (strendswith( output_file_name, ".res"))
|
if (strendswith( output_file_name, ".res"))
|
||||||
{
|
{
|
||||||
if ((fd = open( output_file_name, O_WRONLY|O_CREAT|O_TRUNC, 0666 )) == -1)
|
flush_output_buffer();
|
||||||
fatal_error( "Cannot create %s\n", output_file_name );
|
return;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
res_file = get_temp_file_name( output_file_name, ".res" );
|
||||||
res_file = get_temp_file_name( output_file_name, ".res" );
|
if ((fd = open( res_file, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0600 )) == -1)
|
||||||
if ((fd = open( res_file, O_WRONLY|O_CREAT|O_TRUNC, 0600 )) == -1)
|
fatal_error( "Cannot create %s\n", res_file );
|
||||||
fatal_error( "Cannot create %s\n", res_file );
|
if (write( fd, output_buffer, output_buffer_pos ) != output_buffer_pos)
|
||||||
}
|
|
||||||
if (write( fd, data, total_size ) != total_size)
|
|
||||||
fatal_error( "Error writing to %s\n", res_file );
|
fatal_error( "Error writing to %s\n", res_file );
|
||||||
close( fd );
|
close( fd );
|
||||||
free( data );
|
free( output_buffer );
|
||||||
|
|
||||||
if (res_file)
|
if (res_file)
|
||||||
{
|
{
|
||||||
|
|
|
@ -387,6 +387,18 @@ const char *input_buffer_filename;
|
||||||
const unsigned char *input_buffer;
|
const unsigned char *input_buffer;
|
||||||
size_t input_buffer_pos;
|
size_t input_buffer_pos;
|
||||||
size_t input_buffer_size;
|
size_t input_buffer_size;
|
||||||
|
unsigned char *output_buffer;
|
||||||
|
size_t output_buffer_pos;
|
||||||
|
size_t output_buffer_size;
|
||||||
|
|
||||||
|
static void check_output_buffer_space( size_t size )
|
||||||
|
{
|
||||||
|
if (output_buffer_pos + size >= output_buffer_size)
|
||||||
|
{
|
||||||
|
output_buffer_size = max( output_buffer_size * 2, output_buffer_pos + size );
|
||||||
|
output_buffer = xrealloc( output_buffer, output_buffer_size );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void init_input_buffer( const char *file )
|
void init_input_buffer( const char *file )
|
||||||
{
|
{
|
||||||
|
@ -411,6 +423,20 @@ void init_input_buffer( const char *file )
|
||||||
byte_swapped = 0;
|
byte_swapped = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void init_output_buffer(void)
|
||||||
|
{
|
||||||
|
output_buffer_size = 1024;
|
||||||
|
output_buffer_pos = 0;
|
||||||
|
output_buffer = xmalloc( output_buffer_size );
|
||||||
|
}
|
||||||
|
|
||||||
|
void flush_output_buffer(void)
|
||||||
|
{
|
||||||
|
if (fwrite( output_buffer, 1, output_buffer_pos, output_file ) != output_buffer_pos)
|
||||||
|
fatal_error( "Error writing to %s\n", output_file_name );
|
||||||
|
free( output_buffer );
|
||||||
|
}
|
||||||
|
|
||||||
unsigned char get_byte(void)
|
unsigned char get_byte(void)
|
||||||
{
|
{
|
||||||
if (input_buffer_pos >= input_buffer_size)
|
if (input_buffer_pos >= input_buffer_size)
|
||||||
|
@ -443,6 +469,63 @@ unsigned int get_dword(void)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void put_data( const void *data, size_t size )
|
||||||
|
{
|
||||||
|
check_output_buffer_space( size );
|
||||||
|
memcpy( output_buffer + output_buffer_pos, data, size );
|
||||||
|
output_buffer_pos += size;
|
||||||
|
}
|
||||||
|
|
||||||
|
void put_byte( unsigned char val )
|
||||||
|
{
|
||||||
|
check_output_buffer_space( 1 );
|
||||||
|
output_buffer[output_buffer_pos++] = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
void put_word( unsigned short val )
|
||||||
|
{
|
||||||
|
if (byte_swapped) val = (val << 8) | (val >> 8);
|
||||||
|
put_data( &val, sizeof(val) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void put_dword( unsigned int val )
|
||||||
|
{
|
||||||
|
if (byte_swapped)
|
||||||
|
val = ((val << 24) | ((val << 8) & 0x00ff0000) | ((val >> 8) & 0x0000ff00) | (val >> 24));
|
||||||
|
put_data( &val, sizeof(val) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void put_qword( unsigned int val )
|
||||||
|
{
|
||||||
|
if (byte_swapped)
|
||||||
|
{
|
||||||
|
put_dword( 0 );
|
||||||
|
put_dword( val );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
put_dword( val );
|
||||||
|
put_dword( 0 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* pointer-sized word */
|
||||||
|
void put_pword( unsigned int val )
|
||||||
|
{
|
||||||
|
if (get_ptr_size() == 8) put_qword( val );
|
||||||
|
else put_dword( val );
|
||||||
|
}
|
||||||
|
|
||||||
|
void align_output( unsigned int align )
|
||||||
|
{
|
||||||
|
size_t size = align - (output_buffer_pos % align);
|
||||||
|
|
||||||
|
if (size == align) return;
|
||||||
|
check_output_buffer_space( size );
|
||||||
|
memset( output_buffer + output_buffer_pos, 0, size );
|
||||||
|
output_buffer_pos += size;
|
||||||
|
}
|
||||||
|
|
||||||
/* output a standard header for generated files */
|
/* output a standard header for generated files */
|
||||||
void output_standard_file_header(void)
|
void output_standard_file_header(void)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue