void set_tcp(JNIEnv *env,jobject packet,char *pointer,jbyteArray data,struct ip *ip) { struct tcphdr *tcp=(struct tcphdr *)(pointer); jint length=(*env)->GetArrayLength(env,data); tcp->th_sport=htons((jshort)GetIntField(TCPPacket,packet,"src_port")); tcp->th_dport=htons((jshort)GetIntField(TCPPacket,packet,"dst_port")); tcp->th_seq=htonl((unsigned long)GetLongField(TCPPacket,packet,"sequence")); tcp->th_ack=htonl((unsigned long)GetLongField(TCPPacket,packet,"ack_num")); tcp->th_off=5; // updated by Damien Daspit 5/7/01 tcp->th_flags=(GetBooleanField(TCPPacket,packet,"rsv1")<<7)+ (GetBooleanField(TCPPacket,packet,"rsv2")<<6)+ (GetBooleanField(TCPPacket,packet,"urg")<<5)+ (GetBooleanField(TCPPacket,packet,"ack")<<4)+ (GetBooleanField(TCPPacket,packet,"psh")<<3)+ (GetBooleanField(TCPPacket,packet,"rst")<<2)+ (GetBooleanField(TCPPacket,packet,"syn")<<1)+ (GetBooleanField(TCPPacket,packet,"fin")); // ******************************* tcp->th_win=htons((jshort)GetIntField(TCPPacket,packet,"window")); tcp->th_urp=htons(GetShortField(TCPPacket,packet,"urgent_pointer")); if(length+IPv4HDRLEN+TCPHDRLEN>MAX_PACKET_SIZE) length=MAX_PACKET_SIZE-IPv4HDRLEN-TCPHDRLEN; // updated by Damien Daspit 5/15/01 (*env)->GetByteArrayRegion(env,data,0, length, (u_char *)(pointer+TCPHDRLEN)); tcp->th_sum=0; tcp->th_sum=in_cksum2(ip,htons((u_short)length+TCPHDRLEN),(u_short *)tcp,length+TCPHDRLEN); }
/* * Class: sage_SFIRTuner * Method: closeDevice * Signature: ()V */ JNIEXPORT void JNICALL Java_sage_SFIRTuner_closeDevice(JNIEnv *env, jobject jo) { HINSTANCE hDriver = (HINSTANCE) GetLongField(env, jo, "nativeDllHandle"); LPFNTakedown fnTakedown = (LPFNTakedown)dlsym(hDriver, "CloseDevice"); if (fnTakedown) #if defined(__APPLE__) fnTakedown(); #else fnTakedown((int)GetLongField(env, jo, "nativePort")); #endif }
/* * Class: sage_SFIRTuner * Method: findBitRate * Signature: ()J */ JNIEXPORT jlong JNICALL Java_sage_SFIRTuner_findBitRate(JNIEnv *env, jobject jo) { HINSTANCE hDriver = (HINSTANCE) GetLongField(env, jo, "nativeDllHandle"); LPFNBit_Time fnGetBitrate = (LPFNBit_Time)dlsym(hDriver, "FindBitRate"); if (fnGetBitrate) #if defined(__APPLE__) return fnGetBitrate(); #else return fnGetBitrate((int)GetLongField(env, jo, "nativePort")); #endif else return 0;
/* * Class: com_sun_media_protocol_sunvideo_XILCapture * Method: xilSetQuality * Signature: (I)Z */ JNIEXPORT jboolean JNICALL Java_com_sun_media_protocol_sunvideo_XILCapture_xilSetQuality(JNIEnv *env, jobject jxil, jint jquality) { int quality = (int)jquality; InstanceState *inst = (InstanceState *) GetLongField(env, jxil, "peer"); if (inst == NULL) return FALSE; /* Debug Message*/ PRINT("In xilSetQuality\n"); if (quality < 1) quality = 50; /* force to default quality */ if (quality > 100) quality = 100; /* limit to maximum quality */ if (quality == inst->quality) return TRUE; /* if no change, return */ inst->quality = quality; if (inst->started && inst->xil_cis != NULL) { xil_cis_set_attribute(inst->xil_cis, "COMPRESSION_QUALITY", (void *)inst->quality); } setFormat(env, jxil, inst); return TRUE; }
/* * Class: com_sun_media_protocol_sunvideo_XILCapture * Method: xilSetPort * Signature: (I)Z */ JNIEXPORT jboolean JNICALL Java_com_sun_media_protocol_sunvideo_XILCapture_xilSetPort(JNIEnv *env, jobject jxil, jint port) { int res; InstanceState * inst = (InstanceState *) GetLongField(env, jxil, "peer"); if (inst == NULL) return TRUE; /* Debug Message*/ PRINT("In xilSetPort\n"); if ((int)port == inst->port && inst->signal != UNKNOWN_SIGNAL) return TRUE; inst->port = (int)port; res = tryPort(env, jxil, inst); if (res) { setFormat(env, jxil, inst); updateXilImages(inst); } return res; }
/* * Class: com_sun_media_protocol_sunvideo_XILCapture * Method: xilSetScale * Signature: (I)Z */ JNIEXPORT jboolean JNICALL Java_com_sun_media_protocol_sunvideo_XILCapture_xilSetScale(JNIEnv *env, jobject jxil, jint jscale) { int scale; InstanceState *inst = (InstanceState *) GetLongField(env, jxil, "peer"); if (inst == NULL) return; /* Debug Message*/ PRINT("In xilSetScale\n"); /* For now, only support 1 (full), 2 (1/2), 4 (1/4) */ scale = (int) jscale; if (scale == 1 || scale == 2 || scale == 4) { inst->scale = scale; inst->outWidth = 0; inst->outHeight = 0; inst->inStrideX = 0; setFormat(env, jxil, inst); } else { return 0; } return 1; }
/* * Class: com_sun_media_protocol_sunvideo_XILCapture * Method: xilGetLineStride * Signature: ()I */ JNIEXPORT jint JNICALL Java_com_sun_media_protocol_sunvideo_XILCapture_xilGetLineStride(JNIEnv *env, jobject jxil) { int w; InstanceState *inst = (InstanceState *) GetLongField(env, jxil, "peer"); if (inst == NULL) return -1; if (!inst->started || (inst->do_cis != RAW)) { /* Debug Message */ PRINT("XILCapture xilLineStride() not started \n"); /* return a guess at what it will be */ return (jint) (inst->inWidth * 3); } /* Debug Message*/ PRINT("In xilGetLineStride\n"); if (inst->firstRawRead) { XilMemoryStorage storage; int stride = 0; xil_export(inst->colored_image); xil_get_memory_storage(inst->colored_image, &storage); stride = storage.byte.scanline_stride; xil_import(inst->colored_image, 0); /* Debug Message */ PRINT("XILCapture xilLineStride() no read done \n"); return (jint) stride; } return (jint) inst->inStrideX; }
/*! \param FieldNo */ xbShort xbDbf::MemoFieldExists( xbShort FieldNo ) const { if( GetLongField( FieldNo ) == 0L ) return 0; else return 1; }
/* * Class: sage_SFIRTuner * Method: deviceName * Signature: ()Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_sage_SFIRTuner_deviceName(JNIEnv *env, jobject jo) { HINSTANCE hDriver = (HINSTANCE) GetLongField(env, jo, "nativeDllHandle"); FARPROC deviceNAME = dlsym(hDriver, "DeviceName"); if (deviceNAME) { const char* cName = (const char*)deviceNAME(); return (*env)->NewStringUTF(env, cName); } else return (*env)->NewStringUTF(env, ""); }
/* * Class: com_sun_media_protocol_sunvideo_XILCapture * Method: xilDisconnect * Signature: ()Z */ JNIEXPORT jboolean JNICALL Java_com_sun_media_protocol_sunvideo_XILCapture_xilDisconnect(JNIEnv *env, jobject jxil) { InstanceState *inst = (InstanceState *) GetLongField(env, jxil, "peer"); /* Debug Message */ PRINT("In xilFree\n"); if (inst) { freeXilState(env, jxil, inst); } }
JNIEXPORT void JNICALL Java_jpcap_JpcapWriter_writePacket(JNIEnv *env,jobject obj,jobject packet){ jbyteArray header,body; int hlen,blen; struct pcap_pkthdr hdr; char buf[MAX_PACKET_SIZE]; hdr.ts.tv_sec=(long)GetLongField(Packet,packet,"sec"); hdr.ts.tv_usec=(long)GetLongField(Packet,packet,"usec"); hdr.caplen=GetIntField(Packet,packet,"caplen"); hdr.len=GetIntField(Packet,packet,"len"); header=GetObjectField(Packet,packet,"[B","header"); body=GetObjectField(Packet,packet,"[B","data"); hlen=(*env)->GetArrayLength(env,header); blen=(*env)->GetArrayLength(env,body); (*env)->GetByteArrayRegion(env,header,0,hlen,buf); (*env)->GetByteArrayRegion(env,body,0,blen,(char *)(buf+hlen)); pcap_dump((u_char *)pdt,&hdr,buf); }
remote* createCRemote(JNIEnv *env, jobject jremote) { if (jremote == NULL) return NULL; remote* rv = (remote*)malloc(sizeof(remote)); jstring jname = (jstring) GetObjectField(env, jremote, "name", "Ljava/lang/String;"); const char* cname = (*env)->GetStringUTFChars(env, jname, NULL); rv->name = (unsigned char*) malloc((*env)->GetStringLength(env, jname) + 1); strcpy((char*)rv->name, cname); (*env)->ReleaseStringUTFChars(env, jname, cname); rv->carrier_freq = (unsigned long) GetLongField(env, jremote, "carrier_freq"); rv->bit_time = (unsigned) GetLongField(env, jremote, "bit_time"); rv->command = NULL; jobject currCmd = GetObjectField(env, jremote, "command", "Lsage/SFIRTuner$Command;"); if (currCmd != NULL) { rv->command = createCCmd(env, currCmd); } jobject nextRemote = GetObjectField(env, jremote, "next", "Lsage/SFIRTuner$Remote;"); rv->next = NULL; if (nextRemote != NULL) rv->next = createCRemote(env, nextRemote); return rv; }
/*! \param FieldNo */ xbLong xbDbf::GetFPTFieldLen( xbShort FieldNo ) { xbLong BlockNo; if(( BlockNo = GetLongField(FieldNo)) == 0L ) return 0L; // Seek to start_of_block + 4 if(_fseek(mfp, ((xbOffT)BlockNo * MemoHeader.BlockSize + 4), SEEK_SET) != 0) return XB_SEEK_ERROR; char h[4]; if((fread(h, 4, 1, mfp)) != 1) return XB_READ_ERROR; return xbase->GetHBFULong(h); }
/* * Class: com_sun_media_protocol_sunvideo_XILCapture * Method: xilStop * Signature: ()Z */ JNIEXPORT jboolean JNICALL Java_com_sun_media_protocol_sunvideo_XILCapture_xilStop(JNIEnv *env, jobject jxil) { InstanceState *inst = (InstanceState *) GetLongField(env, jxil, "peer"); if (inst == NULL) return; /* Debug Message*/ PRINT("In xilStop\n"); inst->started = 0; inst->firstRawRead = 1; freeXilImages(inst); }
/* * Class: com_sun_media_protocol_sunvideo_XILCapture * Method: xilSetSkip * Signature: (I)Z */ JNIEXPORT jboolean JNICALL Java_com_sun_media_protocol_sunvideo_XILCapture_xilSetSkip(JNIEnv *env, jobject jxil, jint jskip) { InstanceState *inst = (InstanceState *) GetLongField(env, jxil, "peer"); if (inst == NULL) return; /* Debug Message*/ PRINT("In xilSetSkip\n"); /* TODO - may want to do a sanity check */ inst->skip = (int)jskip; xil_set_device_attribute(inst->rtvc_image, "IMAGE_SKIP", (void *)inst->skip); }
/* * Class: com_sun_media_protocol_sunvideo_XILCapture * Method: xilSetCompress * Signature: (Ljava/lang/String;)Z */ JNIEXPORT jboolean JNICALL Java_com_sun_media_protocol_sunvideo_XILCapture_xilSetCompress(JNIEnv *env, jobject jxil, jstring jcompress) { const char *compress; InstanceState *inst = (InstanceState *) GetLongField(env, jxil, "peer"); if (inst == NULL) return; /* Debug Message*/ PRINT("In xilSetCompress\n"); compress = (*env)->GetStringUTFChars(env, jcompress, 0); if (strcasecmp(compress, "rgb") == 0) { inst->do_cis = RAW; inst->cis_type = "Raw"; } else if (strcasecmp(compress, "jpeg") == 0) { inst->do_cis = JPEG; inst->cis_type = "Jpeg"; } else if ((strcasecmp(compress, "mpeg") == 0) || (strcasecmp(compress, "mpeg1") == 0)) { inst->do_cis = MPEG; inst->cis_type = "Mpeg1"; } else if (strcasecmp(compress, "cellb") == 0) { inst->do_cis = CELLB; inst->cis_type = "CellB"; } else { /* Debug Message */ PRINT("Invalid compress format specified %s "); PRINT(compress); PRINT("\n"); } (*env)->ReleaseStringUTFChars(env, jcompress, compress); setFormat(env, jxil, inst); return TRUE; }
/* * Class: com_sun_media_protocol_sunvideo_XILCapture * Method: xilGetHeight * Signature: ()I */ JNIEXPORT jint JNICALL Java_com_sun_media_protocol_sunvideo_XILCapture_xilGetHeight(JNIEnv *env, jobject jxil) { InstanceState *inst = (InstanceState *) GetLongField(env, jxil, "peer"); if (inst == NULL) return -1; if (!inst->started) { /* Debug Message */ PRINT("XILCapture xilGetHeight() not started \n"); return (jint) (((float) inst->inHeight / inst->scale) + 0.5); } /* Debug Message*/ PRINT("In xilGetHeight\n"); return (jint) inst->outHeight; }
/*! \param FieldNo */ xbLong xbDbf::GetMemoFieldLen( xbShort FieldNo ) { if (Version == (char)0xf5 || Version == (char)0x30 ) return GetFPTFieldLen(FieldNo); xbLong BlockNo, ByteCnt; xbShort scnt, NotDone; char *sp, *spp; if(( BlockNo = GetLongField( FieldNo )) == 0L ) return 0L; if( IsType4Dbt()){ /* dBASE IV */ if( BlockNo == CurMemoBlockNo && CurMemoBlockNo != -1 ) return MFieldLen - MStartPos; if( ReadMemoBlock( BlockNo, 0 ) != XB_NO_ERROR ) return 0L; return MFieldLen - MStartPos; } else { /* version 0x03 dBASE III+ */ ByteCnt = 0L; spp = NULL; NotDone = 1; while( NotDone ){ if( ReadMemoBlock( BlockNo++, 1 ) != XB_NO_ERROR ) return 0L; scnt = 0; sp = (char *) mbb; while( scnt < 512 && NotDone ){ if( *sp == 0x1a && *spp == 0x1a ) NotDone = 0; else{ ByteCnt++; scnt++; spp = sp; sp++; } } } if( ByteCnt > 0 ) ByteCnt--; return ByteCnt; } }
/* * Class: com_sun_media_protocol_sunvideo_XILCapture * Method: xilRead * Signature: ([BI)I */ JNIEXPORT jint JNICALL Java_com_sun_media_protocol_sunvideo_XILCapture_xilRead(JNIEnv *env, jobject jxil, jbyteArray jbuf, jint jlen) { void *buf; int len; InstanceState *inst = (InstanceState *) GetLongField(env, jxil, "peer"); if (inst == NULL) return -1; if (!inst->started) { /* Debug Message */ PRINT("XILCapture xilRead() not started \n"); return -1; } /* Debug Message*/ /* PRINT("In xilRead\n"); */ buf = (void *) (*env)->GetByteArrayElements(env, jbuf, 0); if (inst->xil_cis) { len = readCompressed(inst, buf, (int)jlen); } else { len = readRaw(inst, buf, (int)jlen); if (inst->firstRawRead) { setFormat(env, jxil, inst); inst->firstRawRead = 0; } } (*env)->ReleaseByteArrayElements(env, jbuf, buf, 0); return len; }
/* * Class: com_sun_media_protocol_sunvideo_XILCapture * Method: xilStart * Signature: ()Z */ JNIEXPORT jboolean JNICALL Java_com_sun_media_protocol_sunvideo_XILCapture_xilStart(JNIEnv *env, jobject jxil) { InstanceState *inst = (InstanceState *) GetLongField(env, jxil, "peer"); if (inst == NULL) return 0; /* Debug Message*/ PRINT("In xilStart\n"); /* * Check scale and compression to eliminate invalid combinations. */ if (inst->do_cis == JPEG && inst->scale == 1) { return 0; } /* * At this point, rtvc_image is valid but nothing else is. * Construct the rest of the images needed. */ if (inst->inWidth == 0 || inst->signal == UNKNOWN_SIGNAL) { /* Don't know the input dimensions yet, get them. */ if (!tryPort(env, jxil, inst)) { fprintf(stderr, "SunVideo Capture xilStart() port not responding \n"); return 0; } } inst->started = 1; updateXilImages(inst); return 1; }
/*! */ xbLong xbDbf::GetLongField( const char * FieldName ) const { return( GetLongField( GetFieldNo( FieldName ))); }
/*! \param FieldNo \param DataLen \param Buf \param LockOpt */ xbShort xbDbf::UpdateMemoData( xbShort FieldNo, xbLong DataLen, const char * Buf, xbShort LockOpt ) { xbShort rc; xbLong TotalLen; xbLong BlocksNeeded, BlocksAvailable; #ifdef XB_LOCKING_ON if( LockOpt != -1 ) // if(( rc = LockMemoFile( XB_LOCK )) != XB_NO_ERROR ) // return XB_LOCK_FAILED; #endif if( DataLen ){ TotalLen = DataLen + 2; // add 2 eod 0x1a chars if( IsType4Dbt()) TotalLen += 8; // leading fields for dbase iv } else TotalLen = 0; if( DataLen == 0L ){ /* handle delete */ if( MemoFieldExists( FieldNo )){ if(( rc = DeleteMemoField( FieldNo )) != XB_NO_ERROR ){ #ifdef XB_LOCKING_ON // LockMemoFile( XB_UNLOCK ); #endif return rc; } } } else if((IsType3Dbt() || GetMemoFieldLen(FieldNo)==0L)){ if(( rc = AddMemoData( FieldNo, DataLen, Buf )) != XB_NO_ERROR ){ #ifdef XB_LOCKING_ON // LockMemoFile( XB_UNLOCK ); #endif return rc; } } else { /* version IV type files, reuse unused space */ if( TotalLen % MemoHeader.BlockSize ) BlocksNeeded = TotalLen / MemoHeader.BlockSize + 1; else BlocksNeeded = TotalLen / MemoHeader.BlockSize; if(( rc = ReadMemoBlock( GetLongField( FieldNo ), 4 )) != XB_NO_ERROR ){ #ifdef XB_LOCKING_ON // LockMemoFile( XB_UNLOCK ); #endif return rc; } if( (MFieldLen+2) % MemoHeader.BlockSize ) BlocksAvailable = (MFieldLen+2) / MemoHeader.BlockSize + 1; else BlocksAvailable = (MFieldLen+2) / MemoHeader.BlockSize; if( BlocksNeeded == BlocksAvailable ){ if(( rc = PutMemoData( GetLongField( FieldNo ), BlocksNeeded, DataLen, Buf )) != XB_NO_ERROR ){ #ifdef XB_LOCKING_ON // LockMemoFile( XB_UNLOCK ); #endif return rc; } } else { if(( rc = DeleteMemoField( FieldNo )) != XB_NO_ERROR ){ #ifdef XB_LOCKING_ON // LockMemoFile( XB_UNLOCK ); #endif return rc; } if(( rc = AddMemoData( FieldNo, DataLen, Buf )) != XB_NO_ERROR ){ #ifdef XB_LOCKING_ON // LockMemoFile( XB_UNLOCK ); #endif return rc; } } } #ifdef XB_LOCKING_ON // if( LockOpt != -1 ) // if(( rc = LockMemoFile( XB_UNLOCK )) != XB_NO_ERROR ) // return XB_LOCK_FAILED; #endif return XB_NO_ERROR; }
/*! \param FieldNo \param len \param Buf \param LockOpt */ xbShort xbDbf::GetFPTField(xbShort FieldNo, xbLong len, char * Buf, xbShort LockOpt) { if (FieldNo < 0 || FieldNo > (NoOfFields - 1)) return XB_INVALID_FIELDNO; if (GetFieldType(FieldNo) != 'M') return XB_NOT_MEMO_FIELD; #ifdef XB_LOCKING_ON // if( LockOpt != -1 ) // if( LockMemoFile( XB_LOCK ) != XB_NO_ERROR ) // return XB_LOCK_FAILED; #endif xbLong BlockNo; char buf[18]; if( Version == (char)0x30 ) { memset( buf, 0x00, 18 ) ; GetField( FieldNo, buf ); BlockNo = xbase->GetLong((char*) buf); } else { BlockNo = GetLongField(FieldNo); } if ( BlockNo == 0L ) return 0L; // Seek to start_of_block + 4 // FIXME LOCK #ifdef XB_LOCKING_ON // try { #endif if (_fseek(mfp, ((xbOffT)BlockNo * MemoHeader.BlockSize + 4), SEEK_SET) != 0) return XB_SEEK_ERROR; char h[4]; if ((fread(h, 4, 1, mfp)) != 1) return XB_READ_ERROR; xbULong fLen = xbase->GetHBFULong(h); xbULong l = (fLen < (xbULong)len) ? fLen : len; if ((fread(Buf, l, 1, mfp)) != 1) return XB_READ_ERROR; Buf[l]=0; #ifdef XB_LOCKING_ON // } // catch (...) { // if (LockOpt != -1) // LockMemoFile( XB_UNLOCK ); // throw; // } #endif #ifdef XB_LOCKING_ON // if (LockOpt != -1) // LockMemoFile( XB_UNLOCK ); #endif return XB_NO_ERROR; }
/*! \param FieldNo \param len \param Buf \param LockOpt */ xbShort xbDbf::GetMemoField( xbShort FieldNo, xbLong len, char * Buf, xbShort LockOpt ) { if( Version == (char)0xf5 || Version == (char)0x30 ) return GetFPTField(FieldNo, len, Buf, LockOpt); xbLong BlockNo, Tcnt, Scnt; char *tp, *sp; /* target and source pointers */ xbShort rc; xbShort Vswitch; xbLong MemoLen; if( FieldNo < 0 || FieldNo > ( NoOfFields - 1 )) return XB_INVALID_FIELDNO; if( GetFieldType( FieldNo ) != 'M' ) return XB_NOT_MEMO_FIELD; #ifdef XB_LOCKING_ON // if( LockOpt != -1 ) // if(( rc = LockMemoFile( LockOpt, XB_LOCK )) != XB_NO_ERROR ) // return XB_LOCK_FAILED; #endif if(( BlockNo = GetLongField( FieldNo )) == 0 ){ #ifdef XB_LOCKING_ON // if( LockOpt != -1 ) // LockMemoFile( XB_UNLOCK ); #endif return XB_NO_MEMO_DATA; } if( IsType3Dbt() ) Vswitch = 1; else Vswitch = 0; if(( rc = ReadMemoBlock( BlockNo, Vswitch )) != 0 ){ #ifdef XB_LOCKING_ON // if( LockOpt != -1 ) // LockMemoFile( XB_UNLOCK ); #endif return rc; } tp = Buf; sp = (char *) mbb; if( IsType4Dbt() ){ sp+=8; Scnt = 8L; } else Scnt = 0L; Tcnt = 0L; MemoLen = GetMemoFieldLen( FieldNo ); while( Tcnt < len && Tcnt < MemoLen ){ *tp++ = *sp++; Scnt++; Tcnt++; if( Scnt >= MemoHeader.BlockSize ){ BlockNo++; if(( rc = ReadMemoBlock( BlockNo, 1 )) != 0 ) return rc; Scnt = 0; sp = (char *) mbb; } } #ifdef XB_LOCKING_ON //if( LockOpt != -1 ) // LockMemoFile( XB_LOCK ); #endif return XB_NO_ERROR; }
/*! \param FieldNo */ xbShort xbDbf::DeleteMemoField( xbShort FieldNo ) { xbLong SBlockNo, SNoOfBlocks, SNextBlock; xbLong LastFreeBlock, LastFreeBlockCnt, LastDataBlock; xbShort rc; NextFreeBlock = 0L; LastFreeBlockCnt = 0L; LastFreeBlock = 0L; if( IsType3Dbt() ){ /* type III */ PutField( FieldNo, " " ); return XB_NO_ERROR; } /* Get Block Number */ if(( SBlockNo = GetLongField( FieldNo )) == 0 ) return XB_INVALID_BLOCK_NO; /* Load the first block */ if(( rc = ReadMemoBlock( SBlockNo, 4 )) != XB_NO_ERROR ) return rc; if( (MFieldLen+2) % MemoHeader.BlockSize ) SNoOfBlocks = (MFieldLen+2)/MemoHeader.BlockSize+1L; else SNoOfBlocks = (MFieldLen+2)/MemoHeader.BlockSize; /* Determine last good data block */ LastDataBlock = CalcLastDataBlock(); /* position to correct location in chain */ NextFreeBlock = MemoHeader.NextBlock; while( SBlockNo > NextFreeBlock && SBlockNo < LastDataBlock ){ LastFreeBlock = NextFreeBlock; if(( rc = ReadMemoBlock( NextFreeBlock, 2 )) != XB_NO_ERROR ) return rc; LastFreeBlockCnt = FreeBlockCnt; } /* if next block should be concatonated onto the end of this set */ if((SBlockNo+SNoOfBlocks) == NextFreeBlock && NextFreeBlock < LastDataBlock ) { if(( rc = ReadMemoBlock( NextFreeBlock, 2 )) != XB_NO_ERROR ) return XB_NO_ERROR; SNoOfBlocks += FreeBlockCnt; SNextBlock = NextFreeBlock; } else if( LastFreeBlock == 0L ) SNextBlock = MemoHeader.NextBlock; else SNextBlock = NextFreeBlock; /* if this is the first set of free blocks */ if( LastFreeBlock == 0L ){ /* 1 - write out the current block */ /* 2 - update header block */ /* 3 - write header block */ /* 4 - update data field */ NextFreeBlock = SNextBlock; FreeBlockCnt = SNoOfBlocks; if(( rc = WriteMemoBlock( SBlockNo, 2 )) != XB_NO_ERROR ) return rc; MemoHeader.NextBlock = SBlockNo; if(( rc = UpdateHeadNextNode()) != XB_NO_ERROR ) return rc; PutField( FieldNo, " " ); return XB_NO_ERROR; } /* determine if this block set should be added to the previous set */ if(( LastFreeBlockCnt + LastFreeBlock ) == SBlockNo ){ if(( rc = ReadMemoBlock( LastFreeBlock, 2 )) != XB_NO_ERROR ) return rc; NextFreeBlock = SNextBlock; FreeBlockCnt += SNoOfBlocks; if(( rc = WriteMemoBlock( LastFreeBlock, 2 )) != XB_NO_ERROR ) return rc; PutField( FieldNo, " " ); return XB_NO_ERROR; } /* insert into the chain */ /* 1 - set the next bucket on the current node */ /* 2 - write this node */ /* 3 - go to the previous node */ /* 4 - insert this nodes id into the previous node set */ /* 5 - write previous node */ FreeBlockCnt = SNoOfBlocks; if(( rc = WriteMemoBlock( SBlockNo, 2 )) != XB_NO_ERROR ) return rc; if(( rc = ReadMemoBlock( LastFreeBlock, 2 )) != XB_NO_ERROR ) return rc; NextFreeBlock = SBlockNo; if(( rc = WriteMemoBlock( LastFreeBlock, 2 )) != XB_NO_ERROR ) return rc; PutField( FieldNo, " " ); return XB_NO_ERROR; }