// 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·findnullw(uint16 *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·gostringw(uint16 *str)
{
	int32 n, i;
	byte buf[8];
	String s;

	n = 0;
	for(i=0; str[i]; i++)
		n += runtime·runetochar(buf, str[i]);
	s = runtime·gostringsize(n+4);
	n = 0;
	for(i=0; str[i]; i++)
		n += runtime·runetochar(s.str+n, str[i]);
	s.len = n;
	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:
}
