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

uint32 runtime·maxstring = 256;

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

	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;
	for(;;) {
		ms = runtime·maxstring;
		if((uint32)l <= ms || runtime·cas(&runtime·maxstring, ms, (uint32)l))
			break;
	}
	return s;
}

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

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

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

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

Slice
runtime·gobytes(byte *p, int32 n)
{
	Slice sl;

	sl.array = runtime·mallocgc(n, FlagNoPointers, 1, 0);
	runtime·memmove(sl.array, p, n);
	return sl;
}

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·memmove(s3.str, s1.str, s1.len);
	runtime·memmove(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·memmove(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;
	}
}

byte*
runtime·strstr(byte *s1, byte *s2)
{
	byte *sp1, *sp2;

	if(*s2 == 0)
		return s1;
	for(; *s1; s1++) {
		if(*s1 != *s2)
			continue;
		sp1 = s1;
		sp2 = s2;
		for(;;) {
			if(*sp2 == 0)
				return s1;
			if(*sp1++ != *sp2++)
				break;
		}
	}
	return nil;
}

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·memmove(s.str, b.array, s.len);
}

func stringtoslicebyte(s String) (b Slice) {
	b.array = runtime·mallocgc(s.len, FlagNoPointers, 1, 1);
	b.len = s.len;
	b.cap = s.len;
	runtime·memmove(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]), FlagNoPointers, 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:
}
