Variable de tamaño dinámico?

Iniciado por huchoko, 5 Julio 2019, 05:24 AM

0 Miembros y 1 Visitante están viendo este tema.

huchoko

int fat32_open_file(uint8_t* filename, uint8_t* buff)
{
if (!hd_exists() && !filename)
return 1;
hd_read(start_of_root, FAT32_FILES_PER_DIRECTORY * sizeof(struct DirectoryEntry), (uint8_t*)&drce[0]);

for (int i = 0; i < FAT32_FILES_PER_DIRECTORY; ++i) {
if (drce[i].file_name[0] == FAT32_NO_FILES)
break;
uint8_t* fatbuff = 0;
uint8_t fil[12];
fat2human(drce[i].file_name, fil);
trimName(fil, 11);
if (strcmp((char*)fil, (char*)filename) == 0) {
uint8_t fcluster = ((uint32_t)drce[i].cluster_number_hi) << 16 | ((uint32_t)drce[i].cluster_number_lo);   
int32_t ncluster = fcluster;
int32_t file_size = drce[i].file_size;

kputs("\nFile content: \n");

/* 1 sector file (less than 512 bytes) */
if (file_size < 512) {
hd_read(fcluster, 512, buff);
buff[file_size] = '\0';
//kputs("%s", (char*)buff);
}

while (file_size > 0) {
uint32_t fsect = start_of_data + bpb.sectors_per_cluster * (ncluster - 2);
uint32_t sector_offset = 0;
for (; file_size > 0; file_size -= 512) {
hd_read(fsect + sector_offset, 512, buff);
buff[file_size > 512 ? 512 : file_size] = '\0';
//kputs("%s", (char*)buff);
if (++sector_offset > bpb.sectors_per_cluster)
break;
}
uint32_t fsectcurrentcl = ncluster / (512 / sizeof(uint32_t));

hd_read(fat_start + fsectcurrentcl, 512, fatbuff);
uint32_t foffsectcurrentcl = ncluster % (512 / sizeof (uint32_t));
ncluster = ((uint32_t*)&fatbuff)[foffsectcurrentcl] & 0x0FFFFFFF;
}
return 0;
}
}
kputs("\nFile %s not found\n", filename);
return 1;
}

Funciona, pero hay un problema. Debo darle un tamaño al buffer:

uint8_t fileb[1024];
fat32_open_file(buff, fileb);

La cosa es que no se puede saber el tamaño del buffer pasado por la función, puede ser de 512, 2048, etc.
Hay una forma de hacer que fileb sea dinámico?

MAFUS

Entiendo que trabajas a nivel kernel por lo que deberías usar lo que te explican aquí:
https://stackoverflow.com/questions/2888421/malloc-in-kernel

Eternal Idol

Cita de: huchoko en  5 Julio 2019, 05:24 AM
Funciona, pero hay un problema. Debo darle un tamaño al buffer:

¿No sera demasiado copy/paste? Cada vez que usa buff es solo para  leer el tamaño de un sector de 512 bytes. fatbuff es un puntero nulo asi que asumiendo que no haya otros errores esto solo puede funcionar con archivos de menos de 512 bytes.
La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón

huchoko

#3
Cita de: Eternal Idol en  5 Julio 2019, 21:31 PM
¿No sera demasiado copy/paste? Cada vez que usa buff es solo para  leer el tamaño de un sector de 512 bytes. fatbuff es un puntero nulo asi que asumiendo que no haya otros errores esto solo puede funcionar con archivos de menos de 512 bytes.
Ya sabía que solo se iba a leer 512 bytes (y ya lo he arreglado). Lo que aún no logro hacer funcionar es lo que comento en el título del hilo. Tal como me respondió MAFUS con un malloc es fácil, pero podría ser que el archivo:
a) Sea más grande de lo que hemos reservado en memoria para el buffer
b) Sea más pequeño de lo que hemos reservado, gastando memoria (solucionable con realloc?)

Eternal Idol

#4
Cita de: huchoko en  6 Julio 2019, 03:56 AM
Ya sabía que solo se iba a leer 512 bytes (y ya lo he arreglado). Lo que aún no logro hacer funcionar es lo que comento en el título del hilo. Tal como me respondió MAFUS con un malloc es fácil, pero podría ser que el archivo:
a) Sea más grande de lo que hemos reservado en memoria para el buffer
b) Sea más pequeño de lo que hemos reservado, gastando memoria (solucionable con realloc?)

El problema que planteas ahora es muy facil de solucionar, la memoria la reserva fat32_open_file (doble puntero, referencia, valor de retorno, etc.) o de alguna manera le pasa al llamador el tamaño del archivo (idem) PERO falla el diseño por todas partes. Una funcion que se llama open no deberia estar leyendo un archivo, ni deberias reservar memoria para todo el archivo asi como asi (podria ocupar varios GB por ejemplo). Ni deberias tratar de terminar un buffer con un 0 terminador como si fuera una cadena ... y si esa parte si es una prueba o un codigo que no sera de produccion mejor abstraenos del mismo, solo consigue confundirnos y hacernos perder el tiempo mientras tratamos de ayudarte.

¿Como funciona un S.O. de verdad? Devuelve una referencia, un HANDLE, para hacer esto bien deberias asociar el archivo a una estructura donde tuvieras la informacion necesaria para poder leer (y escribir, retroceder o avanzar dentro del archivo, retornar el tamaño del mismo, etc.) y otra funcion de lectura separada, posteriormente el llamador y (no el S.O.) decide cuanto y como leer.

PD. Si todavia no conseguiste depurar tu codigo ya es imperativo que lo logres, por ejemplo me equivoque antes, el codigo tiene tantos errores que me perdi, fatbuff se intentara usar siempre que encuentre el archivo asi que esto no funciona bien jamas y es algo que podrias ver al depurarlo.
La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón