// 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"
#include "../../cmd/ld/textflag.h"

String	runtime·emptystring;

#pragma textflag NOSPLIT
intgo
runtime·findnull(byte *s)
{
	intgo l;

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

intgo
runtime·findnullw(uint16 *s)
{
	intgo l;

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

uintptr runtime·maxstring = 256; // a hint for print

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

	if(l == 0)
		return runtime·emptystring;
	s.str = runtime·mallocgc(l, 0, FlagNoScan|FlagNoZero);
	s.len = l;
	for(;;) {
		ms = runtime·maxstring;
		if((uintptr)l <= ms || runtime·casp((void**)&runtime·maxstring, (void*)ms, (void*)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;
}

// used by cmd/cgo
Slice
runtime·gobytes(byte *p, intgo n)
{
	Slice sl;

	sl.array = runtime·mallocgc(n, 0, FlagNoScan|FlagNoZero);
	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;
}

func cstringToGo(str *byte) (s String) {
	s = runtime·gostringnocopy(str);
}

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 NOSPLIT
func concatstring2(s1 String, s2 String) (res String) {
	USED(&s2);
	res = concatstring(2, &s1);
}
#pragma textflag NOSPLIT
func concatstring3(s1 String, s2 String, s3 String) (res String) {
	USED(&s2);
	USED(&s3);
	res = concatstring(3, &s1);
}
#pragma textflag NOSPLIT
func concatstring4(s1 String, s2 String, s3 String, s4 String) (res String) {
	USED(&s2);
	USED(&s3);
	USED(&s4);
	res = concatstring(4, &s1);
}
#pragma textflag NOSPLIT
func concatstring5(s1 String, s2 String, s3 String, s4 String, s5 String) (res String) {
	USED(&s2);
	USED(&s3);
	USED(&s4);
	USED(&s5);
	res = concatstring(5, &s1);
}
#pragma textflag NOSPLIT
func concatstrings(s Slice) (res String) {
	res = concatstring(s.len, (String*)s.array);
}

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

int32
runtime·strncmp(byte *s1, byte *s2, uintptr n)
{
	uintptr i;
	byte c1, c2;

	for(i=0; i<n; i++) {
		c1 = s1[i];
		c2 = s2[i];
		if(c1 < c2)
			return -1;
		if(c1 > c2)
			return +1;
		if(c1 == 0)
			break;
	}
	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 slicebytetostringtmp(b Slice) (s String) {
	void *pc;

	if(raceenabled) {
		pc = runtime·getcallerpc(&b);
		runtime·racereadrangepc(b.array, b.len, pc, runtime·slicebytetostringtmp);
	}
	
	// Return a "string" referring to the actual []byte bytes.
	// This is only for use by internal compiler optimizations
	// that know that the string form will be discarded before
	// the calling goroutine could possibly modify the original
	// slice or synchronize with another goroutine.
	// Today, the only such case is a m[string(k)] lookup where
	// m is a string-keyed map and k is a []byte.
	s.str = b.array;
	s.len = b.len;
}

func stringtoslicebyte(s String) (b Slice) {
	uintptr cap;

	cap = runtime·roundupsize(s.len);
	b.array = runtime·mallocgc(cap, 0, FlagNoScan|FlagNoZero);
	b.len = s.len;
	b.cap = cap;
	runtime·memmove(b.array, s.str, s.len);
	if(cap != b.len)
		runtime·memclr(b.array+b.len, cap-b.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;
	uintptr mem;

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

	if(n > MaxMem/sizeof(r[0]))
		runtime·throw("out of memory");
	mem = runtime·roundupsize(n*sizeof(r[0]));
	b.array = runtime·mallocgc(mem, 0, FlagNoScan|FlagNoZero);
	b.len = n;
	b.cap = mem/sizeof(r[0]);
	p = s.str;
	r = (int32*)b.array;
	while(p < ep)
		p += runtime·charntorune(r++, p, ep-p);
	if(b.cap > b.len)
		runtime·memclr(b.array+b.len*sizeof(r[0]), (b.cap-b.len)*sizeof(r[0]));
}

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:
}
