// 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_GOARCH.h"
#include "malloc.h"
#include "race.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; // a hint for print

static String
gostringsize(intgo l)
{
	String s;
	uint32 ms;

	if(l == 0)
		return runtime·emptystring;
	// leave room for NUL for C runtime (e.g., callers of getenv)
	s.str = runtime·mallocgc(l+1, FlagNoPointers, 1, 0);
	s.len = l;
	s.str[l] = 0;
	for(;;) {
		ms = runtime·maxstring;
		if((uint32)l <= ms || runtime·cas(&runtime·maxstring, ms, (uint32)l))
			break;
	}
	return s;
}

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

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

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

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

Slice
runtime·gobytes(byte *p, intgo 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)
{
	intgo n1, n2, i;
	byte buf[8];
	String s;

	n1 = 0;
	for(i=0; str[i]; i++)
		n1 += runtime·runetochar(buf, str[i]);
	s = gostringsize(n1+4);
	n2 = 0;
	for(i=0; str[i]; i++) {
		// check for race
		if(n2 >= n1)
			break;
		n2 += runtime·runetochar(s.str+n2, str[i]);
	}
	s.len = n2;
	s.str[s.len] = 0;
	return s;
}

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

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

	s3 = 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(intgo n, String *s)
{
	intgo i, l, count;
	String out;

	l = 0;
	count = 0;
	for(i=0; i<n; i++) {
		if(l + s[i].len < l)
			runtime·throw("string concatenation too long");
		l += s[i].len;
		if(s[i].len > 0) {
			count++;
			out = s[i];
		}
	}
	if(count == 0)
		return runtime·emptystring;
	if(count == 1) // zero or one non-empty string in concatenation
		return out;
	
	out = 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 int, s1 String) {
	(&s1)[n] = concatstring(n, &s1);
}

func eqstring(s1 String, s2 String) (v bool) {
	if(s1.len != s2.len) {
		v = false;
		return;
	}
	if(s1.str == s2.str) {
		v = true;
		return;
	}
	v = runtime·memeq(s1.str, s2.str, s1.len);
}

int32
runtime·strcmp(byte *s1, byte *s2)
{
	uintptr 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 intstring(v int64) (s String) {
	s = gostringsize(8);
	s.len = runtime·runetochar(s.str, v);
	s.str[s.len] = 0;
}

func slicebytetostring(b Slice) (s String) {
	void *pc;

	if(raceenabled) {
		pc = runtime·getcallerpc(&b);
		runtime·racereadrangepc(b.array, b.len, pc, runtime·slicebytetostring);
	}
	s = 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, 0);
	b.len = s.len;
	b.cap = s.len;
	runtime·memmove(b.array, s.str, s.len);
}

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

	if(raceenabled) {
		pc = runtime·getcallerpc(&b);
		runtime·racereadrangepc(b.array, b.len*sizeof(*a), pc, runtime·slicerunetostring);
	}
	a = (int32*)b.array;
	siz1 = 0;
	for(i=0; i<b.len; i++) {
		siz1 += runtime·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 += runtime·runetochar(s.str+siz2, a[i]);
	}
	s.len = siz2;
	s.str[s.len] = 0;
}

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

	// two passes.
	// unlike slicerunetostring, 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, 0);
	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 int) (retk int) {
	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 int) (retk int, 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:
}
