Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

to decode u64 or i64 slice in native c #455

Draft
wants to merge 25 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
190 changes: 190 additions & 0 deletions native/goIntSlice.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
#include <stdio.h>
#include <malloc.h>
#include <stdbool.h>
#include <stdint.h>
#include <stddef.h>
#include <string.h>

#include "native.h"
#include "types.h"

#define ERR_INVAL 2
#define ERR_RECURSE_MAX 7

typedef struct {
union { // the pointer of u64 or i64 array
int64_t* iptr;
uint64_t* uptr;
};
size_t len; // the length of slice
size_t cap; // the capacity of slice
} GoIntSlice;



bool isSpace(char a){
liuq19 marked this conversation as resolved.
Show resolved Hide resolved
if( a == ' '){
return true;
}else{
return false;
}
}

bool isIntger(char a){
if(a<'0' ||a>'9'){
return false;
}else{
return true;
}
}

int charToNum(char c){
liuq19 marked this conversation as resolved.
Show resolved Hide resolved
return c-'0';
}


long decode_u64_array( const GoString* src, long* p, GoIntSlice* arr){
char* pos = src->buf;
int i =0;
liuq19 marked this conversation as resolved.
Show resolved Hide resolved

while(isSpace(pos[i])){ //If there is a space before the beginning, eat the space first
i++;
}
if(pos[i] != '['){ //If the first one is not a left bracket, returning it directly is illegal
*p = i+1; //P points to the first position after the error
arr->len = 0;
return ERR_INVAL;
}
i++; //It's a left parenthesis
liuq19 marked this conversation as resolved.
Show resolved Hide resolved
int k =0; //K+1 represents the number of digits in the string src
int num = 0; //Num is used to store the current number
while(pos[i] !='\0'){
if(k==arr->cap){ //If the capacity is insufficient, return ERR_ RECURSE_ MAX
*p = i+1;
return ERR_RECURSE_MAX;
liuq19 marked this conversation as resolved.
Show resolved Hide resolved
}
while(isSpace(pos[i])){ //Jump back if it's a space
i++;
}
if(pos[i]<'0' || pos[i]>'9'){
*p = i+1; //P points to the first position after the error
arr->len = 0;
return ERR_INVAL; //The first one is not a number, it must be illegal
}else{
num = charToNum(pos[i]);
}

i++;
while(!isSpace(pos[i])&& pos[i] !=','){ //If it is not followed by a space or a comma, it indicates that it is a number or an error has occurred
if(isIntger(pos[i])){

num = num*10 + charToNum(pos[i]);
i++;
}else if(pos[i] ==']'){ //If the right bracket is used, it can be closed and a value can be returned
(arr->uptr)[k] = num;
arr->len = k+1;
*p = i+1;
return 0;
}else{
*p = i+1; //If it's not a number or a comma, it's an error. Point to the position after the error and return ERR_ INVAL
arr->len = 0;
return ERR_INVAL;
}
}
while(isSpace(pos[i])){
i++;
}
if(pos[i] ==','){ //If it's a comma, put it away
(arr->uptr)[k] = num;
k++;
i++;
}


}




}



long decode_i64_array(const GoString* src, long* p, GoIntSlice* arr){
char* pos = src->buf;
int i =0;

while(isSpace(pos[i])){
i++;
}
if(pos[i] != '['){
*p = i+1;
arr->len = 0;
return ERR_INVAL;
}
i++;
int k =0;
int num = 0;
char flag ='+'; //Define a flag to represent the symbol of a signed number
while(pos[i] !=0){
if(k==arr->cap){
*p = i+1;
return ERR_RECURSE_MAX;
}
while(isSpace(pos[i])){
liuq19 marked this conversation as resolved.
Show resolved Hide resolved
i++;
}
if((pos[i]<'0' || pos[i]>'9') && (pos[i]!='+' && pos[i]!='-' )){

*p = i+1;
arr->len = 0;
return ERR_INVAL; //The first one is neither a number nor a Plus�Cminus sign, so it must be illegal
}else if(pos[i]=='+' || pos[i]=='-'){
flag = pos[i]; //If it is a symbol, then the symbol is fixed, and the first digit immediately after it is also stored in num and i+1
i++;
num = charToNum(pos[i]);

}else{
num = charToNum(pos[i]);
}

i++;
while(!isSpace(pos[i])&& pos[i] !=','){
if(isIntger(pos[i])){

num = num*10 + charToNum(pos[i]);
i++;
}else if(pos[i] ==']'){
if(flag =='-'){
num = -(num);
}
(arr->iptr)[k] = num;
arr->len = k+1;
*p = i+1;
return 0;
}else{
*p = i+1;
arr->len = 0;
return ERR_INVAL;
}
}
while(isSpace(pos[i])){
i++;
}
if(pos[i] ==','){

if(flag =='-'){
num = -(num);
}
(arr->iptr)[k] = num;
k++;
i++;
}
flag = '+'; //Reset flag to positive sign

}
}




4 changes: 3 additions & 1 deletion native/native.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,6 @@
#include "atof_eisel_lemire.c"
#include "atof_native.c"
#include "scanning.c"
#include "f32toa.c"
#include "f32toa.c"
#include "goIntSlice.c"

52 changes: 52 additions & 0 deletions native/unittest/test_goIntSlice.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#include "../goIntSlice.c"

#include <stdio.h>
#include <malloc.h>
#include <stdbool.h>
#include <stdint.h>
#include <stddef.h>
#include <string.h>



int main(){
liuq19 marked this conversation as resolved.
Show resolved Hide resolved
// ��ʼ��GoIntSlice
GoIntSlice demo;
size_t cap = 4096;
//demo.uptr = (uint64_t*)malloc(cap * sizeof(uint64_t));
demo.iptr = (int64_t*)malloc(cap * sizeof(int64_t));
demo.len = 0;
demo.cap = cap;

// long* pp; // ������һ��Ұָ�룬����û�г�ʼ����
long p = 0;
long* pp = &p;
GoString test;
/*
Ŀǰ��������������У�
"{[1,2,3,4]" ��������
"[1,2,3.5,4]" ��������
"[1, 2,3, 4]" ��ȷ���������в�����ո�
"[ 1,2,3,4]" ��ȷ���������в�����ո�
"[1,2,3,4]" ��ȷ����
"[1,2,3]" ��ȷ����
"[1 ,2,3,4]" ��ȷ���������в�����ո�
*/


const char* str = "[1,-2,3,-4,5]"; // ʹ��C�����ַ���д�����Ӽ�࣬���ҽ�β�Զ�������'\0'
test.buf = str;
test.len = strlen(str);


long res = decode_i64_array(&test,pp,&demo);
//long res = decode_u64_array(&test,pp,&demo);

printf("%lld ,%lld\n",*pp,res);
for(int z=0;z<demo.len;z++){
printf("%d ",demo.iptr[z]);
}

// �������ͷ��ڴ�
free(demo.uptr);
}
76 changes: 76 additions & 0 deletions native/unittest/unittest_goIntSlice.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
#include <stdio.h>
#include <string.h>

#include "../goIntSlice.c"

void test_decode_i64_array(const char* test_str){
GoIntSlice demo;
size_t cap = 4096;
demo.iptr = (int64_t*)malloc(cap * sizeof(int64_t));
demo.len = 0;
demo.cap = cap;

long p = 0;
long* pp = &p;
GoString test;

const char* str = test_str;
test.buf = str;
test.len = strlen(str);

long res = decode_i64_array(&test,pp,&demo);

printf("%lld ,%lld\n",*pp,res);

for(int z=0;z<demo.len;z++){
printf(" %d ",demo.iptr[z]);

}

free(demo.iptr);


}

void test_decode_u64_array(const char* test_str){
GoIntSlice demo;
size_t cap = 4096;
demo.uptr = (uint64_t*)malloc(cap * sizeof(uint64_t));
demo.len = 0;
demo.cap = cap;

long p = 0;
long* pp = &p;
GoString test;

const char* str = test_str;
test.buf = str;
test.len = strlen(str);

long res = decode_u64_array(&test,pp,&demo);

printf("%lld ,%lld\n",*pp,res);

for(int z=0;z<demo.len;z++){
printf(" %d ",demo.uptr[z]);

}

free(demo.uptr);
}

int main(){


char teststr[10][100] = {"{[1,2,3,4]","[1,2,3.5,4]","[1, 2,3, 4]","[ 1,2,3,4]","[1,2,3,4]","[1,2,3]","[1 ,2,3,4]","[1,-2,-3,4]","[1,-2, -3, 4]","[1, -2.3, 4]"};

for(int i=0;i<10;i++){
test_decode_u64_array(teststr[i]);
printf("*");
test_decode_i64_array(teststr[i]);
printf("*");
}



}