PDA

Visualizza la versione completa : [C] - Problema con ciclo for


potenzio
03-05-2012, 17:47
Salve a tutti, ho realizzato un buffer per operazioni di I/O su di un file a livello di bit. Il buffer prevede le funzioni di apertura, chiusura, lettura e scrittura.
Per testare il buffer ho creato un main in cui riempio il buffer con valori tra 0 e 499 e poi li leggo. Il problema sta che quando eseguo la read sul buffer all'interno di un ciclo for il programma effettua la lettura ma non incrementa il contatore del for. Potreste aiutarmi sto letteralmente sbattendo la testa da 2 giorni.
Ecco il codice del main:


int main() {
BITFILE* WBUF=bitfile_open("/home/enzo/Scrivania/test_buffer.txt",MODE_WRITE);
for (int var = 0; var < 500; ++var)
{
bitfile_write(&WBUF,&var,9);
}
bitfile_close(WBUF);
BITFILE* RBUF=bitfile_open("/home/enzo/Scrivania/test_buffer.txt",MODE_READ);
int i;
int letti;
for(i=0;i<10;i++)
{
printf("i: %d\n",i);
int result=bitfile_read(&RBUF,&letti,9);
if(result!=-1)
printf("letti: %d\n",letti);
else
printf("err\n");
}
}


questo e' il codice del buffer:


int minimo(int a,int b)
{
return (a<=b)?a:b;
}

BITFILE* bitfile_open(char* filename,int mode)
{
int fd;
BITFILE* p;
if(mode!=0 && mode !=1)
{
errno=EINVAL;
return NULL;
}
fd=open(filename,(mode==0?O_RDONLY: ( O_WRONLY | O_CREAT )),0644);
if(fd<0)
{
return NULL;
}
p=calloc(1,sizeof(BITFILE));
if(p==NULL)
{
close(fd);
errno=ENOMEM;
return NULL;
}
p->FD=fd;
p->mode=mode;
p->POS=0;
return p;
}

int bitfile_read(BITFILE** _P,uint64_t* D,int LEN)
{
BITFILE* P=*_P;
if(P->mode!=MODE_READ)
{
printf("Lettura non consentita buffer aperto in modalita' scrittura");
return -1;
}
int LEN2=LEN;
int bit_letti=0;
int pos=P->POS;
uint64_t D1;
int bit_D=0;
if(P->LEN==BITBUF_SIZE_IN_BITS || P->POS==0 )
{
//printf("carico \n");
int temp=read(P->FD,P->BUF,BITBUF_SIZE);
if(temp<=0)
return -1;
P->LEN=0;
P->POS=8*temp;
pos=P->POS;
LEN2=minimo(LEN2,pos-P->LEN);
}
while (LEN>0)
{
LEN2=LEN;
if(pos-P->LEN<=0)
{
int temp=read(P->FD,P->BUF,BITBUF_SIZE);
if(temp<=0)
return -1;
P->LEN=0;
P->POS=8*temp;
pos=P->POS;
D1=*D;
bit_D=bit_letti;
LEN2=minimo(LEN2,pos-P->LEN);
}
int to_read=minimo(LEN2,pos-P->LEN);
int ultimo=P->LEN+to_read-1;
int OFS=ultimo/8; int sx_ofs=ultimo%8;
int dx_ofs=0;
if(sx_ofs+1<=to_read)
to_read=sx_ofs+1; // devo leggere + di quello che posso => leggo solo quello che posso
else
dx_ofs=sx_ofs-to_read+1; // devo leggere - di quello che posso => leggo solo quello che serve
uint8_t MASK=(1<<(sx_ofs+1))-1;
*D<<=to_read;
*D|=((P->BUF[OFS]&MASK)>>dx_ofs);
LEN-=to_read;
bit_letti+=to_read;
pos-=to_read;
}
if(bit_D>0)
{
uint64_t mask;
mask=(uint64_t)pow(2,bit_D)-1;
while(bit_D>31)
{
*D<<=31;
bit_D-=31;
}
*D<<=bit_D;
*D|=D1 & mask;
}
P->LEN+=bit_letti-bit_D;
*D&=(uint64_t)pow(2,bit_letti)-1;
*_P=P;
return bit_letti;
}

int bitfile_write(BITFILE** _P,uint64_t *SRC,int LEN)
{
BITFILE* P=*_P;
uint64_t D=*SRC;
if(P->mode!=MODE_WRITE)
{
printf("Scrittura non consentita buffer aperto in modalita' lettura");
return -1;
}
uint8_t mask=0;
int OFS,K,RES,LEN2;
int err;
LEN2=LEN;
while(LEN2>0)
{
OFS=P->POS/8;
K=P->POS%8;
RES=8-K;
if(LEN2<RES) //devo scrivere meno di quello che posso
RES=LEN2; //segnalo che devo scrivere solo LEN2
mask=(1<<RES)-1;
P->BUF[OFS]&=(1<<K)-1; //azzereo i bit da scrivere
P->BUF[OFS]|=(D & mask)<<K; //scrivo
LEN2-=RES;
P->POS+=RES;
D>>=RES;
if(P->POS >= BITBUF_SIZE_IN_BITS)
{
err=safe_write(P->FD,P->BUF,BITBUF_SIZE_IN_BITS);
P->POS=0;
}
}
*_P=P;
return LEN;
}

int bitfile_close(BITFILE* P)
{
int err=0;
if(P->mode==MODE_WRITE)
{
err=safe_write(P->FD,P->BUF,P->POS);
}
close(P->FD);
bzero(P,sizeof(BITFILE));
free(P);
return err;
}

int safe_write(int fd,uint8_t* buf,int pos)
{
if(pos>0)
{
int OFS=pos/8;
if (pos%8!=0)
{
int K=pos%8;
buf[OFS]&=(1<<K)-1;
OFS+=1;
}
int err=write(fd,buf,OFS);
return err;
}
else
return 0;
}

vi posto anche il punto h


#ifndef BITFILE_H_
#define BITFILE_H_
#include <stdint.h>

// dimensione del buffer in byte
#define BITBUF_SIZE 1
// dimensione del buffer in bit
#define BITBUF_SIZE_IN_BITS (BITBUF_SIZE * 8)
#define MODE_WRITE 1
#define MODE_READ 0

typedef struct
{
int POS ; // primo bit libero per scrivere
int LEN; // primo bit utilie per leggere
int mode; // 0 = READ; 1 = WRITE
int FD; // riferimento al file
uint8_t BUF[BITBUF_SIZE]; // buffer
}BITFILE;


BITFILE* bitfile_open(char* nome,int mode);
int bitfile_read(BITFILE** P,uint64_t* dst,int LEN);
int bitfile_write(BITFILE** P,uint64_t *D,int LEN);
int bitfile_close(BITFILE* P);
int safe_write(int fd,uint8_t* buf,int byte);
int minimo(int a,int b);

#endif


grazie mille!!

oregon
03-05-2012, 17:52
Intendi che in questa for



for(i=0;i<10;i++)
{
printf("i: %d\n",i);
int result=bitfile_read(&RBUF,&letti,9);
if(result!=-1)
printf("letti: %d\n",letti);
else
printf("err\n");
}


la variabile i non risulta incrementata?

potenzio
03-05-2012, 17:55
esatto quando stampo a video la variabile i questa rimane sempre allo stesso valore per quindi risulta un ciclo for infinito ma la cosa ancora piu' strana che termina automaticamente quando legge tutto il buffer fino a quando la variabile result non diventa -1.

oregon
03-05-2012, 19:36
Se scrivi

int result=1; //bitfile_read(&RBUF,&letti,9);

il ciclo si comporta regolarmente?

potenzio
03-05-2012, 20:03
si senza l'istruzione read il ciclo funziona regolarmente!

oregon
03-05-2012, 20:05
Quindi, quella funzione "sporca" lo stack in maniera tale che anche la memoria dove memorizzata la variabile i viene modificata tra una chiamata e l'altra.

Non ho ancora controllato il codice della bitfile_read ma l dentro il problema ...

potenzio
03-05-2012, 20:17
in che senso sporca lo stack???

oregon
03-05-2012, 20:19
Nel senso che viene scritto oltre la fine di un buffer dove il buffer non esiste ...

potenzio
03-05-2012, 22:35
ho controllato e nn mi sembra che ci siano di questi problemi!!

Loading