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 size_t input_buffer_pos;
|
||||
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_output_buffer(void);
|
||||
extern void flush_output_buffer(void);
|
||||
extern unsigned char get_byte(void);
|
||||
extern unsigned short get_word(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 */
|
||||
|
||||
|
|
|
@ -80,9 +80,6 @@ struct res_tree
|
|||
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 */
|
||||
#define RESOURCE_DIR_SIZE (4 * 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 */
|
||||
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 */
|
||||
void output_res_o_file( DLLSPEC *spec )
|
||||
{
|
||||
unsigned int i, total_size;
|
||||
unsigned char *data;
|
||||
unsigned int i;
|
||||
char *res_file = NULL;
|
||||
int fd, err;
|
||||
|
||||
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" );
|
||||
|
||||
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;
|
||||
file_out_pos = data;
|
||||
file_out_end = data + total_size;
|
||||
init_output_buffer();
|
||||
|
||||
put_dword( 0 ); /* ResSize */
|
||||
put_dword( 32 ); /* HeaderSize */
|
||||
|
@ -557,34 +524,30 @@ void output_res_o_file( DLLSPEC *spec )
|
|||
put_dword( (header_size + 3) & ~3 );
|
||||
put_string( &spec->resources[i].type );
|
||||
put_string( &spec->resources[i].name );
|
||||
if ((unsigned long)file_out_pos & 2) put_word( 0 );
|
||||
align_output( 4 );
|
||||
put_dword( 0 );
|
||||
put_word( spec->resources[i].mem_options );
|
||||
put_word( spec->resources[i].lang );
|
||||
put_dword( 0 );
|
||||
put_dword( 0 );
|
||||
memcpy( file_out_pos, spec->resources[i].data, spec->resources[i].data_size );
|
||||
file_out_pos += spec->resources[i].data_size;
|
||||
while ((unsigned long)file_out_pos & 3) *file_out_pos++ = 0;
|
||||
put_data( spec->resources[i].data, spec->resources[i].data_size );
|
||||
align_output( 4 );
|
||||
}
|
||||
assert( file_out_pos == file_out_end );
|
||||
|
||||
/* if the output file name is a .res too, don't run the results through windres */
|
||||
if (strendswith( output_file_name, ".res"))
|
||||
{
|
||||
if ((fd = open( output_file_name, O_WRONLY|O_CREAT|O_TRUNC, 0666 )) == -1)
|
||||
fatal_error( "Cannot create %s\n", output_file_name );
|
||||
flush_output_buffer();
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
res_file = get_temp_file_name( output_file_name, ".res" );
|
||||
if ((fd = open( res_file, O_WRONLY|O_CREAT|O_TRUNC, 0600 )) == -1)
|
||||
fatal_error( "Cannot create %s\n", res_file );
|
||||
}
|
||||
if (write( fd, data, total_size ) != total_size)
|
||||
|
||||
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)
|
||||
fatal_error( "Cannot create %s\n", res_file );
|
||||
if (write( fd, output_buffer, output_buffer_pos ) != output_buffer_pos)
|
||||
fatal_error( "Error writing to %s\n", res_file );
|
||||
close( fd );
|
||||
free( data );
|
||||
free( output_buffer );
|
||||
|
||||
if (res_file)
|
||||
{
|
||||
|
|
|
@ -387,6 +387,18 @@ const char *input_buffer_filename;
|
|||
const unsigned char *input_buffer;
|
||||
size_t input_buffer_pos;
|
||||
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 )
|
||||
{
|
||||
|
@ -411,6 +423,20 @@ void init_input_buffer( const char *file )
|
|||
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)
|
||||
{
|
||||
if (input_buffer_pos >= input_buffer_size)
|
||||
|
@ -443,6 +469,63 @@ unsigned int get_dword(void)
|
|||
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 */
|
||||
void output_standard_file_header(void)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue