-
Notifications
You must be signed in to change notification settings - Fork 32
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
Objetos String_t #7
Comments
Muy bueno!! Una duda, los tipos de datos vamos a diferneciar entre tipos con minúscula y con mayúscula? Porque todos los declarados hasta ahora empiezan con minúscuala pero esto tiene mucha más pinta de Clase que de tipo como float32_y o bool_t. Quizá difernciándolos con las mayúsculas pordíamos indicarle al usuario que estos se usan ligados a sus métodos y no se asignan directammente como los demás. De esta manera tipso como delay_t pasarían a ser Delay_t por ejemplo. En cuanto a tus preguntas:
¿String como un caso particular de un Stream genérico o como una cosa aparte? |
@epernia 👍 En mi opinión:
En cuanto a delay_t, si es un derivado de tipo basico, yo lo dejaria como delay_t. Si tiene algun mecanismo subyacente lo haría Delay_t pero solo si requiere el uso como clase. Los string sin nullpointer pueden ser strings o substrings indistintamente. Por ejemplo: String_t s1 = StringNew("for I=1 to 10 step 2");
int token_count = StringSplit(s1, ' ', NULL, 0);
String_t tokens[token_count];
StringSplit(s1, ' ', tokens, ARRAY_LEN(tokens)); Es facil si usamos Como vez, esa es la forma de tener substrings sin malloc. Basicamente, siempre estas haciendo referencia al mismo objeto, por lo tanto, tiene que haber alguna forma de hacer un string copy: String_t s1, s2:
s1 = StringNew("Hola mundo");
StringBuffer_t buffer[StringLen(s1)];
s2 = StringCopy(s1, buffer); |
Entonces vamos con strings sin NULL si facilita las cosas. Hay un tema que no me queda claro que es ¿Dónde pondríamos el vector con el string, dentro de la estructura o aparte?, lo tiene que crear el New o el Copy seguramente, allí se puede saber el largo en tiempo de compilación pero si luego queremos concatenar estamos fritos así que supongo que serán todos de un largo fijo, supongamos 256 caracteres, o ¿cómo lo pensaste esto? |
Los punteros del string apuntan a donde empieza y termina el string (posiblemente un tercer puntero para tomar el maximo del tail) Esto es: typedef struct {
const char *head;
const char *tail;
const char *top;
} String_t;
String_t StringNewFromC(const char *cstr) {
String_t v;
v.head = cstr;
v.tail = v.head + strlen(cstr);
v.top = v.tail;
return v;
}
String_t _StringNew(const char *ptr, size_t size) {
String_t v;
v.head = v.tail = ptr;
v.top = ptr + size;
return v;
}
#define StringNew(buf) _StringNew(buf, sizeof(buf)) En el caso de una concatenación, tenemos varias alternativas. Manejarlo de forma directa pasandole el buffer String_t s1, s2, s3;
s1 = StringNew("Hola ");
s2 = StringNew("Mundo");
char buffer[StringLen(s1) + StringLen(s2)];
s3 = StringConcat(s1, s2, buffer); O tener un memory pool seleccionable o por defecto: s3 = StringConcat(s1, s2, mpool); Voy a seguir pensando alternativas, estaria bueno que alguien mas aporte |
Métodos de mínima que creo que deberíamos soportar para string:
En caso de error en estos métodos habría que pensar una forma de marcarlo, quizá que devuelvan un NULL_STRING cuyos índices sean cosas sin sentido, o que todas devuelvan bool y el resultado lo ecriban en un string que les llega por referencia (me inclino por opcion 1). |
Teniendo en cuenta todo lo comentado, me inclino por esta estructura: typedef struct {
char *start;
char *stop;
size_t capacity;
} String_t; Agrego algunos prototipos mas: String_t stringNewFromPool(size_t capacity, Pool_t memoryPool/memoryHeap); //!< Crea un nuevo string pidiendo memoria a un pool
String_t stringNewFromHeap(size_t capacity, Heap_t memoryPool/memoryHeap); //!< Crea un nuevo string pidiendo memoria a un heap
const String_t stringNewFromCStr(const char *str); //!< Crea un nuevo string desde un C string. Notar que se retorna <const String_t>
String_t stringNewFromArray(char *ptr, size_t len); //!< Crea un nuevo string desde un buffer
String_t stringCopy(String_t to, const String_t from); //!< Copia `from` en `to` y devuelve `to`
bool stringIsEqual(const String_t a, const String_t b); //!< Retorna `true` si `a == b`
bool stringIsEqualNotCase(const String_t a, const String_t b); //!< Retorna `true` si `a == b` case insensitive
int stringDiff(const String_t a, const String_t b); //!< Retorna 0 si `a==b` o la diferencia del primer caracter distinto (util para implementar ordanamiento) Aparte, en tus declaraciones falta distinguir entre |
El codigo que charlamos por chat: #define DECL_STRING(name, value) DECL_STRING(a, "Hola mundo"); |
La biblioteca para usar como base: |
Abro este ISSUE como mejora para discutir la creación de un api String_t en C
Criterios de diseño
<string.h>
(requiere test para corroborar esto)Ideas
Head/Tail
The text was updated successfully, but these errors were encountered: