📄 sds_assem.c
字号:
off_t cur = lseek(scp->tstream, 0L, SEEK_CUR); int pads = align_delta((sds_off_t)cur ,ddptr[(int)object].align_type); padbytes[0] = padbytes[1] = 0L; if (pads && sds_buffered(scp->tstream, (char *)padbytes, pads, b,s,&c) != pads) { sds_push_error(SDS_FILE_WR, SDS_ERROR, "Adding data object to file"); return 0L; } if (!sds_write_object(scp->tstream,sds,object,obj_ptr,b,s,&c)) { sds_push_error(SDS_FILE_WR,SDS_ERROR, "Adding data object to file"); return 0L; } sds_flush(scp->tstream, b,&c); }/* And return its object number */ return(object);}/*********************************************************************/char **sds_saverestore(sds,dptr, flag)sds_handle sds;struct direc *dptr;int flag;/*********************************************************************/{ int i; long junk = 0; struct sds_saverestore *sr = sds_saver();/* I'm going to put the real object addresses in this pointer list */ if (flag == SDS_SAVE_STATE) { sr->opointer = (char **)sds_malloc((unsigned int)dptr[0].nelems * (unsigned int)sizeof(char *)); if (sr->opointer == 0 ) { sds_push_error(SDS_NO_MEM, SDS_ERROR,"calloc failure, sds_make"); return (char **)0; } /* Get the addresses from the approved routine ... */ /* Save the directory state in case it's NOT_ASSEMBLED */ sr->sds_state = (char *)dptr[0].offst; for (i=0;i < dptr[0].nelems;i++) sr->opointer[i] = (char*) sds_getp(dptr,i); if (sr->sds_state == (char *)SDS_NOT_ASSEMBLED) sr->status = offil(sds, 0, 0, &junk); return sr->opointer; } else {/* leave things as before in case dataset expansion is required */ if (sr->sds_state == (char *)SDS_NOT_ASSEMBLED) { dptr[0].offst = (sds_off_t)sr->sds_state; for (i=1;i < dptr[0].nelems;i++) dptr[i].offst = (sds_off_t)sr->opointer[i]; } free((char *)sr->opointer); return NULL; }}/*********************************************************************/sds_handlesds_ass(sds,name,flg)sds_handle sds;sds_code flg;char *name;/* 'assemble' means assemble the bits of an SDS into a coherent thing. That means the target place for assembly must be specified. In the simplest case - assemble in process memory - the only action will be to allocate memory for any objects which don't yet have any - no new SDS is created. For assembly to *shared memory* a contiguous memory chunk has to be filled, so a new SDS is made. Assembling to file or streaming to a network do generate a new SDS but it is NOT accessible to the generating process without more work (eg sds_load) so no new SDS index is returned*//*********************************************************************/{ struct direc *dptr; char *cptr; sds_handle sds_return = sds; unsigned long i; int tw,ow,fd; char **object_pointer; struct sds_control_p *scp; long padbytes[2]; char b[4096]; int c = 0,s = 4096; #ifdef SHMEM sds_handle cp_size; sds_off_t new_base,new_offset; struct direc *new_dptr;#endif padbytes[0] = padbytes[1] = 0L; if (!(scp = sds_control(sds))) { sds_push_error(SDS_NO_SUCH_SDS,SDS_ERROR,"Assembling non-existant dataset"); return 0L; } dptr = sds_direc(sds); if ((scp->target_name)) { char buf[1024]; char *ch; int nb,pads; char *tname = sds_malloc(strlen(scp->target_name) + 5); if ((ch = strrchr(scp->target_name,'.')) != (char *)0) *ch = (char)0; strcpy(tname,scp->target_name); strcat(tname,".tmp"); if (scp->tstream != SDS_FILE_OP) sds_close_fd(scp->tstream); if ((scp->tstream = sds_open_file(scp->target_name, O_RDONLY)) == -1) { sds_push_error(SDS_FILE_OP,SDS_ERROR, "Could not open data file"); sds_return = 0L; } else if ((fd = sds_open_file(tname,O_RDWR)) >= 0) { object_pointer = sds_saverestore(sds,dptr,SDS_SAVE_STATE); if ((tw = sds_write_header(fd,sds,b,s,&c)) < 0) { sds_push_error(SDS_FILE_WR,SDS_ERROR,"Failure writing header to file"); sds_return = 0L; } else if ((pads = sds_prepads(&dptr[0], tw)) > 0) { if (sds_buffered(fd, (char *)padbytes, pads,b,s,&c) != pads) { sds_push_error(SDS_FILE_WR,SDS_ERROR,"Failure writing pads to file"); sds_return = 0L; } else tw += pads; } if ((ow = sds_write_object(fd,sds,0,(char *)scp->dptr,b,s,&c)) < 0) { sds_push_error(SDS_FILE_WR,SDS_ERROR, "Failure writing directory to file"); sds_return = 0L; } tw += ow; if (lseek(scp->tstream,0,SEEK_SET) == -1) { sds_push_error(SDS_FILE_OP,SDS_ERROR,"lseek on data target"); sds_return = 0L; } else { while((nb = read(scp->tstream, buf, 1024)) > 0) sds_buffered(fd,buf, nb,b,s,&c); if (nb == -1) { sds_push_error(SDS_FILE_RD,SDS_ERROR,"read on data target"); sds_return = 0L; } sds_flush(scp->tstream,b,&c); sds_close_fd(scp->tstream); scp->tstream = (int)NULL; } sds_close_fd(fd); } else { sds_push_error(SDS_FILE_OP,SDS_ERROR, "Could not open file"); sds_return = 0L; } if (sds_return) {#if defined(__MSDOS__) unlink(scp->target_name);#endif rename(tname,scp->target_name); } free(tname); sds_saverestore(sds,dptr,SDS_RESTORE_STATE); } else if ((flg & SDS_FILE)) /* no new sds created */ { object_pointer = sds_saverestore(sds,dptr,SDS_SAVE_STATE); if ((fd = sds_open_file(name,(int)flg)) >= 0) { if (!to_file(sds,fd,object_pointer)) { sds_push_error(SDS_FILE_WR,SDS_ERROR, "Failure writing dataset to file"); sds_return = 0L; } sds_close_fd(fd); } else { sds_push_error(SDS_FILE_OP,SDS_ERROR, "Could not open file"); sds_return = 0L; } sds_saverestore(sds,dptr,SDS_RESTORE_STATE); } else if (flg & SDS_SYBASE) /* no new sds created */ {#ifndef SDSDB sds_push_error(SDS_FILE_OP,SDS_ERROR,"Database operations not supported:"); return 0L;#else object_pointer = sds_saverestore(sds,dptr,SDS_SAVE_STATE); sds_return = sds_db_make(sds,name,name,flg,object_pointer); sds_saverestore(sds,dptr,SDS_RESTORE_STATE);#endif }#ifdef SHMEM else if (flg & SDS_SHARED_MEM) /* a new sds is created */ { if ((sds_return = next_sds()) >= 0) { object_pointer = sds_saverestore(sds,dptr,SDS_SAVE_STATE);/* Allocate the memory */ if ((cptr = (char *)shm_make(name, sds_fullsize(sds),0666)) == (char *)0) { sds_push_error(SDS_NO_MEM,SDS_ERROR, "Shared memory failure"); return 0L; }/* Make and load the sds header,tlist and heap */ cptr += sds_mem_header(sds,cptr); cptr += align_delta((sds_off_t)cptr,dptr[0].align_type);/* How big is the directory? */ cp_size = (sds_handle)dptr[0].nelems*dptr[0].elemsz;/* Copy the directory over */ memcpy(cptr,(char *)dptr,cp_size); new_dptr = (struct direc *)cptr; new_base = (sds_off_t)cptr; set_sys_vars(sds_return,(struct direc *)cptr); cptr += cp_size;/* And all the objects */ for (i=1;i < dptr[0].nelems;i++) { new_dptr[i].illoca = SDS_EXTERNAL_OBJECT; cptr += align_delta((sds_off_t)cptr,dptr[i].align_type); new_offset = new_dptr[0].offst + (sds_off_t)cptr - new_base; if (new_offset != new_dptr[i].offst ) new_dptr[i].offst = (sds_off_t)new_offset; cp_size = (sds_handle)dptr[i].nelems; if (dptr[i].illoca & SDS_REALLOC) if (scp->dup_size[i] < dptr[i].nelems) cp_size = scp->dup_size[i]; cp_size *= dptr[i].elemsz; if (new_dptr[i].structype & SDS_RECORDS) { cptr += sds_copy_records(sds_return,cptr, (sds_record_handle *)object_pointer[i]); new_dptr[i].structype &= ~SDS_RECORDS; } else { if (object_pointer[i] != SDS_ALLOCATE) memcpy(cptr, object_pointer[i], cp_size); cptr += (int)dptr[i].nelems*dptr[i].elemsz; } } sds_saverestore(sds,dptr,SDS_RESTORE_STATE); } }#endif else if (flg & SDS_PROC_MEM) /* Just do necessary memory allocation */ { for (i=1;i < dptr[0].nelems;i++) { if ((dptr[i].offst == (sds_code)SDS_ALLOCATE)) { dptr[i].offst = (sds_off_t)sds_calloc(dptr[i].nelems,dptr[i].elemsz); dptr[i].illoca |= SDS_WAS_ALLOCATED; } else if (dptr[i].illoca & SDS_REALLOC) { /* Can't: have to copy over? if (dptr[i].illoca & SDS_WAS_ALLOCATED) free((char *)dptr[i].offst; */ dptr[i].offst = (sds_off_t)sds_calloc(dptr[i].nelems,dptr[i].elemsz); dptr[i].illoca |= SDS_WAS_ALLOCATED; dptr[i].illoca &= ~SDS_REALLOC; } else { dptr[i].illoca |= SDS_EXTERNAL_OBJECT; } } scp->is_proto = 0; } else /* this is an unknown target */ { sds_return = 0L; sds_push_error(SDS_TRANSFER_UNDEF,SDS_WARNING, "Do not understand this assembly target"); } return sds_return;}/*********************************************************************/sds_handleto_file(sds,fd,object_pointer)sds_handle sds;int fd;char **object_pointer;/*********************************************************************/{ struct direc *dptr; unsigned long i; sds_handle total_write = 0; sds_handle pads, ob_write; long padbytes[2]; char b[4096]; int c= 0,s= 4096; padbytes[0] = padbytes[1] = 0L; if ((dptr = sds_direc(sds)) == DNULL) { sds_push_error(SDS_NO_SUCH_SDS,SDS_ERROR,"Writing non-existant dataset to file"); return 0L; } if ((total_write = sds_write_header(fd,sds,b,s,&c)) < 0) { sds_push_error(SDS_FILE_WR,SDS_ERROR,"Writing header failed"); return 0L; } for (i=0;i < dptr[0].nelems;i++) { if (dptr[i].illoca != SDS_DISJOINT_OBJECT) { if ((pads = sds_prepads(&dptr[i], total_write)) > 0) { if (sds_buffered(fd, (char *)padbytes, pads,b,s,&c) != pads) { sds_push_error(SDS_FILE_WR,SDS_ERROR,"Writing pads failed"); return 0L; } else total_write += pads; } if ((ob_write = sds_write_object(fd,sds,i,object_pointer[i],b,s,&c)) < 0) { sds_push_error(SDS_FILE_WR,SDS_ERROR,"Writing object"); return 0L; } else total_write += ob_write; } } sds_flush(fd,b,&c); return 1L;;}/*********************************************************************/sds_handlesds_prepads(dptr, total_write)struct direc *dptr;sds_handle total_write;/*********************************************************************/{ return (sds_handle)align_delta((sds_off_t)total_write,dptr->align_type); }/*********************************************************************/sds_handlesds_mem_header(sds,cptr)sds_handle sds;char *cptr;/*********************************************************************/{ struct sds_header *sdsh = (struct sds_header *)cptr; sdsh->magic_number = (long)SDS_MAGIC; sdsh->version = SDS_VERSION; sdsh->controlbits |= SDS_BIGADDR?SDS_FROM_BIGADDR:0; sdsh->list_size = (short)tlist_size(sds_tlist(sds)); sdsh->heap_size = (short)sds_heap_size(sds); sdsh->heap_size += (short)align_delta((sds_off_t)sdsh->heap_size,4); cptr += sizeof(struct sds_header); if (sdsh->list_size) /* there is a tlist */ { memcpy(cptr,(char *)sds_tlist(sds),(int)sdsh->list_size); cptr += sdsh->list_size; } memcpy(cptr,sds_heap(sds),(int)sdsh->heap_size); return((int)sdsh->list_size +(int)sdsh->heap_size + sizeof(struct sds_header));}/*********************************************************************/sds_handlesds_write_header(int fd,sds_handle sds,char *b, int s, int *c)/*********************************************************************/{ struct sds_header sdsh; int ret_size = 0L; sdsh.magic_number = (long)SDS_MAGIC; sdsh.version = SDS_VERSION; sdsh.controlbits = SDS_BIGADDR?SDS_FROM_BIGADDR:0; sdsh.list_size = (short)tlist_size(sds_tlist(sds)); sdsh.heap_size = (short)sds_heap_size(sds); ret_size += sds_buffered(fd,(char *)&sdsh,sizeof(struct sds_header),b,s,c); if (sdsh.list_size) ret_size += sds_buffered(fd,(char *)sds_tlist(sds),(int)sdsh.list_size,b,s,c); ret_size += sds_buffered(fd,sds_heap(sds),(int)sdsh.heap_size,b,s,c); return ret_size;}/*********************************************************************/sds_handlesds_write_object(int fd,sds_handle sds,sds_code i,void *pointer, char *b,int s, int *c)/*********************************************************************/{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -