コード例 #1
0
libspectrum_error
libspectrum_tape_block_read_symbol_table(
  libspectrum_tape_generalised_data_symbol_table *table,
  const libspectrum_byte **ptr, size_t length )
{
  if( table->symbols_in_block ) {
    
    libspectrum_tape_generalised_data_symbol *symbol;
    size_t i, j;

    /* Sanity check */
    if( length < ( 2 * table->max_pulses + 1 ) * table->symbols_in_table ) {
      libspectrum_print_error( LIBSPECTRUM_ERROR_CORRUPT,
			       "%s: not enough data in buffer", __func__ );
      return LIBSPECTRUM_ERROR_CORRUPT;
    }


    table->symbols = libspectrum_malloc( table->symbols_in_table * sizeof( *table->symbols ) );

    for( i = 0, symbol = table->symbols;
	 i < table->symbols_in_table;
	 i++, symbol++ ) {
      symbol->edge_type = **ptr; (*ptr)++;
      symbol->lengths = libspectrum_malloc( table->max_pulses * sizeof( *symbol->lengths ) );
      for( j = 0; j < table->max_pulses; j++ ) {
	symbol->lengths[ j ] = (*ptr)[0] + (*ptr)[1] * 0x100;
	(*ptr) += 2;
      }
    }

  }
  
  return LIBSPECTRUM_ERROR_NONE;
}
コード例 #2
0
ファイル: garray.c プロジェクト: jacadym/fuse-emulator
				   `proper' glib */
#include <string.h>

#include "internals.h"

GArray*
g_array_new( gboolean zero_terminated, gboolean clear, guint element_size )
{
  GArray *array;

  /* Don't support these options */
  if( zero_terminated || clear ) {
    fprintf( stderr, "%s: zero_terminated and clear options not supported\n",
	     __func__ );
    abort();
  }

  array = libspectrum_malloc( sizeof( *array ) );

  array->element_size = element_size;
  array->data = NULL;
  array->len = array->allocated = 0;

  return array;
}
コード例 #3
0
ファイル: memory.c プロジェクト: jacadym/fuse-emulator
void*
libspectrum_malloc_n( size_t nmemb, size_t size )
{
  if( nmemb > SIZE_MAX / size ) abort();

  return libspectrum_malloc( nmemb * size );
}
コード例 #4
0
libspectrum_tape_block*
libspectrum_tape_block_alloc( libspectrum_tape_type type )
{
  libspectrum_tape_block *block = libspectrum_malloc( sizeof( *block ) );
  libspectrum_tape_block_set_type( block, type );
  return block;
}
コード例 #5
0
static GHashNode*
g_hash_node_new (gpointer key,
                 gpointer value)
{
  GHashNode *hash_node;
  guint i;

  if (!node_free_list)
    {
      node_free_list = libspectrum_malloc (1024 * sizeof (GHashNode));
      node_allocated_list = node_free_list;

      for(i = 0; i < 1023; i++ )
	node_free_list[i].next = &node_free_list[i+1];
      node_free_list[1023].next = NULL;
    }

  
  hash_node = node_free_list;
  node_free_list = node_free_list->next;
  
  hash_node->key = key;
  hash_node->value = value;
  hash_node->next = NULL;
  
  return hash_node;
}
コード例 #6
0
ファイル: rzx.c プロジェクト: CiaranG/ZXdroid
libspectrum_rzx*
libspectrum_rzx_alloc( void )
{
  libspectrum_rzx *rzx = libspectrum_malloc( sizeof( *rzx ) );
  rzx->blocks = NULL;
  rzx->current_block = NULL;
  rzx->current_input = NULL;
  rzx->signed_start = NULL;
  return rzx;
}
コード例 #7
0
ファイル: rzx.c プロジェクト: CiaranG/ZXdroid
static libspectrum_error
rzx_read_frames( input_block_t *block, const libspectrum_byte **ptr,
		 const libspectrum_byte *end )
{
  size_t i, j;

  /* And read in the frames */
  for( i=0; i < block->count; i++ ) {

    /* Check the two length bytes exist */
    if( end - (*ptr) < 4 ) {
      libspectrum_print_error( LIBSPECTRUM_ERROR_CORRUPT,
			       "rzx_read_frames: not enough data in buffer" );
      for( j=0; j<i; j++ ) {
	if( !block->frames[i].repeat_last ) libspectrum_free( block->frames[j].in_bytes );
      }
      return LIBSPECTRUM_ERROR_CORRUPT;
    }

    block->frames[i].instructions = libspectrum_read_word( ptr );
    block->frames[i].count        = libspectrum_read_word( ptr );

    if( block->frames[i].count == libspectrum_rzx_repeat_frame ) {
      block->frames[i].repeat_last = 1;
      continue;
    }

    block->frames[i].repeat_last = 0;

    if( end - (*ptr) < (ptrdiff_t)block->frames[i].count ) {
      libspectrum_print_error( LIBSPECTRUM_ERROR_CORRUPT,
			       "rzx_read_frames: not enough data in buffer" );
      for( j=0; j<i; j++ ) {
	if( !block->frames[i].repeat_last ) libspectrum_free( block->frames[j].in_bytes );
      }
      return LIBSPECTRUM_ERROR_CORRUPT;
    }

    if( block->frames[i].count ) {

      block->frames[i].in_bytes =
	libspectrum_malloc( block->frames[i].count * sizeof( libspectrum_byte ) );
      memcpy( block->frames[i].in_bytes, *ptr, block->frames[i].count );

    } else {
      block->frames[i].in_bytes = NULL;
    }

    (*ptr) += block->frames[i].count;
  }

  return LIBSPECTRUM_ERROR_NONE;
}
コード例 #8
0
GHashTable*
g_hash_table_new_full (GHashFunc       hash_func,
		       GCompareFunc    key_equal_func,
		       GDestroyNotify  key_destroy_func,
		       GDestroyNotify  value_destroy_func)
{
  GHashTable *hash_table;
  guint i;

  hash_table = libspectrum_malloc (sizeof (GHashTable));

  hash_table->nnodes = 0;
  hash_table->hash_func = hash_func? hash_func : g_direct_hash;
  hash_table->key_equal_func = key_equal_func;
  hash_table->key_destroy_func   = key_destroy_func;
  hash_table->value_destroy_func = value_destroy_func;
  hash_table->nodes = libspectrum_malloc (HASH_TABLE_SIZE * sizeof (GHashNode*));

  for (i = 0; i < HASH_TABLE_SIZE; i++)
    hash_table->nodes[i] = NULL;

  return hash_table;
}
コード例 #9
0
ファイル: crypto.c プロジェクト: CiaranG/ZXdroid
static libspectrum_error
serialise_mpis( libspectrum_byte **signature, size_t *signature_length,
		gcry_mpi_t r, gcry_mpi_t s )
{
  gcry_error_t error;
  size_t length, length_s;
  unsigned char *ptr;

  error = gcry_mpi_print( GCRYMPI_FMT_PGP, NULL, 0, &length, r );
  if( error ) {
    libspectrum_print_error( LIBSPECTRUM_ERROR_LOGIC,
			     "serialise_mpis: length of r: %s",
			     gcry_strerror( error ) );
    return LIBSPECTRUM_ERROR_LOGIC;
  }

  error = gcry_mpi_print( GCRYMPI_FMT_PGP, NULL, 0, &length_s, s );
  if( error ) {
    libspectrum_print_error( LIBSPECTRUM_ERROR_LOGIC,
			     "serialise_mpis: length of s: %s",
			     gcry_strerror( error ) );
    return LIBSPECTRUM_ERROR_LOGIC;
  }

  length += length_s; *signature_length = length;

  *signature = libspectrum_malloc( length );

  error = gcry_mpi_print( GCRYMPI_FMT_PGP, *signature, length, &length, r );
  if( error ) {
    libspectrum_print_error( LIBSPECTRUM_ERROR_LOGIC,
			     "serialise_mpis: printing r: %s",
			     gcry_strerror( error ) );
    libspectrum_free( *signature );
    return LIBSPECTRUM_ERROR_LOGIC;
  }

  ptr = *signature + length; length = *signature_length - length;
  error = gcry_mpi_print( GCRYMPI_FMT_PGP, ptr, length, NULL, s );
  if( error ) {
    libspectrum_print_error( LIBSPECTRUM_ERROR_LOGIC,
			     "serialise_mpis: printing s: %s",
			     gcry_strerror( error ) );
    libspectrum_free( *signature );
    return LIBSPECTRUM_ERROR_LOGIC;
  }

  return LIBSPECTRUM_ERROR_NONE;
}
コード例 #10
0
ファイル: crypto.c プロジェクト: CiaranG/ZXdroid
static libspectrum_error
get_hash( gcry_sexp_t *hash, const libspectrum_byte *data, size_t data_length )
{
  gcry_error_t error;
  unsigned char *digest; size_t digest_length;
  gcry_mpi_t hash_mpi;
  
  digest_length = gcry_md_get_algo_dlen( HASH_ALGORITHM );
  digest = libspectrum_malloc( digest_length );

  gcry_md_hash_buffer( HASH_ALGORITHM, digest, data, data_length );

  error = gcry_mpi_scan( &hash_mpi, GCRYMPI_FMT_USG, digest, digest_length,
			 NULL );
  if( error ) {
    libspectrum_print_error( LIBSPECTRUM_ERROR_LOGIC,
			     "get_hash: error creating hash MPI: %s",
			     gcry_strerror( error )
    );
    libspectrum_free( digest );
    return LIBSPECTRUM_ERROR_LOGIC;
  }

  libspectrum_free( digest );

  error = gcry_sexp_build( hash, NULL, hash_format, hash_mpi );
  if( error ) {
    libspectrum_print_error( LIBSPECTRUM_ERROR_LOGIC,
			     "get_hash: error creating hash sexp: %s",
			     gcry_strerror( error )
    );
    gcry_mpi_release( hash_mpi );
    return LIBSPECTRUM_ERROR_LOGIC;
  }

  gcry_mpi_release( hash_mpi );

  return LIBSPECTRUM_ERROR_NONE;
}
コード例 #11
0
ファイル: utils.c プロジェクト: matthewbauer/fuse-libretro
int
utils_read_fd( compat_fd fd, const char *filename, utils_file *file )
{
  file->length = compat_file_get_length( fd );
  if( file->length == -1 ) return 1;

  file->buffer = libspectrum_malloc( file->length );

  if( compat_file_read( fd, file ) ) {
    libspectrum_free( file->buffer );
    compat_file_close( fd );
    return 1;
  }

  if( compat_file_close( fd ) ) {
    ui_error( UI_ERROR_ERROR, "Couldn't close '%s': %s", filename,
	      strerror( errno ) );
    libspectrum_free( file->buffer );
    return 1;
  }

  return 0;
}
コード例 #12
0
ファイル: rzx.c プロジェクト: CiaranG/ZXdroid
libspectrum_error
libspectrum_rzx_store_frame( libspectrum_rzx *rzx, size_t instructions,
			     size_t count, libspectrum_byte *in_bytes )
{
  input_block_t *input;
  libspectrum_rzx_frame_t *frame;

  input = rzx->current_input;

  /* Check we've got an IRB to record to */
  if( !input ) {
    libspectrum_print_error(
      LIBSPECTRUM_ERROR_INVALID,
      "libspectrum_rzx_store_frame called with no active input block"
    );
    return LIBSPECTRUM_ERROR_INVALID;
  }

  /* Get more space if we need it; allocate twice as much as we currently
     have, with a minimum of 50 */
  if( input->count == input->allocated ) {

    libspectrum_rzx_frame_t *ptr; size_t new_allocated;

    new_allocated = input->allocated >= 25 ? 2 * input->allocated : 50;

    ptr = realloc( input->frames, new_allocated * sizeof( *ptr ) );
    if( !ptr ) return LIBSPECTRUM_ERROR_MEMORY;

    input->frames = ptr;
    input->allocated = new_allocated;
  }

  frame = &input->frames[ input->count ];

  frame->instructions = instructions;

  /* Check for repeated frames */
  if( input->count != 0 && count != 0 &&
      count == input->frames[ input->non_repeat ].count &&
      !memcmp( in_bytes, input->frames[ input->non_repeat ].in_bytes,
	       count )
    ) {
	
    frame->repeat_last = 1;

  } else {

    frame->repeat_last = 0;
    frame->count = count;

    /* Note this as the last non-repeated frame */
    input->non_repeat = input->count;

    if( count ) {

      frame->in_bytes = libspectrum_malloc( count * sizeof( *( frame->in_bytes ) ) );

      memcpy( frame->in_bytes, in_bytes,
	      count * sizeof( *( frame->in_bytes ) ) );

    } else {

      frame->in_bytes = NULL;

    }
  }

  /* Move along to the next frame */
  input->count++;

  return 0;
}
コード例 #13
0
ファイル: rzx.c プロジェクト: CiaranG/ZXdroid
static void
block_alloc( rzx_block_t **block, libspectrum_rzx_block_id type )
{
  *block = libspectrum_malloc( sizeof( **block ) );
  (*block)->type = type;
}
コード例 #14
0
ファイル: snap_accessors.c プロジェクト: leiradel/tape2wav
/* Initialise a libspectrum_snap structure */
libspectrum_snap*
libspectrum_snap_alloc_internal( void )
{
  return libspectrum_malloc( sizeof( libspectrum_snap ) );
}
コード例 #15
0
ファイル: rzx.c プロジェクト: CiaranG/ZXdroid
static libspectrum_error
rzx_read_input( libspectrum_rzx *rzx,
		const libspectrum_byte **ptr, const libspectrum_byte *end )
{
  size_t blocklength;
  libspectrum_dword flags; int compressed;
  libspectrum_error error;
  rzx_block_t *rzx_block;
  input_block_t *block;

  /* Check we've got enough data for the block */
  if( end - (*ptr) < 18 ) {
    libspectrum_print_error( LIBSPECTRUM_ERROR_CORRUPT,
			     "rzx_read_input: not enough data in buffer" );
    return LIBSPECTRUM_ERROR_CORRUPT;
  }

  block_alloc( &rzx_block, LIBSPECTRUM_RZX_INPUT_BLOCK );

  block = &( rzx_block->types.input );

  /* Get the length and number of frames */
  blocklength = libspectrum_read_dword( ptr );
  block->count = libspectrum_read_dword( ptr );

  /* Frame size is undefined, so just skip it */
  (*ptr)++;

  /* Allocate memory for the frames */
  block->frames = libspectrum_malloc( block->count * sizeof( *block->frames ) );
  block->allocated = block->count;

  /* Fetch the T-state counter and the flags */
  block->tstates = libspectrum_read_dword( ptr );

  flags = libspectrum_read_dword( ptr );
  compressed = flags & 0x02;

  if( compressed ) {

#ifdef HAVE_ZLIB_H

    libspectrum_byte *data; const libspectrum_byte *data_ptr;
    size_t data_length = 0;

    /* Discount the block intro */
    blocklength -= 18;

    /* Check that we've got enough compressed data */
    if( end - (*ptr) < (ptrdiff_t)blocklength ) {
      libspectrum_print_error( LIBSPECTRUM_ERROR_CORRUPT,
			       "rzx_read_input: not enough data in buffer" );
      libspectrum_free( rzx_block );
      return LIBSPECTRUM_ERROR_CORRUPT;
    }

    error = libspectrum_zlib_inflate( *ptr, blocklength, &data, &data_length );
    if( error != LIBSPECTRUM_ERROR_NONE ) {
      block_free( rzx_block );
      return error;
    }

    *ptr += blocklength;

    data_ptr = data;

    error = rzx_read_frames( block, &data_ptr, data + data_length );
    if( error ) { libspectrum_free( rzx_block ); libspectrum_free( data ); return error; }

    libspectrum_free( data );

#else				/* #ifdef HAVE_ZLIB_H */

    libspectrum_print_error( LIBSPECTRUM_ERROR_UNKNOWN,
			     "rzx_read_input: zlib needed for decompression" );
    libspectrum_free( rzx_block );
    return LIBSPECTRUM_ERROR_UNKNOWN;

#endif				/* #ifdef HAVE_ZLIB_H */

  } else {			/* Data not compressed */

    error = rzx_read_frames( block, ptr, end );
    if( error ) { libspectrum_free( rzx_block ); return error; }
  }

  rzx->blocks = g_slist_append( rzx->blocks, rzx_block );

  return LIBSPECTRUM_ERROR_NONE;
}
コード例 #16
0
ファイル: zxs.c プロジェクト: CiaranG/ZXdroid
static libspectrum_error
inflate_block( libspectrum_byte **uncompressed, size_t *uncompressed_length,
	       const libspectrum_byte **compressed, size_t compressed_length )
{

#ifdef HAVE_ZLIB_H

  libspectrum_dword header_length, expected_crc32, actual_crc32;
  libspectrum_byte *zlib_buffer;
  unsigned long actual_length;
  int error;

  /* First, look at the compression header */
  header_length = libspectrum_read_dword( compressed );
  if( header_length != 12 ) {
    libspectrum_print_error( LIBSPECTRUM_ERROR_UNKNOWN,
			     "zxs_inflate_block: unknown header length %lu",
			     (unsigned long)header_length );
    return LIBSPECTRUM_ERROR_UNKNOWN;
  }
  compressed_length -= 12;

  expected_crc32 = libspectrum_read_dword( compressed );
  *uncompressed_length = libspectrum_read_dword( compressed );

  /* Some space to put the zlib header for decompression */
  zlib_buffer =
    libspectrum_malloc( ( compressed_length + 6 ) * sizeof( *zlib_buffer ) );

  /* zlib's header */
  zlib_buffer[0] = 0x78; zlib_buffer[1] = 0xda;

  memcpy( &zlib_buffer[2], *compressed, compressed_length );
  *compressed += compressed_length;

  *uncompressed = libspectrum_malloc( *uncompressed_length * sizeof( **uncompressed ) );

  actual_length = *uncompressed_length;
  error = uncompress( *uncompressed, &actual_length, zlib_buffer,
		      compressed_length + 6 );

  /* At this point, we expect to get a Z_DATA_ERROR, as we don't have
     the Adler-32 checksum of the data. There is a 1 in 65521 chance
     that the random bytes will match, so we might (very rarely) get
     Z_OK */
  if( error != Z_DATA_ERROR && error != Z_OK ) {
    libspectrum_free( *uncompressed ); libspectrum_free( zlib_buffer );
    libspectrum_print_error( LIBSPECTRUM_ERROR_CORRUPT,
			     "zxs_inflate_block: unexpected zlib error" );
    return LIBSPECTRUM_ERROR_CORRUPT;
  }

  if( *uncompressed_length != actual_length ) {
    libspectrum_free( *uncompressed ); libspectrum_free( zlib_buffer );
    libspectrum_print_error(
      LIBSPECTRUM_ERROR_CORRUPT,
      "zxs_inflate_block: block expanded to 0x%04lx, not the expected 0x%04lx bytes",
      actual_length, (unsigned long)*uncompressed_length
    );
    return LIBSPECTRUM_ERROR_CORRUPT;
  }

  libspectrum_free( zlib_buffer );

  actual_crc32 = crc32( 0, Z_NULL, 0 );
  actual_crc32 = crc32( actual_crc32, *uncompressed, *uncompressed_length );

  if( actual_crc32 != expected_crc32 ) {
    libspectrum_free( *uncompressed );
    libspectrum_print_error(
      LIBSPECTRUM_ERROR_CORRUPT,
      "zxs_inflate_block: crc 0x%08x does not match expected 0x%08x",
      actual_crc32, expected_crc32
    );
    return LIBSPECTRUM_ERROR_CORRUPT;
  }

  return LIBSPECTRUM_ERROR_NONE;

#else				/* #ifdef HAVE_ZLIB_H */

  /* No zlib, so can't inflate the block */
  return LIBSPECTRUM_ERROR_UNKNOWN;

#endif				/* #ifdef HAVE_ZLIB_H */

}
コード例 #17
0
ファイル: tzx_write.c プロジェクト: CiaranG/ZXdroid
/* Convert RLE block to a TZX DRB as TZX CSW block support is limited :/ */
static libspectrum_error
tzx_write_rle( libspectrum_tape_block *block, libspectrum_byte **buffer,
               libspectrum_byte **ptr, size_t *length,
               libspectrum_tape *tape,
               libspectrum_tape_iterator iterator )
{
  libspectrum_error error;
  libspectrum_tape_block_state it;
  libspectrum_dword scale = libspectrum_tape_block_scale( block );
  libspectrum_dword pulse_tstates = 0;
  libspectrum_dword balance_tstates = 0;
  int flags = 0;

  libspectrum_tape_block *raw_block = 
    libspectrum_tape_block_alloc( LIBSPECTRUM_TAPE_BLOCK_RAW_DATA );

  libspectrum_tape_block_set_bit_length( raw_block, scale );
  libspectrum_tape_block_set_pause     ( raw_block, 0 );

  rle_state.bits_used = 0;
  rle_state.level = 0;
  rle_state.length = 0;
  rle_state.tape_length = 8192;
  rle_state.tape_buffer = libspectrum_malloc( rle_state.tape_length );

  *rle_state.tape_buffer = 0;

  it.current_block = iterator;
  error = libspectrum_tape_block_init( block, &it );
  if( error != LIBSPECTRUM_ERROR_NONE ) {
    libspectrum_free( rle_state.tape_buffer );
    libspectrum_tape_block_free( raw_block );
    return error;
  }

  while( !(flags & LIBSPECTRUM_TAPE_FLAGS_BLOCK) ) {
    libspectrum_dword pulse_length = 0;

    /* Use internal version of this that doesn't bugger up the
       external tape status */
    error = libspectrum_tape_get_next_edge_internal( &pulse_tstates, &flags,
                                                     tape, &it );
    if( error != LIBSPECTRUM_ERROR_NONE ) {
      libspectrum_free( rle_state.tape_buffer );
      libspectrum_tape_block_free( raw_block );
      return error;
    }

    balance_tstates += pulse_tstates;

    /* next set of pulses is: balance_tstates / scale; */
    pulse_length = balance_tstates / scale;
    balance_tstates = balance_tstates % scale;

    /* write pulse_length bits of the current level into the buffer */
    write_pulse( pulse_length );
  }

  if( rle_state.length || rle_state.bits_used ) {
    if( rle_state.bits_used ) {
      rle_state.length++;
    } else {
      rle_state.bits_used = 8;
    }

    error = libspectrum_tape_block_set_bits_in_last_byte( raw_block,
                                                          rle_state.bits_used );
    if( error != LIBSPECTRUM_ERROR_NONE ) {
      libspectrum_free( rle_state.tape_buffer );
      libspectrum_tape_block_free( raw_block );
      return error;
    }

    error = libspectrum_tape_block_set_data_length( raw_block,
                                                    rle_state.length );
    if( error != LIBSPECTRUM_ERROR_NONE ) {
      libspectrum_free( rle_state.tape_buffer );
      libspectrum_tape_block_free( raw_block );
      return error;
    }

    error = libspectrum_tape_block_set_data( raw_block, rle_state.tape_buffer );
    if( error != LIBSPECTRUM_ERROR_NONE ) {
      libspectrum_free( rle_state.tape_buffer );
      libspectrum_tape_block_free( raw_block );
      return error;
    }

    /* now have tzx_write_raw_data finish the job */
    tzx_write_raw_data( raw_block, buffer, ptr, length );
  } else {
    libspectrum_free( rle_state.tape_buffer );
  }

  return libspectrum_tape_block_free( raw_block );
}