/**********************************************************************
 * Copyright (c) 2005, 2007 IBM Corporation and others.
 * All rights reserved.   This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * $Id: utility.c,v 1.2 2007/04/06 00:57:47 jkubasta Exp $
 * 
 * Contributors: 
 * IBM - Initial API and implementation
 **********************************************************************/

#include "utility.h"
#include "JvmpiWriter.h"
#include <stdlib.h>

/********************************************************
 * strcpyrealloc()
 * 
 * Copy one string to the other, first reallocating the 
 * space pointed to by the destination so that the src
 * can comfortably fit in it. 
 * @param dest address of the destination buffer 
 * @param src the source string 
 * @return 0 if successful, -1 otherwise 
 */ 

int strcpyrealloc(char **dest, const char *src) {
	char *tmp; 
	if (*dest) {
		/* if realloc fails, we don't want to overwrite *dest or we'll get
		   a memory leak */ 
		tmp = (char *)realloc(*dest,strlen(src)+1); 
	} else {
		tmp = (char *)malloc(strlen(src)+1); 
	}
	if (!tmp) {
		return -1; 
	} else {
		*dest = tmp;
	}
	strcpy(*dest,src); 
	return 0; 
}

/** CALLOC  *************************************************************
  * Allocate some memory from the heap.  If there is no more memory left
  * the VM will exit gracefully.
  */
extern void* jvmpiAgent_Calloc(unsigned int size) {
	void *p=malloc(size);
	if(p==NULL) {
		fprintf(stderr, "FATAL ERROR:  Out of memory...JVM Exiting\n");
		fflush(stderr); 
		_jvmpiAgent_jvmpiInterface->ProfilerExit((jint)-1);
	}
	memset(p, 0, size);
	return p;
}


#ifdef MVS                    
#pragma convlit(suspend)
#endif
unsigned short double2string(double val, char *buffer, unsigned short offset, int precision) {

	int i; 
	Uint64 digits;

	digits = (Uint64) val; 
	
	/* print the values that occur before the decimal */ 
	offset += sprintf(&buffer[offset], "%lld", digits); 
 
	/* hard code the period '.' as the decimal symbol */ 
	buffer[offset++] = '.'; 
	/* get the digits to the right of the decimal */ 
#ifdef _WIN32
	val = val - (signed __int64)digits; 
#else 
	val = val - digits; 
#endif
	/* move the digits to the right of the decimal to be to the left */ 
	/* the following loop essentially shifts each digit left, at which point we grab
	   it and add it to the string. */ 
	for (i = 0; i < precision; i++) {
		val = val * 10; 
	    /* get the next digit */ 
		digits = (Uint64) val; 
		buffer[offset++] = '0' + (char)digits; 
#ifdef _WIN32
		val = val - (signed __int64)digits; 
#else
		val = val - digits; 
#endif
	}
	return offset; 
}
#ifdef MVS                    
#pragma convlit(resume)
#endif


#ifdef _WIN32
char *realpath(const char* fileName, char * buf)
{
	LPTSTR foo;

	GetFullPathName (fileName, PATH_MAX, buf, &foo);
	return buf;
}
#elif defined(__OS400__)
char *realpath(const char* fileName, char * buf)
{
	strcpy(buf, fileName);
	return buf;
}
#endif
