/*

  Author: Timo J. Rinne

  Copyright (C) 1998 SSH Communications Security Oy, Espoo, Finland
  All rights reserved.

  Created:  Mon Oct 26 18:04:49 1998 tri

  Misc string functions.

*/

/*
 * $Id: sshmiscstring.c,v 1.1.4.2 2000/02/18 15:06:34 sjl Exp $
 * $Log: sshmiscstring.c,v $
 * $EndLog$
 */

#include "sshincludes.h"
#include "sshmiscstring.h"

char *ssh_string_concat_2(const char *s1, const char *s2)
{
  int l1, l2;
  char *r;

  l1 = s1 ? strlen(s1) : 0;
  l2 = s2 ? strlen(s2) : 0;

  r = ssh_xmalloc(l1 + l2 + 1);

  if (l1 > 0)
    strcpy(r, s1);
  else
    *r = '\000';
  if (l2 > 0)
    strcpy(&(r[l1]), s2);

  return r;
}

char *ssh_string_concat_3(const char *s1, const char *s2, const char *s3)
{
  int l1, l2, l3;
  char *r;

  l1 = s1 ? strlen(s1) : 0;
  l2 = s2 ? strlen(s2) : 0;
  l3 = s3 ? strlen(s3) : 0;
  r = ssh_xmalloc(l1 + l2 + l3 + 1);

  if (l1 > 0)
    strcpy(r, s1);
  else
    *r = '\000';
  if (l2 > 0)
    strcpy(&(r[l1]), s2);
  if (l3 > 0)
    strcpy(&(r[l1 + l2]), s3);

  return r;
}

char *ssh_replace_in_string(const char *str, const char *src, const char *dst)
{
  char *hlp1, *hlp2, *hlp3, *strx;

  if (src == NULL)
    src = "";
  if (dst == NULL)
    dst = "";
  strx = ssh_xstrdup(str ? str : "");

  if ((*src == '\000') || ((hlp1 = strstr(strx, src)) == NULL))
    return strx;
    
  *hlp1 = '\000';
  hlp2 = ssh_string_concat_2(strx, dst);
  hlp1 = ssh_replace_in_string(&(hlp1[strlen(src)]), src, dst);
  hlp3 = ssh_string_concat_2(hlp2, hlp1);
  ssh_xfree(strx);
  ssh_xfree(hlp1);

  return hlp3;
}

size_t ssh_strnlen(const char *str, size_t len)
{
  size_t l;

  for(l = 0; len > 0 && *str != '\0'; l++, len--, str++)
    ;

  return l;
}

/*
 * Pretty print numbers using kilo/mega etc abbrevs to `buffer'. The resulting
 * string is at maximum 3 numbers + letter (kMGTPE) + null, so the buffer must
 * be large enough to hold at least 5 characters. Scale can be either 1024, or
 * 1000, and it will specify if the kMGTPE are for 2^10 or for 10^3 multiples.
 */
char *ssh_format_number(char *buffer, size_t len, SshUInt64 number, int scale)
{
  const char *scale_str = " kMGTPE";
  double num;

  if (scale != 1000 && scale != 1024)
    ssh_fatal("Invalid scale in the ssh_format_number, must be 1024 or 1000");

  if (number < scale)
    {
      snprintf(buffer, len, "%d", (int) number);
      return buffer;
    }
  num = number;
  while (num >= 1000)
    {
      num /= scale;
      scale_str++;
    }
  if (num < 9.95)
    snprintf(buffer, len, "%1.1f%c", num, *scale_str);
  else
    {
      snprintf(buffer, len, "%d%c", (int) (num + 0.5), *scale_str);
    }
  return buffer; 
}

/*
 * Pretty print time using 23:59:59, 999+23:59, 99999+23, 99999999 format to
 * the `buffer'. Suitable for printing time values from few seconds up to
 * years. The output string at maximum of 9 charcaters, so the buffer must be
 * large enough to hold at least 9 characters.
 */
char *ssh_format_time(char *buffer, size_t len, SshTime t)
{
  if (t < 60 * 60 * 24)
    snprintf(buffer, len, "%02d:%02d:%02d",
             (int)(t / 60 / 60), (int)((t / 60) % 60),(int) (t % 60));
  else
    if (t < 60 * 60 * 24 * 100)
      snprintf(buffer, len, "%d+%02d:%02d",
               (int) (t / 24 / 60 / 60), (int)((t / 60 / 60) % 24),
               (int)((t / 60) % 60));
    else
      if (t / (60 * 60 * 24) < 100000)
        snprintf(buffer, len, "%d+%02d",
                 (int) (t / 24 / 60 / 60), (int)((t / 60 / 60) % 24));
      else
        snprintf(buffer, len, "%d",
                 (int)(t / 24 / 60 / 60));
  return buffer;
}

/* eof (sshmiscstring.c) */
