// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package runtime
#include "runtime.h"
#include "malloc.h"

String	runtime·emptystring;

int32
runtime·findnull(byte *s)
{
	int32 l;

	if(s == nil)
		return 0;
	for(l=0; s[l]!=0; l++)
		;
	return l;
}

int32 runtime·maxstring = 256;

String
runtime·gostringsize(int32 l)
{
	String s;

	if(l == 0)
		return runtime·emptystring;
	s.str = runtime·mal(l+1);	// leave room for NUL for C runtime (e.g., callers of getenv)
	s.len = l;
	if(l > runtime·maxstring)
		runtime·maxstring = l;
	return s;
}

String
runtime·gostring(byte *str)
{
	int32 l;
	String s;

	l = runtime·findnull(str);
	s = runtime·gostringsize(l);
	runtime·mcpy(s.str, str, l);
	return s;
}

String
runtime·gostringn(byte *str, int32 l)
{
	String s;

	s = runtime·gostringsize(l);
	runtime·mcpy(s.str, str, l);
	return s;
}

String
runtime·gostringnocopy(byte *str)
{
	String s;
	
	s.str = str;
	s.len = runtime·findnull(str);
	return s;
}

String
runtime·catstring(String s1, String s2)
{
	String s3;

	if(s1.len == 0)
		return s2;
	if(s2.len == 0)
		return s1;

	s3 = runtime·gostringsize(s1.len + s2.len);
	runtime·mcpy(s3.str, s1.str, s1.len);
	runtime·mcpy(s3.str+s1.len, s2.str, s2.len);
	return s3;
}

static String
concatstring(int32 n, String *s)
{
	int32 i, l;
	String out;

	l = 0;
	for(i=0; i<n; i++) {
		if(l + s[i].len < l)
			runtime·throw("string concatenation too long");
		l += s[i].len;
	}
	
	out = runtime·gostringsize(l);
	l = 0;
	for(i=0; i<n; i++) {
		runtime·mcpy(out.str+l, s[i].str, s[i].len);
		l += s[i].len;
	}
	return out;
}

#pragma textflag 7
// s1 is the first of n strings.
// the output string follows.
func concatstring(n int32, s1 String) {
	(&s1)[n] = concatstring(n, &s1);
}

static int32
cmpstring(String s1, String s2)
{
	uint32 i, l;
	byte c1, c2;

	l = s1.len;
	if(s2.len < l)
		l = s2.len;
	for(i=0; i<l; i++) {
		c1 = s1.str[i];
		c2 = s2.str[i];
		if(c1 < c2)
			return -1;
		if(c1 > c2)
			return +1;
	}
	if(s1.len < s2.len)
		return -1;
	if(s1.len > s2.len)
		return +1;
	return 0;
}

func cmpstring(s1 String, s2 String) (v int32) {
	v = cmpstring(s1, s2);
}

int32
runtime·strcmp(byte *s1, byte *s2)
{
	uint32 i;
	byte c1, c2;

	for(i=0;; i++) {
		c1 = s1[i];
		c2 = s2[i];
		if(c1 < c2)
			return -1;
		if(c1 > c2)
			return +1;
		if(c1 == 0)
			return 0;
	}
}

func slicestring(si String, lindex int32, hindex int32) (so String) {
	int32 l;

	if(lindex < 0 || lindex > si.len ||
	   hindex < lindex || hindex > si.len) {
	   	runtime·panicslice();
	}

	l = hindex-lindex;
	so.str = si.str + lindex;
	so.len = l;
}

func slicestring1(si String, lindex int32) (so String) {
	int32 l;

	if(lindex < 0 || lindex > si.len) {
		runtime·panicslice();
	}

	l = si.len-lindex;
	so.str = si.str + lindex;
	so.len = l;
}

func intstring(v int64) (s String) {
	s = runtime·gostringsize(8);
	s.len = runtime·runetochar(s.str, v);
}

func slicebytetostring(b Slice) (s String) {
	s = runtime·gostringsize(b.len);
	runtime·mcpy(s.str, b.array, s.len);
}

func stringtoslicebyte(s String) (b Slice) {
	b.array = runtime·mallocgc(s.len, RefNoPointers, 1, 1);
	b.len = s.len;
	b.cap = s.len;
	runtime·mcpy(b.array, s.str, s.len);
}

func sliceinttostring(b Slice) (s String) {
	int32 siz1, siz2, i;
	int32 *a;
	byte dum[8];

	a = (int32*)b.array;
	siz1 = 0;
	for(i=0; i<b.len; i++) {
		siz1 += runtime·runetochar(dum, a[i]);
	}

	s = runtime·gostringsize(siz1+4);
	siz2 = 0;
	for(i=0; i<b.len; i++) {
		// check for race
		if(siz2 >= siz1)
			break;
		siz2 += runtime·runetochar(s.str+siz2, a[i]);
	}
	s.len = siz2;
}

func stringtosliceint(s String) (b Slice) {
	int32 n;
	int32 dum, *r;
	uint8 *p, *ep;

	// two passes.
	// unlike sliceinttostring, no race because strings are immutable.
	p = s.str;
	ep = s.str+s.len;
	n = 0;
	while(p < ep) {
		p += runtime·charntorune(&dum, p, ep-p);
		n++;
	}

	b.array = runtime·mallocgc(n*sizeof(r[0]), RefNoPointers, 1, 1);
	b.len = n;
	b.cap = n;
	p = s.str;
	r = (int32*)b.array;
	while(p < ep)
		p += runtime·charntorune(r++, p, ep-p);
}

enum
{
	Runeself	= 0x80,
};

func stringiter(s String, k int32) (retk int32) {
	int32 l;

	if(k >= s.len) {
		// retk=0 is end of iteration
		retk = 0;
		goto out;
	}

	l = s.str[k];
	if(l < Runeself) {
		retk = k+1;
		goto out;
	}

	// multi-char rune
	retk = k + runtime·charntorune(&l, s.str+k, s.len-k);

out:
}

func stringiter2(s String, k int32) (retk int32, retv int32) {
	if(k >= s.len) {
		// retk=0 is end of iteration
		retk = 0;
		retv = 0;
		goto out;
	}

	retv = s.str[k];
	if(retv < Runeself) {
		retk = k+1;
		goto out;
	}

	// multi-char rune
	retk = k + runtime·charntorune(&retv, s.str+k, s.len-k);

out:
}
