📄 sdc.c
字号:
{ if(bs_flag == SDS_SWAPPED_BYTES) rswabd(buffer,new->address,old->size*old->nelems); else memcpy(new->address,buffer,old->size*old->nelems); } break; case SDS_POINTER: printf("Problem in conversion: pointer found!\n"); break; case SDS_PADB: printf("Problem n conversion: pad byte found!\n"); break; default: if(bs_flag != SDS_SWAPPED_BYTES || old->elemcod == SDS_STRING || old->elemcod == SDS_FSTRING || old->elemcod == SDS_BYTE || old->elemcod == SDS_UNS_BYTE || old->elemcod == SDS_CHAR_BITFIELD || old->elemcod == SDS_LOGICAL_1) memcpy(new->address,buffer,old->size*old->nelems); else { if (new->size == 2) rswab(buffer,new->address,old->size*old->nelems); else if (new->size == 4) rswabw(buffer,new->address,old->size*old->nelems); else if (new->size == 8) rswabd(buffer,new->address,old->size*old->nelems); else { memcpy(new->address,buffer,old->size*old->nelems); printf("Problem n conversion: unknown type found!\n"); } break; } } } if (size) sds_push_error(SDS_FILE_RD,SDS_ERROR, "Reading for conversion:not enough bytes!"); return(ret_type);}/***********************************************************************/voidrswab(buffer,bto,number)int number;char *buffer, *bto;/***********************************************************************/{ int i; struct dshort *to = (struct dshort *)bto; struct dshort *from = (struct dshort *)buffer; char temp; for (i=0;i<number;i += 2,to++,from++) { temp = from->one; to->one = from->two; to->two = temp; }}/***********************************************************************/voidrswabw(buffer,bto,number)int number;char *buffer, *bto;/***********************************************************************/{ int i; struct dlong *from = (struct dlong *)buffer; struct dlong *to = (struct dlong *)bto; char temp; for (i=0;i<number;i += 4,to++,from++) { temp = from->four; to->four = from->one; to->one = temp; temp = from->two; to->two = from->three; to->three = temp; }}/***********************************************************************/voidrswabd(buffer,bto,number)int number;char *buffer, *bto;/***********************************************************************/{ int i; struct ddouble *from = (struct ddouble *)buffer; struct ddouble *to = (struct ddouble *)bto; char temp; for (i=0;i<number;i += 8,to++,from++) { temp = from->one; to->one = from->eight; to->eight = temp; temp = from->two; to->two = from->seven; to->seven = temp; temp = from->three; to->three = from->six; to->six = temp; temp = from->four; to->four = from->five; to->five = temp; }}/***********************************************************************/voidsds_fix_header(header,orig_state)struct sds_header *header;int orig_state;/***********************************************************************/{ char *cptr = (char *)header; if (orig_state == SDS_SWAPPED_BYTES) { rswabw(cptr,cptr,4); cptr += 4; if (*(cptr + 6) > (char)2) /* New version coding - 2 bytes */ rswab(cptr,cptr,4); else rswabw(cptr,cptr,4); cptr += 4; rswab(cptr,cptr,4); }}/***********************************************************************/voidsds_fix_tlist(header,tlist,orig_state)struct sds_header *header;struct type_list *tlist;int orig_state;/***********************************************************************/{ if (orig_state == SDS_SWAPPED_BYTES) rswabw((char *)tlist,(char *)tlist,(int)header->list_size);}/***********************************************************************/voidsds_fix_direc(struct direc *dptr,int number,int orig_state,int size)/***********************************************************************/{ int i; char *fromptr,*toptr,*start; int delta = size - sizeof(struct direc); int from_bigger = (delta > 0)?1:0; int testint = 1, goodbytes = 1; char *t = (char *)&testint; /* Find out if the I am big or little endian: goodbytes is true if I'm big endian. */ if (*t != 0) goodbytes = 0; fromptr = (char *)dptr; start = toptr = delta?calloc(number,size):fromptr; for (i=0;i<number;i++) { if (orig_state == SDS_SWAPPED_BYTES) { char *temp = fromptr; if (from_bigger) { rswabd(fromptr,fromptr,8); fromptr += 8; } else { rswabw(fromptr,fromptr,4); fromptr += 4; } rswabw(fromptr,fromptr,16); fromptr += 16; rswab(fromptr,fromptr,2); fromptr += 4; rswabw(fromptr,fromptr,4); fromptr = temp; } if (delta) { if (from_bigger) { memcpy(toptr, fromptr + goodbytes * 4, 4); memcpy(toptr + 4, fromptr + 8,sizeof(struct direc) - 4); } else { memcpy(toptr + goodbytes * 4, fromptr, 4); memcpy(toptr + 8, fromptr + 4,sizeof(struct direc) - 8); } } toptr += sizeof(struct direc); fromptr += size; } if (delta) { memcpy((char *)dptr,start,number * sizeof(struct direc)); free(start); }}/*********************************************************************/sds_handlesds_cload_direc(sds_handle sds, int fd,sds_handle *state ,struct sds_header *header)/*********************************************************************/{ struct direc *dtp; char *cptr; struct type_list *tl; struct sds_header *nhead; struct direc *dptr; int ndirecs,lhsize; char old_rbyte; char *temp_malloc; int arc; struct sds_control_p *scp; int incoming_direc_size = sizeof(struct direc); long l, total_direc_delta; long MoreInFile = 0, MoreInMemory = 0; if (fd < 0) { sds_push_error(SDS_FILE_NOP,SDS_ERROR, "File for conversion not open"); return 0L; }/* Read in the header ; */ if (sds_read(fd,BASE_OFFSET,(char *)header) != BASE_OFFSET) { sds_push_error(SDS_FILE_RD,SDS_ERROR, "Reading for conversion failed"); return 0L; } if (sds_header_ok(header)) { sds_push_error(SDS_GOOD_FORMAT,SDS_WARNING, "Conversion not necessary"); return 0; } *state = sds_last_warning(); if ((header->magic_number & 0xff00ffff) == SDS_MAGIC_BYTESWAP) *state = SDS_SWAPPED_BYTES; sds_fix_header(header,*state);/* Find out what sort of architecture : save this in the control block later */ arc = (int)((header->magic_number & 0x0000ff00) >> 8) - 1; if (arc > NARCS) { sds_push_error(SDS_FILE_RD,SDS_ERROR, "Unknown architecture received for conversion"); return 0L; } lhsize = (int)header->heap_size + (int)header->list_size + align_delta((sds_off_t)header->heap_size,4); lhsize += align_delta((sds_off_t)lhsize, sds_palign(SDS_DIRECTORY_STRUCTURE));/* If I'm not 8-byte addressing, but incoming data is, the direc stucture is bigger incoming than here, and vice versa. This is only true with version 3 and up...before that, I had a different version coding and had not implemented 8-byte addresses */ if (!SDS_BIGADDR && header->version > (short)2 && header->controlbits & SDS_FROM_BIGADDR) { incoming_direc_size += 4; MoreInFile = align_delta((sds_off_t)lhsize + BASE_OFFSET,8); } if (SDS_BIGADDR && ((header->version <= (short)2) || !(header->controlbits & SDS_FROM_BIGADDR))) { incoming_direc_size -= 4; MoreInMemory = align_delta((sds_off_t)lhsize + BASE_OFFSET,8); } temp_malloc = sds_malloc((unsigned)lhsize+ MoreInFile); old_rbyte = sds_arc_rbyte(arc); tl = (struct type_list *)temp_malloc; if (sds_read(fd,lhsize + MoreInFile,temp_malloc) != lhsize + MoreInFile) { sds_push_error(SDS_FILE_RD,SDS_ERROR, "Unexpected end-of-dataset"); sds_discard(sds); return 0; } sds_fix_tlist(header,tl,*state);/* Find size of directory */ dtp = (struct direc *)sds_malloc(incoming_direc_size); if (sds_read(fd,incoming_direc_size,(char *)dtp) != incoming_direc_size) { sds_push_error(SDS_FILE_RD,SDS_ERROR, "Unexpected end-of-dataset"); sds_discard(sds); return 0; } sds_fix_direc(dtp,1,*state,incoming_direc_size); ndirecs = (int)dtp->nelems;/* Just in case I'm loading from a different directory structure size */ dtp->align_type = sds_palign(SDS_DIRECTORY_STRUCTURE); dtp->elemsz = sds_psize(SDS_DIRECTORY_STRUCTURE);/* New directory,tlist heap and header go here */ cptr = sds_malloc((unsigned int)(ndirecs*sizeof(struct direc)) + (unsigned int)BASE_OFFSET + (unsigned int)lhsize );/* Copy in header..... */ memcpy(cptr,(char *)header,BASE_OFFSET); nhead = (struct sds_header *)cptr; cptr += BASE_OFFSET;/* Copy in tlist and heap */ memcpy(cptr,tl,lhsize); free(temp_malloc); cptr += lhsize + MoreInMemory;/* Copy in top directory..... */ memcpy(cptr,(char *)dtp,sizeof(struct direc)); free((char *)dtp); dptr = (struct direc *)cptr; cptr += sizeof(struct direc); temp_malloc = sds_malloc((ndirecs-1) * incoming_direc_size);/* Read in rest of directory..... */ if (sds_read(fd,incoming_direc_size*(ndirecs-1),temp_malloc) != incoming_direc_size*(ndirecs-1)) { sds_push_error(SDS_FILE_RD,SDS_ERROR, "Unexpected end-of-dataset"); sds_discard(sds); return 0; } sds_fix_direc((struct direc *)temp_malloc,ndirecs-1,*state,incoming_direc_size); memcpy(cptr,temp_malloc,sizeof(struct direc)*(ndirecs-1)); free(temp_malloc);/* Now, I've resized the direc structures to be locally OK - if there are any offst values greater than 32 bits something is drastically cock-eyed. However the internal offsets of other direcs, are wrong */ dptr[0].offst = (sds_off_t )dptr - (sds_off_t)nhead; total_direc_delta = (incoming_direc_size - sizeof(struct direc)) * dptr[0].nelems; for (l=1;l<dptr[0].nelems;l++) dptr[l].offst -= total_direc_delta; scp = sds_control(sds); set_sys_vars(sds,dptr); scp->allofl |= SDS_HEAD_ALLOC; scp->genarc = arc; return(sds);}/*********************************************************************/sds_handlesds_lofd(sds_handle sds,int fd, unsigned long nbytes, struct sds_header *header )/*********************************************************************//* Here I have loaded the header - but I cannot assume a seekable device; so I will read in what remains from the fd (nbytes is the COMPLETE size, including the header) and copy the header info. The name of the game is minimise your system calls. If size is 0, however, it mean I have to work out the size. */{ char *sdptr, *sdp; /* Points to beginning of allocated memory */ struct sds_header *sdsh; /* ...so does this */ struct direc *dptr; sds_handle obj; struct sds_control_p *scp; long already_read,del; long remains; sds_off_t lhsize; scp = sds_control(sds); lhsize = BASE_OFFSET + (sds_off_t)header->list_size + (sds_off_t)header->heap_size; lhsize += align_delta(lhsize,sds_palign(SDS_DIRECTORY_STRUCTURE)); if (!nbytes) { remains = lhsize + sizeof(struct direc) - BASE_OFFSET; sdptr = sds_malloc(lhsize + sizeof(struct direc)); } else { remains = nbytes - BASE_OFFSET; sdptr = sds_malloc(nbytes); } sdp = sdptr + BASE_OFFSET; if (sds_read(fd,remains,sdp) != remains) { free(sdptr); return 0L; } memcpy(sdptr, (char *)header, BASE_OFFSET); sdsh = (struct sds_header*)sdptr; dptr = (struct direc *)(sdptr + lhsize); if (!nbytes) { already_read = lhsize + sizeof(struct direc); remains = (dptr[0].nelems-1) * sizeof(struct direc); sdptr = sds_realloc(sdptr,already_read + remains); dptr = (struct direc *)(sdptr + lhsize); sdp = sdptr + already_read; /* Do this now to get trailing pads, if they exist, in del */ already_read += ((dptr[0].nelems-1) * sizeof(struct direc)); del = align_delta((sds_off_t)already_read, sds_palign(dptr[1].align_type)); remains += del; already_read += del; if (sds_read(fd,remains,sdp) != remains) { free(sdptr); return 0L; } nbytes = sds_sz(dptr); sdptr = sds_realloc(sdptr,nbytes); dptr = (struct direc *)(sdptr + lhsize); sdp = sdptr + already_read; sds_read(fd,nbytes - already_read,sdp); } set_sys_vars(sds,dptr); scp->source = SDS_FILE; for (obj = 0;obj < dptr[0].nelems; obj++) /* This is gross. Must get illoca sorted properly. Just 0R'ing it takes out DISJOINT_OBJETC dptr[obj].illoca = 0; */ dptr[obj].illoca &= ~(SDS_WAS_ALLOCATED | SDS_EXTERNAL_OBJECT | SDS_REALLOC); return(sds);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -