Initial commit
This commit is contained in:
21
LICENSE
Normal file
21
LICENSE
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) [year] [fullname]
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
76
Makefile
Normal file
76
Makefile
Normal file
@@ -0,0 +1,76 @@
|
||||
# Compiler Flags
|
||||
CC := gcc
|
||||
CFLAGS := -g -Wall -Wextra -Werror -pedantic -fsanitize=address,undefined -fno-omit-frame-pointer
|
||||
|
||||
# Directory variables
|
||||
LIBDIR := lib
|
||||
OBJ := obj
|
||||
INC := include
|
||||
SRC := src
|
||||
TEST := tests
|
||||
|
||||
# Filepath Pattern Matching
|
||||
LIB := $(LIBDIR)/lib.a
|
||||
SRCS := $(wildcard $(SRC)/*.c)
|
||||
OBJS := $(patsubst $(SRC)/%.c, $(OBJ)/%.o, $(SRCS))
|
||||
TESTS := $(wildcard $(TEST)/*.c)
|
||||
TESTBINS := $(patsubst $(TEST)/%.c, $(TEST)/bin/%, $(TESTS))
|
||||
|
||||
# Commands must be labeled PHONY
|
||||
.PHONY: all release clean test
|
||||
|
||||
# Compiler Release Flags
|
||||
release: CFLAGS := -Wall -Wextra -Werror -pedantic -fsanitize=address,undefined -fno-omit-frame-pointer -O2 -DNDEBUG
|
||||
release: clean $(LIB)
|
||||
|
||||
# Target for compilation.
|
||||
all: $(LIB)
|
||||
|
||||
# Target / Dependencies
|
||||
$(LIB): $(OBJS) | $(LIBDIR)
|
||||
$(RM) $(LIB)
|
||||
ar -cvrs $@ $^
|
||||
|
||||
$(OBJ)/%.o: $(SRC)/%.c $(SRC)/%.h | $(OBJ)
|
||||
$(CC) $(CFLAGS) -c $< -o $@
|
||||
|
||||
$(OBJ)/%.o: $(SRC)/%.c | $(OBJ)
|
||||
$(CC) $(CFLAGS) -c $< -o $@
|
||||
|
||||
$(TEST)/bin/%: $(TEST)/%.c $(LIB) | $(TEST)/bin
|
||||
$(CC) $(CFLAGS) $< $(LIB) -o $@
|
||||
|
||||
# Make directories if none.
|
||||
$(LIBDIR):
|
||||
mkdir $@
|
||||
|
||||
$(INC):
|
||||
mkdir $@
|
||||
|
||||
$(OBJ):
|
||||
mkdir $@
|
||||
|
||||
$(TEST)/bin:
|
||||
mkdir $@
|
||||
|
||||
# Run the tests in the bin folder and track results
|
||||
test: $(LIB) $(TEST)/bin $(TESTBINS)
|
||||
@SUCCESS_COUNT=0; FAILURE_COUNT=0; \
|
||||
for test in $(TESTBINS); do \
|
||||
./$$test; \
|
||||
EXIT_CODE=$$?; \
|
||||
TEST_NAME=$(notdir $$test); \
|
||||
if [ $$EXIT_CODE -eq 0 ]; then \
|
||||
echo "\033[0;32m$$TEST_NAME: EXIT CODE: $$EXIT_CODE (SUCCESS)\033[0m"; \
|
||||
SUCCESS_COUNT=$$((SUCCESS_COUNT + 1)); \
|
||||
else \
|
||||
echo "\033[0;31m$$TEST_NAME: EXIT CODE: $$EXIT_CODE (FAILURE)\033[0m"; \
|
||||
FAILURE_COUNT=$$((FAILURE_COUNT + 1)); \
|
||||
fi; \
|
||||
done; \
|
||||
echo "\n\nTests completed"; \
|
||||
echo "SUCCESS: $$SUCCESS_COUNT"; \
|
||||
echo "FAILURE: $$FAILURE_COUNT";
|
||||
|
||||
clean:
|
||||
$(RM) -r $(LIBDIR) $(OBJ) $(TEST)/bin/
|
||||
28
README.md
Normal file
28
README.md
Normal file
@@ -0,0 +1,28 @@
|
||||
# sv
|
||||
|
||||
## Description
|
||||
String View implementation written in c.
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- [Description](#description)
|
||||
- [Features](#features)
|
||||
- [Usage](#usage)
|
||||
- [Credits / Resources](#credits--resources)
|
||||
- [License](#license)
|
||||
|
||||
## Features / TODOS
|
||||
+ Easy strings.
|
||||
+ Safe access.
|
||||
+ Clear semantics
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
## Credits / Resources
|
||||
[Mongoose Webserver](https://mongoose.ws/)<br>
|
||||
[Tsoding SV](https://github.com/tsoding/sv)<br>
|
||||
[C Interfaces and Implementations - David Hanson](https://github.com/drh/cii)<br>
|
||||
|
||||
## License
|
||||
This project is licensed under MIT - see the [LICENSE](LICENSE) file for details.
|
||||
34
include/sv.h
Normal file
34
include/sv.h
Normal file
@@ -0,0 +1,34 @@
|
||||
#ifndef SV_INCLUDED
|
||||
#define SV_INCLUDED
|
||||
|
||||
#include <stddef.h>
|
||||
struct String_View {
|
||||
size_t len;
|
||||
const char *buf;
|
||||
};
|
||||
typedef struct String_View SV;
|
||||
|
||||
// Macros for String_View printf
|
||||
#define SV_FMT "%.*s"
|
||||
#define SV_ARG(sv) (int) (sv).len, (sv).buf
|
||||
|
||||
// Null String
|
||||
#define SV_NULL sv_strn(NULL, 0)
|
||||
|
||||
extern struct String_View sv_str(const char *s);
|
||||
extern struct String_View sv_strn(const char *s, size_t n);
|
||||
extern struct String_View sv_trim_left(struct String_View sv);
|
||||
extern struct String_View sv_trim_right(struct String_View sv);
|
||||
extern struct String_View sv_trim(struct String_View sv);
|
||||
extern int sv_eq(const struct String_View sv1, const struct String_View sv2);
|
||||
extern int sv_casecmp( const struct String_View sv1, const struct String_View sv2);
|
||||
extern struct String_View sv_before_delim(const struct String_View sv,
|
||||
const char *delims);
|
||||
extern struct String_View sv_after_delim(const struct String_View sv,
|
||||
const char *delims);
|
||||
extern struct String_View sv_str_str(const struct String_View haystack,
|
||||
const struct String_View needle);
|
||||
extern size_t sv_pack_size(const struct String_View sv);
|
||||
extern void sv_pack(unsigned char *buf, const struct String_View sv);
|
||||
extern struct String_View sv_unpack(unsigned char *buf);
|
||||
#endif
|
||||
152
src/sv.c
Normal file
152
src/sv.c
Normal file
@@ -0,0 +1,152 @@
|
||||
#include "../include/sv.h"
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
static bool sv_is_space(int c) {
|
||||
return c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '\v' || c == '\f';
|
||||
}
|
||||
static int sv_tolc(char c) {
|
||||
return (c >= 'A' && c <= 'Z') ? c + 'a' - 'A' : c;
|
||||
}
|
||||
static void sv_pack_u64(uint64_t i, unsigned char *buf){
|
||||
*buf++ = i>>56;
|
||||
*buf++ = i>>48;
|
||||
*buf++ = i>>40;
|
||||
*buf++ = i>>32;
|
||||
*buf++ = i>>24;
|
||||
*buf++ = i>>16;
|
||||
*buf++ = i>>8;
|
||||
*buf++ = i;
|
||||
}
|
||||
static uint64_t sv_unpack_u64(unsigned char *buf){
|
||||
return ((unsigned long long int)buf[0]<<56) |
|
||||
((unsigned long long int)buf[1]<<48) |
|
||||
((unsigned long long int)buf[2]<<40) |
|
||||
((unsigned long long int)buf[3]<<32) |
|
||||
((unsigned long long int)buf[4]<<24) |
|
||||
((unsigned long long int)buf[5]<<16) |
|
||||
((unsigned long long int)buf[6]<<8) |
|
||||
buf[7];
|
||||
}
|
||||
struct String_View sv_str(const char *s) {
|
||||
struct String_View str = {s == NULL ? 0 : strlen(s), (char *) s };
|
||||
return str;
|
||||
}
|
||||
struct String_View sv_strn(const char *s, size_t n) {
|
||||
struct String_View str = {n, (char *) s};
|
||||
return str;
|
||||
}
|
||||
|
||||
struct String_View sv_trim(struct String_View s){
|
||||
while (s.len > 0 && sv_is_space((int) *s.buf)) s.buf++, s.len--;
|
||||
while (s.len > 0 && sv_is_space((int) *(s.buf + s.len - 1))) s.len--;
|
||||
return s;
|
||||
}
|
||||
struct String_View sv_trim_left(struct String_View s){
|
||||
while (s.len > 0 && sv_is_space((int) *s.buf)) s.buf++, s.len--;
|
||||
return s;
|
||||
}
|
||||
struct String_View sv_trim_right(struct String_View s){
|
||||
|
||||
while (s.len > 0 && sv_is_space((int) *(s.buf + s.len - 1))) s.len--;
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
int sv_eq( const struct String_View sv1, const struct String_View sv2){
|
||||
if (sv1.len != sv2.len) {
|
||||
return 0;
|
||||
} else {
|
||||
return memcmp(sv1.buf, sv2.buf, sv1.len) == 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
int sv_casecmp(const struct String_View sv1, const struct String_View sv2){
|
||||
size_t i = 0;
|
||||
while (i < sv1.len && i < sv2.len) {
|
||||
int c1 = sv_tolc(sv1.buf[i]);
|
||||
int c2 = sv_tolc(sv2.buf[i]);
|
||||
if (c1 < c2) return -1;
|
||||
if (c1 > c2) return 1;
|
||||
i++;
|
||||
}
|
||||
if (i < sv1.len) return 1;
|
||||
if (i < sv2.len) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct String_View sv_before_delim(const struct String_View sv,const char *delims){
|
||||
// Handle NULL pointer or empty string view
|
||||
if (sv.buf == NULL || delims == NULL) {
|
||||
return sv_strn(NULL, 0);
|
||||
}
|
||||
|
||||
size_t i = 0;
|
||||
while (i < sv.len) {
|
||||
// Check if the current character is a delimiter
|
||||
for (size_t j = 0; delims[j] != '\0'; j++) {
|
||||
if (sv.buf[i] == delims[j]) {
|
||||
struct String_View result = sv_strn(sv.buf, i);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
// Return the whole string if no delimiter was found
|
||||
struct String_View result = sv_strn(sv.buf, i);
|
||||
return result;
|
||||
|
||||
}
|
||||
struct String_View sv_after_delim(const struct String_View sv, const char *delims){
|
||||
// Handle NULL pointer or empty string view
|
||||
if (sv.buf == NULL || delims == NULL) {
|
||||
return sv_strn(NULL, 0);
|
||||
}
|
||||
|
||||
size_t i = 0;
|
||||
while (i < sv.len) {
|
||||
// Check if the current character is a delimiter
|
||||
for (size_t j = 0; delims[j] != '\0'; j++) {
|
||||
if (sv.buf[i] == delims[j]) {
|
||||
struct String_View result = sv_strn(sv.buf+i+1, sv.len-i-1);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
// Return the whole string if no delimiter was found
|
||||
struct String_View result = sv_strn(sv.buf, i);
|
||||
return result;
|
||||
}
|
||||
|
||||
struct String_View sv_str_str(const struct String_View haystack, const struct String_View needle){
|
||||
size_t i;
|
||||
if (needle.len > haystack.len) return sv_strn(NULL,0);
|
||||
if (needle.len == 0) return haystack;
|
||||
for (i = 0; i <= haystack.len - needle.len; i++) {
|
||||
if (memcmp(haystack.buf + i, needle.buf, needle.len) == 0) {
|
||||
return sv_strn(haystack.buf + i, haystack.len -i);
|
||||
}
|
||||
}
|
||||
return sv_strn(NULL,0);
|
||||
}
|
||||
|
||||
size_t sv_pack_size(const struct String_View sv){
|
||||
size_t result = 0;
|
||||
result += sv.len;
|
||||
result += sizeof(uint64_t);
|
||||
return result;
|
||||
}
|
||||
void sv_pack(unsigned char *buf, const struct String_View sv){
|
||||
sv_pack_u64(sv.len, buf);
|
||||
size_t offset = sizeof(uint64_t);
|
||||
memcpy(buf+offset, sv.buf, sv.len);
|
||||
}
|
||||
struct String_View sv_unpack(unsigned char *buf){
|
||||
size_t len = sv_unpack_u64(buf);
|
||||
return sv_strn((const char *)buf+sizeof(uint64_t),len);
|
||||
}
|
||||
15
tests/01_sv_str.c
Normal file
15
tests/01_sv_str.c
Normal file
@@ -0,0 +1,15 @@
|
||||
#define DEBUG
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include "../include/sv.h"
|
||||
|
||||
int main(void){
|
||||
const char *s = "Hello World!";
|
||||
SV sv = sv_str(s);
|
||||
|
||||
assert(sv.buf != NULL);
|
||||
assert(strlen(s) == sv.len);
|
||||
assert( memcmp(sv.buf, s, strlen(s) ) == 0);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
15
tests/02_sv_strn.c
Normal file
15
tests/02_sv_strn.c
Normal file
@@ -0,0 +1,15 @@
|
||||
#define DEBUG
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include "../include/sv.h"
|
||||
|
||||
int main(void){
|
||||
const char *s = "Hello World!";
|
||||
SV sv = sv_strn(s, strlen(s));
|
||||
|
||||
assert(sv.buf != NULL);
|
||||
assert(strlen(s) == sv.len);
|
||||
assert( memcmp(sv.buf, s, strlen(s) ) == 0);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
24
tests/03_trim_left.c
Normal file
24
tests/03_trim_left.c
Normal file
@@ -0,0 +1,24 @@
|
||||
#define DEBUG
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include "../include/sv.h"
|
||||
|
||||
int main(void){
|
||||
const char *s = " Hello World!";
|
||||
const char *s2 = "Hello World!";
|
||||
|
||||
SV sv = sv_str(s);
|
||||
|
||||
assert(sv.buf != NULL);
|
||||
assert(strlen(s) == sv.len);
|
||||
assert( memcmp(sv.buf, s, strlen(s)) == 0);
|
||||
SV sv2 = sv_trim_left(sv);
|
||||
assert(sv2.len != strlen(s));
|
||||
assert( memcmp(sv2.buf, s, sv2.len) != 0);
|
||||
assert( memcmp(sv2.buf, s2, sv2.len) == 0);
|
||||
assert( sv2.len == strlen(s2));
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
21
tests/04_trim_right.c
Normal file
21
tests/04_trim_right.c
Normal file
@@ -0,0 +1,21 @@
|
||||
#define DEBUG
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include "../include/sv.h"
|
||||
|
||||
int main(void){
|
||||
const char *s = "Hello World! ";
|
||||
const char *s2 = "Hello World!";
|
||||
|
||||
SV sv = sv_str(s);
|
||||
assert(sv.buf != NULL);
|
||||
assert(strlen(s) == sv.len);
|
||||
assert( memcmp(sv.buf, s, strlen(s)) == 0);
|
||||
SV sv2 = sv_trim_right(sv);
|
||||
assert(sv2.len == strlen(s2));
|
||||
assert(memcmp(s2, sv2.buf, sv2.len) == 0);
|
||||
assert(sv2.len != strlen(s));
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
22
tests/05_trim.c
Normal file
22
tests/05_trim.c
Normal file
@@ -0,0 +1,22 @@
|
||||
#define DEBUG
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include "../include/sv.h"
|
||||
|
||||
int main(void){
|
||||
const char *s = " Hello World! ";
|
||||
const char *s2 = "Hello World!";
|
||||
|
||||
SV sv = sv_str(s);
|
||||
assert(sv.buf != NULL);
|
||||
assert(strlen(s) == sv.len);
|
||||
assert( memcmp(sv.buf, s, strlen(s)) == 0);
|
||||
SV sv2 = sv_trim(sv);
|
||||
assert(sv2.len == strlen(s2));
|
||||
assert(memcmp(s2, sv2.buf, sv2.len) == 0);
|
||||
assert(sv2.len != strlen(s));
|
||||
assert( memcmp(s, sv2.buf, sv2.len) != 0);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
25
tests/06_sv_eq.c
Normal file
25
tests/06_sv_eq.c
Normal file
@@ -0,0 +1,25 @@
|
||||
#define DEBUG
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include "../include/sv.h"
|
||||
|
||||
int main(void){
|
||||
const char *s = " Hello World! ";
|
||||
const char *s2 = "Hello World!";
|
||||
|
||||
SV sv = sv_str(s);
|
||||
SV sv3 = sv_str(s2);
|
||||
assert(sv.buf != NULL);
|
||||
assert(strlen(s) == sv.len);
|
||||
assert( memcmp(sv.buf, s, strlen(s)) == 0);
|
||||
SV sv2 = sv_trim(sv);
|
||||
assert(sv2.len == strlen(s2));
|
||||
assert(memcmp(s2, sv2.buf, sv2.len) == 0);
|
||||
assert(sv2.len != strlen(s));
|
||||
assert( memcmp(s, sv2.buf, sv2.len) != 0);
|
||||
assert( !sv_eq(sv, sv2));
|
||||
assert( sv_eq(sv2,sv3));
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
29
tests/07_case_cmp.c
Normal file
29
tests/07_case_cmp.c
Normal file
@@ -0,0 +1,29 @@
|
||||
#define DEBUG
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include "../include/sv.h"
|
||||
|
||||
int main(void){
|
||||
const char *s = " Hello World! ";
|
||||
const char *s2 = "Hello World!";
|
||||
const char *s3 = "hElLo wOrLD!";
|
||||
const char *s4 = "Goodbye World!";
|
||||
|
||||
SV sv = sv_str(s);
|
||||
SV sv3 = sv_str(s3);
|
||||
SV sv4 = sv_str(s4);
|
||||
assert(sv.buf != NULL);
|
||||
assert(strlen(s) == sv.len);
|
||||
assert( memcmp(sv.buf, s, strlen(s)) == 0);
|
||||
SV sv2 = sv_trim(sv);
|
||||
assert(sv2.len == strlen(s2));
|
||||
assert(memcmp(s2, sv2.buf, sv2.len) == 0);
|
||||
assert(sv2.len != strlen(s));
|
||||
assert( memcmp(s, sv2.buf, sv2.len) != 0);
|
||||
assert( !sv_eq(sv, sv2));
|
||||
assert( sv_casecmp(sv2,sv3) == 0);
|
||||
assert( sv_casecmp(sv3,sv4) == 1);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
18
tests/08_sv_before_delims.c
Normal file
18
tests/08_sv_before_delims.c
Normal file
@@ -0,0 +1,18 @@
|
||||
#define DEBUG
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include "../include/sv.h"
|
||||
|
||||
int main(void){
|
||||
const char *s = "Hello World!,Goodbye World!";
|
||||
const char *s3 = "Hello World!";
|
||||
|
||||
struct String_View sv = sv_strn(s, strlen(s));
|
||||
struct String_View sv2 = sv_before_delim(sv,",");
|
||||
assert(sv2.len == strlen(s3));
|
||||
assert( memcmp(sv2.buf, s3, sv2.len) == 0);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
18
tests/09_after_delims.c
Normal file
18
tests/09_after_delims.c
Normal file
@@ -0,0 +1,18 @@
|
||||
#define DEBUG
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include "../include/sv.h"
|
||||
|
||||
int main(void){
|
||||
const char *s = "Hello World!,Goodbye World!";
|
||||
const char *s3 = "Goodbye World!";
|
||||
|
||||
struct String_View sv = sv_strn(s, strlen(s));
|
||||
struct String_View sv2 = sv_after_delim(sv,",");
|
||||
assert(sv2.len == strlen(s3));
|
||||
assert( memcmp(sv2.buf, s3, sv2.len) == 0);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
20
tests/10_strstr.c
Normal file
20
tests/10_strstr.c
Normal file
@@ -0,0 +1,20 @@
|
||||
#define DEBUG
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include "../include/sv.h"
|
||||
|
||||
int main(void){
|
||||
const char *s = "Hello World!,Goodbye World!";
|
||||
const char *n = "Goodbye";
|
||||
const char *test = "Goodbye World!";
|
||||
struct String_View sv = sv_strn(s, strlen(s));
|
||||
struct String_View sv2 = sv_strn(n, strlen(n));
|
||||
|
||||
struct String_View found = sv_str_str(sv, sv2);
|
||||
assert(found.len == strlen(test));
|
||||
assert( memcmp(found.buf, test, found.len) == 0);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
24
tests/11_sv_pack.c
Normal file
24
tests/11_sv_pack.c
Normal file
@@ -0,0 +1,24 @@
|
||||
#define DEBUG
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include "../include/sv.h"
|
||||
|
||||
int main(void){
|
||||
const char *s = "Hello";
|
||||
struct String_View sv = sv_strn(s, strlen(s));
|
||||
size_t offset = sv_pack_size(sv);
|
||||
unsigned char *buf = malloc(offset);
|
||||
|
||||
sv_pack(buf, sv);
|
||||
|
||||
struct String_View out = sv_unpack(buf);
|
||||
assert(out.len == strlen(s));
|
||||
assert( memcmp(out.buf, s, out.len) == 0);
|
||||
assert( sv_eq(sv, out));
|
||||
assert( sv_casecmp(sv, out ) == 0);
|
||||
free(buf);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
21
tests/12_sv_pack2.c
Normal file
21
tests/12_sv_pack2.c
Normal file
@@ -0,0 +1,21 @@
|
||||
#define DEBUG
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include "../include/sv.h"
|
||||
|
||||
int main(void){
|
||||
const char *s = "Hello";
|
||||
size_t offset = strlen(s) + sizeof(uint64_t);
|
||||
unsigned char *buf = malloc(offset);
|
||||
struct String_View sv = sv_strn(s, strlen(s));
|
||||
sv_pack(buf, sv);
|
||||
|
||||
struct String_View out = sv_unpack(buf);
|
||||
assert(out.len == strlen(s));
|
||||
assert( memcmp(out.buf, s, out.len) == 0);
|
||||
free(buf);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
Reference in New Issue
Block a user