// 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	emptystring;

int32
findnull(byte *s)
{
	int32 l;

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

int32
findnullw(uint16 *s)
{
	int32 l;

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

int32 maxstring = 256;

String
gostringsize(int32 l)
{
	String s;

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

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

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

String
gostringw(uint16 *str)
{
	int32 n, i;
	byte buf[8];
	String s;

	n = 0;
	for(i=0; str[i]; i++)
		n += runetochar(buf, str[i]);
	s = gostringsize(n+4);
	n = 0;
	for(i=0; str[i]; i++)
		n += runetochar(s.str+n, str[i]);
	s.len = n;
	return s;
}

func catstring(s1 String, s2 String) (s3 String) {
	if(s1.len == 0) {
		s3 = s2;
		goto out;
	}
	if(s2.len == 0) {
		s3 = s1;
		goto out;
	}

	s3 = gostringsize(s1.len + s2.len);
	mcpy(s3.str, s1.str, s1.len);
	mcpy(s3.str+s1.len, s2.str, s2.len);
out:
}

static void
prbounds(int8* s, int32 a, int32 b, int32 c)
{
	prints(s);
	prints(" ");
	·printint(a);
	prints("<");
	·printint(b);
	prints(">");
	·printint(c);
	prints("\n");
	throw("string bounds");
}

uint32
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
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) {
		·printpc(&si);
		prints(" ");
		prbounds("slice", lindex, si.len, hindex);
	}

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

//	alternate to create a new string
//	so = gostringsize(l);
//	mcpy(so.str, si.str+lindex, l);
}

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

	if(lindex < 0 || lindex > si.len) {
		·printpc(&si);
		prints(" ");
		prbounds("slice", lindex, si.len, si.len);
	}

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

//	alternate to create a new string
//	so = gostringsize(l);
//	mcpy(so.str, si.str+lindex, l);
}

func indexstring(s String, i int32) (b byte) {
	if(i < 0 || i >= s.len) {
		·printpc(&s);
		prints(" ");
		prbounds("index", 0, i, s.len);
	}

	b = s.str[i];
}

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

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

func stringtoslicebyte(s String) (b Slice) {
	b.array = mallocgc(s.len, RefNoPointers, 1, 1, 1);
	b.len = s.len;
	b.cap = s.len;
	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 += runetochar(dum, a[i]);
	}

	s = gostringsize(siz1+4);
	siz2 = 0;
	for(i=0; i<b.len; i++) {
		// check for race
		if(siz2 >= siz1)
			break;
		siz2 += 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 += charntorune(&dum, p, ep-p);
		n++;
	}

	b.array = mallocgc(n*sizeof(r[0]), RefNoPointers, 1, 1, 1);
	b.len = n;
	b.cap = n;
	p = s.str;
	r = (int32*)b.array;
	while(p < ep)
		p += 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 + 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 + charntorune(&retv, s.str+k, s.len-k);

out:
}
