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

#pragma textflag 7
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;
	// leave room for NUL for C runtime (e.g., callers of getenv)
	s.str = runtime·mallocgc(l+1, 0, FlagNoPointers|FlagNoZero);
	s.len = l;
	s.str[l] = 0;
	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;
}

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

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

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

// NOTE: Cannot use func syntax, because we need the ...,
// to signal to the garbage collector that this function does
// not have a fixed size argument count.
#pragma textflag 7
void
runtime·concatstring(intgo n, String s1, ...)
{
	(&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, 0, FlagNoPointers|FlagNoZero);
	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]), 0, FlagNoPointers|FlagNoZero);
	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:
}
