// 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 "arch.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);
	sl.len = n;
	sl.cap = n;
	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:
}
