#! /usr/bin/env perl
#
# Used to join a directory of dctc created parts of one file
# Copyright Tobias Olsson 2002
# Licensed under GPL version 2
#
# $Id: GDLjoiner,v 1.2 2003/05/17 07:03:32 ericprev Exp $

# usage: GDLjoiner [outputfile] [directory]
#
# simple usage with defaults: "GDLjoiner >joined_file"
# or "GDLjoiner | mplayer -"

use Fcntl;
use strict;

# Name of the directory that should be joined
my $GDLdir = "./";
# name of the file that will be the result ("-" is standard output)
my $outputfilename = "-";
# verbose output enabled (recommended)
my $verbose = 1;


# simplistic command line parser
if ($#ARGV >= 0) {
  $outputfilename = $ARGV[0];
  if ($#ARGV >= 1) {
    $GDLdir = $ARGV[1]."/";
  }
}

opendir(DIR, $GDLdir) || die "can't opendir $GDLdir $!, stopped";
my @files = grep { /^[0-9A-F]+-[0-9A-F]+$/ } readdir(DIR); # stuff all files matching in the array voodoo
closedir(DIR);

my ($realPos, $startingPos, $buffer, $bytesRead, $offset, $file) = 0;
if ($outputfilename ne "-") {
  open(OUTPUT, ">".$outputfilename) or
    die ("can't open file $outputfilename: $!, stopped");
} else {
  open(OUTPUT, ">-") or
    die ("can't open stdout $!, stopped");
}

foreach (sort(@files)) {
  $file = $_; # set $file
  /^([0-9A-F]+)/; $startingPos = hex($1); # convert the file's starting position from hex string to int
  $verbose and print STDERR "filename: $file, starting position of file: $startingPos, next byte to write: $realPos \n";

  if ($startingPos > $realPos) {
    die ("parts missing: $file begins at $startingPos, which is after $realPos, stopped");
  } elsif ($startingPos < $realPos) {
    print STDERR "anomaly detected and dealt with, size: ".($realPos - $startingPos).", file where data is skipped: $file\n";
  }

  open(INPUT, $GDLdir.$file) or die ("can't open input $GDLdir$file : $!, stopped");
  $bytesRead = read(INPUT, $buffer, 8192, $realPos - $startingPos);
  while ($bytesRead) {
    if (syswrite(OUTPUT, $buffer, $bytesRead) != $bytesRead) {
      die ("error writing to disk. disk full?: $!, stopped");
    }
    $realPos += $bytesRead;
    $bytesRead = read(INPUT, $buffer, 8192);
  }
  close INPUT;
}
close OUTPUT;
