summaryrefslogtreecommitdiff
path: root/libgo/go/internal/bytealg/bytealg.c
blob: 969732dfebc0284dab83623691f88ce9aaa49ec8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/* bytealg.c -- gccgo implementations of bytealg functions

   Copyright 2018 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.  */

#include <stddef.h>
#include <string.h>

#include "runtime.h"
#include "array.h"

#ifndef HAVE_MEMMEM

#define memmem goMemmem

static const void *goMemmem(const void *in, size_t inl, const void *s, size_t sl) {
	const char *p;
	char first;
	const char *stop;

	if (sl == 0) {
		return in;
	}
	if (inl < sl) {
		return nil;
	}
	first = *(const char *)(s);
	stop = (const char *)(in) + (inl - sl);
	for (p = (const char *)(in); p <= stop; p++) {
		if (*p == first && __builtin_memcmp(p + 1, (const char *)(s) + 1, sl - 1) == 0) {
			return (const void *)(p);
		}
	}
	return nil;
}

#endif

intgo Compare(struct __go_open_array, struct __go_open_array)
  __asm__(GOSYM_PREFIX "internal..z2fbytealg.Compare")
  __attribute__((no_split_stack));

intgo Compare(struct __go_open_array a, struct __go_open_array b)
{
	intgo l;

	l = a.__count;
	if (b.__count < l) {
		l = b.__count;
	}
	if (l > 0 && a.__values != b.__values) {
		int i;

		i = __builtin_memcmp(a.__values, b.__values, (size_t)(l));
		if (i < 0) {
			return -1;
		} else if (i > 0) {
			return 1;
		}
	}
	if (a.__count < b.__count) {
		return -1;
	}
	if (a.__count > b.__count) {
		return +1;
	}
	return 0;
}

intgo IndexByte(struct __go_open_array, byte)
  __asm__(GOSYM_PREFIX "internal..z2fbytealg.IndexByte")
  __attribute__((no_split_stack));

intgo IndexByte(struct __go_open_array b, byte c)
{
	const byte *p;

	p = __builtin_memchr(b.__values, c, (size_t)(b.__count));
	if (p == nil) {
		return -1;
	}
	return p - (byte *)(b.__values);
}


intgo IndexByteString(String, byte)
  __asm__(GOSYM_PREFIX "internal..z2fbytealg.IndexByteString")
  __attribute__((no_split_stack));

intgo IndexByteString(String s, byte c)
{
	const byte *p;

	p = __builtin_memchr(s.str, c, (size_t)(s.len));
	if (p == nil) {
		return -1;
	}
	return p - s.str;
}

intgo Index(struct __go_open_array, struct __go_open_array)
  __asm__(GOSYM_PREFIX "internal..z2fbytealg.Index")
  __attribute__((no_split_stack));

intgo Index(struct __go_open_array a, struct __go_open_array b)
{
	const byte* p;

	p = memmem(a.__values, a.__count, b.__values, b.__count);
	if (p == nil) {
		return -1;
	}
	return p - (const byte*)(a.__values);
}

intgo IndexString(String, String)
  __asm__(GOSYM_PREFIX "internal..z2fbytealg.IndexString")
  __attribute__((no_split_stack));

intgo IndexString(String a, String b)
{
	const byte* p;

	p = memmem(a.str, a.len, b.str, b.len);
	if (p == nil) {
		return -1;
	}
	return p - a.str;
}