示例#1
0
int snapshot_read( const char *filename )
{
  utils_file file;
  libspectrum_snap *snap = libspectrum_snap_alloc();
  int error;

  error = utils_read_file( filename, &file );
  if( error ) { libspectrum_snap_free( snap ); return error; }

  error = libspectrum_snap_read( snap, file.buffer, file.length,
				 LIBSPECTRUM_ID_UNKNOWN, filename );
  if( error ) {
    utils_close_file( &file ); libspectrum_snap_free( snap );
    return error;
  }

  utils_close_file( &file );

  error = snapshot_copy_from( snap );
  if( error ) { libspectrum_snap_free( snap ); return error; }

  error = libspectrum_snap_free( snap ); if( error ) return error;

  return 0;
}
示例#2
0
static libspectrum_snap*
read_snap( const char *filename )
{
  unsigned char *buffer = NULL;
  size_t length = 0;
  int error;
  libspectrum_snap *snap;

  if( read_file( filename, &buffer, &length ) ) {
    return NULL;
  }

  snap = libspectrum_snap_alloc();

  error = libspectrum_snap_read( snap, buffer, length, LIBSPECTRUM_ID_UNKNOWN,
                                 filename );

  if( error ) {
    libspectrum_snap_free( snap );
    snap = NULL;
  }

  free( buffer );

  return snap;
}
示例#3
0
int snapshot_write( const char *filename )
{
  libspectrum_id_t type;
  libspectrum_class_t class;
  libspectrum_snap *snap;
  unsigned char *buffer; size_t length;
  int flags;

  int error;

  /* Work out what sort of file we want from the filename; default to
     .szx if we couldn't guess */
  error = libspectrum_identify_file_with_class( &type, &class, filename, NULL,
						0 );
  if( error ) return error;

  if( class != LIBSPECTRUM_CLASS_SNAPSHOT || type == LIBSPECTRUM_ID_UNKNOWN )
    type = LIBSPECTRUM_ID_SNAPSHOT_SZX;

  snap = libspectrum_snap_alloc();

  error = snapshot_copy_to( snap );
  if( error ) { libspectrum_snap_free( snap ); return error; }

  flags = 0;
  length = 0;
  buffer = NULL;
  error = libspectrum_snap_write( &buffer, &length, &flags, snap, type,
				  fuse_creator, 0 );
  if( error ) { libspectrum_snap_free( snap ); return error; }

  if( flags & LIBSPECTRUM_FLAG_SNAPSHOT_MAJOR_INFO_LOSS ) {
    ui_error(
      UI_ERROR_WARNING,
      "A large amount of information has been lost in conversion; the snapshot probably won't work"
    );
  } else if( flags & LIBSPECTRUM_FLAG_SNAPSHOT_MINOR_INFO_LOSS ) {
    ui_error(
      UI_ERROR_WARNING,
      "Some information has been lost in conversion; the snapshot may not work"
    );
  }

  error = libspectrum_snap_free( snap );
  if( error ) { libspectrum_free( buffer ); return 1; }

  error = utils_write_file( filename, buffer, length );
  if( error ) { libspectrum_free( buffer ); return error; }

  libspectrum_free( buffer );

  return 0;

}
示例#4
0
int
snapshot_read_buffer( const unsigned char *buffer, size_t length,
		      libspectrum_id_t type )
{
  libspectrum_snap *snap = libspectrum_snap_alloc();
  int error;

  error = libspectrum_snap_read( snap, buffer, length, type, NULL );
  if( error ) { libspectrum_snap_free( snap ); return error; }
    
  error = snapshot_copy_from( snap );
  if( error ) { libspectrum_snap_free( snap ); return error; }

  error = libspectrum_snap_free( snap ); if( error ) return error;

  return 0;
}
示例#5
0
static int
rzx_add_snap( libspectrum_rzx *rzx, int automatic )
{
  int error;
  libspectrum_snap *snap = libspectrum_snap_alloc();

  error = snapshot_copy_to( snap );
  if( error ) {
    libspectrum_snap_free( snap );
    return error;
  }

  error = libspectrum_rzx_add_snap( rzx, snap, automatic );
  if( error ) {
    libspectrum_snap_free( snap );
    return error;
  }

  return 0;
}
示例#6
0
文件: rzx.c 项目: CiaranG/ZXdroid
static libspectrum_error
rzx_read_snapshot( libspectrum_rzx *rzx, const libspectrum_byte **ptr,
		   const libspectrum_byte *end )
{
  rzx_block_t *block;
  libspectrum_snap *snap;
  size_t blocklength, snaplength;
  libspectrum_error error = LIBSPECTRUM_ERROR_NONE;
  libspectrum_dword flags;
  const libspectrum_byte *snap_ptr;
  int done;
  snapshot_string_t *type;

  /* For deflated snapshot data: */
  int compressed;
  libspectrum_byte *gzsnap = NULL; size_t uncompressed_length = 0;

  if( end - (*ptr) < 16 ) {
    libspectrum_print_error( LIBSPECTRUM_ERROR_CORRUPT,
			     "rzx_read_snapshot: not enough data in buffer" );
    return LIBSPECTRUM_ERROR_CORRUPT;
  }

  blocklength = libspectrum_read_dword( ptr );

  if( end - (*ptr) < (ptrdiff_t)blocklength - 5 ) {
    libspectrum_print_error( LIBSPECTRUM_ERROR_CORRUPT,
			     "rzx_read_snapshot: not enough data in buffer" );
    return LIBSPECTRUM_ERROR_CORRUPT;
  }

  /* See if we want a compressed snap */
  flags = libspectrum_read_dword( ptr );

  /* We don't handle 'links' to external snapshots. I really think these
     are just more trouble than they're worth */
  if( flags & 0x01 ) {
    libspectrum_print_error( LIBSPECTRUM_ERROR_UNKNOWN,
			     "rzx_read_snapshot: skipping external snapshot" );
    (*ptr) += blocklength - 9;
    return LIBSPECTRUM_ERROR_NONE;
  }

  /* Do we have a compressed snapshot? */
  compressed = flags & 0x02;

  /* How long is the (uncompressed) snap? */
  (*ptr) += 4;
  snaplength = libspectrum_read_dword( ptr );
  (*ptr) -= 8;

  /* If compressed, uncompress the data */
  if( compressed ) {

#ifdef HAVE_ZLIB_H

    error = libspectrum_zlib_inflate( (*ptr) + 8, blocklength - 17,
				      &gzsnap, &uncompressed_length );
    if( error != LIBSPECTRUM_ERROR_NONE ) return error;

    if( uncompressed_length != snaplength ) {
      libspectrum_print_error(
        LIBSPECTRUM_ERROR_CORRUPT,
        "rzx_read_snapshot: compressed snapshot has wrong length"
      );
      libspectrum_free( gzsnap );
      return LIBSPECTRUM_ERROR_CORRUPT;
    }   
    snap_ptr = gzsnap;

#else			/* #ifdef HAVE_ZLIB_H */

    libspectrum_print_error(
      LIBSPECTRUM_ERROR_UNKNOWN,
      "rzx_read_snapshot: zlib needed for decompression\n"
    );
    return LIBSPECTRUM_ERROR_UNKNOWN;

#endif			/* #ifdef HAVE_ZLIB_H */

  } else {

    /* If not compressed, check things are consistent */
    if( blocklength != snaplength + 17 ) {
      libspectrum_print_error(
        LIBSPECTRUM_ERROR_CORRUPT,
        "rzx_read_snapshot: inconsistent snapshot lengths"
      );
      return LIBSPECTRUM_ERROR_CORRUPT;
    }
    snap_ptr = (*ptr) + 8;
    uncompressed_length = snaplength;

  }

  block_alloc( &block, LIBSPECTRUM_RZX_SNAPSHOT_BLOCK );
  block->types.snap.snap = libspectrum_snap_alloc();
  block->types.snap.automatic = 0;

  snap = block->types.snap.snap;

  for( done = 0, type = snapshot_strings; type->format; type++ ) {
    if( !strncasecmp( (char*)*ptr, type->string, 4 ) ) {
      error = libspectrum_snap_read( snap, snap_ptr, uncompressed_length,
				     type->format, NULL );
      done = 1;
    }
  }

  if( !done ) {
    libspectrum_print_error(
      LIBSPECTRUM_ERROR_UNKNOWN,
      "%s:rzx_read_snapshot: unrecognised snapshot format", __FILE__
    );
    if( compressed ) libspectrum_free( gzsnap );
    block_free( block );
    return LIBSPECTRUM_ERROR_UNKNOWN;
  }

  if( error != LIBSPECTRUM_ERROR_NONE ) {
    if( compressed ) libspectrum_free( gzsnap );
    block_free( block );
    return error;
  }

  /* Free the decompressed data (if we created it) */
  if( compressed ) libspectrum_free( gzsnap );

  /* Skip over the data */
  (*ptr) += blocklength - 9;

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

  return LIBSPECTRUM_ERROR_NONE;
}
int
main( int argc, char **argv )
{
  libspectrum_snap *snap;
  libspectrum_id_t type; libspectrum_class_t class;
  unsigned char *buffer; size_t length;
  libspectrum_creator *creator;
  int flags;
  int compress = 0;
  int fix = 0;
  FILE *f;

  int error = 0;
  int c;

  struct option long_options[] = {
    { "help", 0, NULL, 'h' },
    { "version", 0, NULL, 'V' },
    { 0, 0, 0, 0 }
  };

  progname = argv[0];

  while( ( c = getopt_long( argc, argv, "cnfhV", long_options, NULL ) ) != -1 ) {

    switch( c ) {

    case 'c': compress = LIBSPECTRUM_FLAG_SNAPSHOT_ALWAYS_COMPRESS;
      break;

    case 'n': compress = LIBSPECTRUM_FLAG_SNAPSHOT_NO_COMPRESSION;
      break;

    case 'f': fix = 1;
      break;

    case 'h': show_help(); return 0;

    case 'V': show_version(); return 0;

    case '?':
      /* getopt prints an error message to stderr */
      error = 1;
      break;

    default:
      error = 1;
      fprintf( stderr, "%s: unknown option `%c'\n", progname, (char) c );
      break;

    }
  }
  argc -= optind;
  argv += optind;

  if( error ) {
    fprintf( stderr, "Try `%s --help' for more information.\n", progname );
    return error;
  }

  if( argc < 2 ) {
    fprintf( stderr, "%s: usage: %s [-c] [-n] [-f] <infile> <outfile>\n", progname,
	     progname );
    fprintf( stderr, "Try `%s --help' for more information.\n", progname );
    return 1;
  }

  error = init_libspectrum(); if( error ) return error;

  snap = libspectrum_snap_alloc();

  if( read_file( argv[0], &buffer, &length ) ) {
    libspectrum_snap_free( snap );
    return 1;
  }

  error = libspectrum_snap_read( snap, buffer, length, LIBSPECTRUM_ID_UNKNOWN,
				 argv[0] );
  if( error ) {
    libspectrum_snap_free( snap ); free( buffer );
    return error;
  }

  free( buffer );

  if( fix ) fix_snapshot( snap );

  error = libspectrum_identify_file_with_class( &type, &class, argv[1], NULL,
                                                0 );
  if( error ) { libspectrum_snap_free( snap ); return error; }

  if( class != LIBSPECTRUM_CLASS_SNAPSHOT ) {
    fprintf( stderr, "%s: '%s' is not a snapshot file\n", progname, argv[1] );
    libspectrum_snap_free( snap );
    return 1;
  }

  error = get_creator( &creator, "snapconv" );
  if( error ) { libspectrum_snap_free( snap ); return error; }

  length = 0;
  error = libspectrum_snap_write( &buffer, &length, &flags, snap, type,
                                  creator, compress );
  if( error ) {
    libspectrum_creator_free( creator ); libspectrum_snap_free( snap );
    return error;
  }

  if( flags & LIBSPECTRUM_FLAG_SNAPSHOT_MAJOR_INFO_LOSS ) {
    fprintf( stderr,
	     "%s: warning: major information loss during conversion\n",
	     progname );
  } else if( flags & LIBSPECTRUM_FLAG_SNAPSHOT_MINOR_INFO_LOSS ) {
    fprintf( stderr,
	     "%s: warning: minor information loss during conversion\n",
	     progname );
  }
  error = libspectrum_creator_free( creator );
  if( error ) { free( buffer ); libspectrum_snap_free( snap ); return error; }

  error = libspectrum_snap_free( snap );
  if( error ) { free( buffer ); return error; }

  f = fopen( argv[1], "wb" );
  if( !f ) {
    fprintf( stderr, "%s: couldn't open '%s': %s\n", progname, argv[1],
	     strerror( errno ) );
    free( buffer );
    return 1;
  }
    
  if( fwrite( buffer, 1, length, f ) != length ) {
    fprintf( stderr, "%s: error writing to '%s'\n", progname, argv[1] );
    free( buffer );
    fclose( f );
    return 1;
  }

  free( buffer );
  fclose( f );

  return 0;
}