//
// hfstools - a Macintosh filesystem access tool
// (C) Copyright 1993 by Equivalence
//
// This file part of hfs.
//
// hfs is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2, or (at your option)
// any later version.
// 
// hfs is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public License
// along with hfs; see the file COPYING.  If not, write to
// the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  
//
//
// $Id: misc.cxx,v 1.7 1994/07/08 12:00:59 craigs Exp $
// $Log: misc.cxx,v $
// Revision 1.7  1994/07/08  12:00:59  craigs
// Fixed problem with displaying misleading error messages
// Changed part command to display drive name rather than partition name
//
// Revision 1.6  1994/07/02  05:04:21  craigs
// Added support for CDROM drives under MSDOS
//
// Revision 1.5  1994/06/30  14:40:54  craigs
// Changed for bigger block sizes and partitions
//
// Revision 1.4  1994/01/06  03:05:08  craigs
// Final checkin to include GNU header
//
// Revision 1.3  1993/12/23  22:44:23  craigs
// Added strprepend function
//
// Revision 1.2  1993/11/23  20:28:49  craigs
// Removed reference to std.h
//
// Revision 1.1  1993/11/22  22:25:55  craigs
// Initial revision
//
//
//

#include "config.h"

#include <stdio.h>
#include <iostream.h>
#include <string.h>

#include "misc.h"
#include "error.h"

static BYTE mac_to_latin1_table [128] = {

#define NA  0xa4    // currency symbol used for undefined characters

  0xc4,  // 0x80  A umlaut
  0xc5,  // 0x81  A ring
  0xc7,  // 0x82  C cedilla
  0xc9,  // 0x83  E acute
  0xd1,  // 0x84  N tilda
  0xd6,  // 0x85  O umlaut
  0xdc,  // 0x86  U umlaut
  0xe1,  // 0x87  a acute
  0xe0,  // 0x88  a grave
  0xe2,  // 0x89  a caret
  0xe4,  // 0x8a  a umlaut
  0xe3,  // 0x8b  a tilda
  0xe5,  // 0x8c  a ring
  0xe7,  // 0x8d  c cedilla
  0xe9,  // 0x8e  e acute
  0xe8,  // 0x8f  e grave

  0xea, // 0x90  e caret
  0xeb, // 0x91  e umlaut
  0xed, // 0x92  i acute
  0xec, // 0x93  i grave
  0xee, // 0x94  i caret
  0xef, // 0x95  i umlaut
  0xf1, // 0x96  n tilda
  0xf3, // 0x97  o acute
  0xf2, // 0x98  o grave
  0xf4, // 0x99  o caret
  0xf6, // 0x9a  o umlaut
  0xf5, // 0x9b  o tilda
  0xfa, // 0x9c  u acute
  0xf9, // 0x9d  u grave
  0xfb, // 0x9e  u caret
  0xfc, // 0x9f  u umlaut

  NA,   // 0xa0  
  0xb0, // 0xa1  degree
  0xa2, // 0xa2  cent
  0xa3, // 0xa3  pound sign
  0xa7, // 0xa4  section sign
  0xb7, // 0xa5  bullet hole
  0xb6, // 0xa6  paragraph sign
  0xdf, // 0xa7  beta
  0xae, // 0xa8  registered symbol
  0xa9, // 0xa9  copyright symbol
  NA,   // 0xaa  trademark symbol
  0xb4, // 0xab  acute accent
  0xa8, // 0xac  umlaut
  NA,   // 0xad  not equals
  0xc6, // 0xae  AE
  0xd8, // 0xaf  O oblique

  NA,   // 0xb0  infinity
  0xb1, // 0xb1  +-
  NA,   // 0xb2  <=
  NA,   // 0xb3  >=
  0xa5, // 0xb4  yen
  0xb5, // 0xb5  micro
  0xf0, // 0xb6  Icelandic eth
  NA,   // 0xb7  sigma
  NA,   // 0xb8  
  NA,   // 0xb9  
  NA,   // 0xba
  0xaa, // 0xbb  feminal ordinal
  0xba, // 0xbc  masculine ordinal
  NA,   // 0xbd  omega
  0xe6, // 0xbe  ae
  0xf8, // 0xbf  o oblique

  0xbf, // 0xc0  inverted ?
  0xa1, // 0xc1  inverted !
  0xac, // 0xc2  not sign
  NA,   // 0xc3  square root
  'f',  // 0xc4  extended f (often used for folders)
  NA,   // 0xc5  double wavy
  NA,   // 0xc6  capital delta
  0xab, // 0xc7  left angle
  0xbb, // 0xc8  right angle
  '.',  // 0xc9  ellipsis
  '_',  // 0xca  sort of underscore
  0xc0, // 0xcb  A grave
  0xc3, // 0xcc  A tilda
  0xd5, // 0xcd  O tilda
  NA,   // 0xce  OE
  NA,   // 0xcf  oe

  0xad, // 0xd0  hyphen
  0xad, // 0xd1  big hyphen
  '"',  // 0xd2  left double quote
  '"',  // 0xd3  right double quote
  '`',  // 0xd4  left single quote
  '\'', // 0xd5  right single quote
  0xf7, // 0xd6  division
  NA,   // 0xd7  diamond
  0xff, // 0xd8  y umlaut
  NA,   // 0xd9
  NA,   // 0xda
  NA,   // 0xdb
  NA,   // 0xdc
  NA,   // 0xdd
  NA,   // 0xde
  NA,   // 0xdf

  NA,   // 0xe0
  NA,   // 0xe1
  NA,   // 0xe2
  NA,   // 0xe3
  NA,   // 0xe4
  NA,   // 0xe5
  NA,   // 0xe6
  NA,   // 0xe7
  NA,   // 0xe8
  NA,   // 0xe9
  NA,   // 0xea
  NA,   // 0xeb
  NA,   // 0xec
  NA,   // 0xed
  NA,   // 0xee
  NA,   // 0xef

  NA,   // 0xf0
  NA,   // 0xf1
  NA,   // 0xf2
  NA,   // 0xf3
  NA,   // 0xf4
  NA,   // 0xf5
  NA,   // 0xf6
  NA,   // 0xf7
  NA,   // 0xf8
  NA,   // 0xf9
  NA,   // 0xfa
  NA,   // 0xfb
  NA,   // 0xfc
  NA,   // 0xfd
  NA,   // 0xfe
  NA,   // 0xff
#undef NA
};


char * mac_to_latin1 (char * str, int len)

{
  BYTE * ptr = (BYTE *)str;
  if (len < 0)
    len = strlen(str);

  for (;len-- > 0;ptr++)
    if (*ptr >= 0x80)
      *ptr = mac_to_latin1_table[(*ptr)-0x80];

  return str;
}

char * ptocstr (BYTE * pstring)

{
  // get size of the string
  int len = pstring[0];

  // allocate storage
  char * cstring = new char[len + 1];

  // copy the name in
  strncpy (cstring, (const char *)pstring+1, len);

  // and terminate it
  cstring [len] = '\0';

  return cstring;
}

void dump (void * vbuffer, int count)

{
  unsigned char * buffer = (unsigned char *)vbuffer;
  int i, b;
  for (b = 0; b < count; b += 16) {
    printf ("%03x   ", b);
    for (i = 0; i < 16; i++) 
      printf ("%02x ", buffer [i+b]);
    printf ("    ");
    for (i = 0; i < 16; i++) 
      printf ("%c", (0x20 <= buffer [i+b]) && (buffer[i+b] < 0x7f) ? buffer[i+b] : '.');
    printf ("\n");
  }
}

void pstring (char * str)

{
  int k;
  cout << "\"";
  for (k = 1; k <= str[0]; k++)
    cout << str[k];
  cout << "\"";
}


char * strprepend (char * s1, char * s2)

{
  char *z;

  if (s2 == NULL) {
    z = new char [strlen(s1) + 1];
    strcpy(z,s1);
  } else {
    z = new char [strlen(s1) + strlen(s2) + 1]; 
    strcpy(z,s1);
    strcat(z,s2);
    delete s2;
  }
  return z;
}

void display_error (char *msg, int code)

{
  cerr << msg << " as ";

  switch (code) {
    case E_OK:
      break;
    case E_FAULTYMDB:
      cerr << "the MDB is corrupted\n";
      break;
    case E_NOTHFS:
      cerr << "the disk is not an HFS disk\n";
      break;
    case E_FAULTYDESCRIPTOR:
      cerr << "the driver descriptor is corrupted\n";
      break;
    case E_FAULTYPARTITION:
      cerr << "the partition table is corrupted\n";
      break;
    case E_NOHFSPARTITIONS:
      cerr << "there are no HFS partitions on the disk\n";
      break;
    case E_READERROR:
      cerr << "a sector read error occured\n";
      break;
    default:
      cerr << "an unknown error occurred\n";
      break;
  }
}
