Bend.SegmentBlockBasicDecoder._prevRecord C# (CSharp) Метод

_prevRecord() приватный Метод

private _prevRecord ( RecordLocator &rloc ) : void
rloc RecordLocator
Результат void
        private void _prevRecord(ref RecordLocator rloc)
        {
            byte[] search_buffer = new byte[PREV_RECORD_SCANSIZE];
            int read_result_size, read_size;

            if (!rloc.have_record) {
                throw new Exception("_prevRecord() called with rloc.have_record==false");
            }
            if (rloc.start_pos == 0) {
                // we can't go back before the beginning of our block, so if we reach it, we are done
                rloc.have_record = false;
                rloc.start_pos = 0;
                rloc.after_end_pos = 0;
                rloc.record = default(KeyValuePair<RecordKey,RecordUpdate>);
                return;
            }

            int check_up_to = rloc.start_pos - 1;  // stop short, or we'll try to redecode the same record we were handed
            int cur_stream_pos = Math.Max(0, rloc.start_pos - search_buffer.Length);
            while (cur_stream_pos >= 0) {
                this.datastream.Seek(cur_stream_pos, SeekOrigin.Begin);
                read_size = (int)Math.Min(search_buffer.Length,check_up_to-cur_stream_pos);
                read_result_size = this.datastream.Read(search_buffer,0,read_size);

                int bufpos = read_result_size - 1;
                while (bufpos >= 0) {

                    if (search_buffer[bufpos] == SegmentBlockBasicEncoder.END_OF_LINE) {
                        // decode record
                        int new_record_start = cur_stream_pos + bufpos + 1;

                        this.datastream.Seek(new_record_start, SeekOrigin.Begin);
                        rloc.record = SegmentBlockBasicDecoder._decodeRecordFromBlock(this.datastream);
                        rloc.after_end_pos = (int) this.datastream.Position;
                        if (rloc.after_end_pos != rloc.start_pos) {
                            // if this decode didn't bring us to the start of the record we were
                            // ..handed, then something is WRONG!
                            throw new Exception("_prevRecord() INTERNAL scan error");
                        }
                        rloc.have_record = true;
                        rloc.start_pos = new_record_start;
                        return;
                    }
                    bufpos--;
                }
                // IF we got this far with cur_stream_pos == 0, we're at the start of the block!
                if (cur_stream_pos == 0) {
                    // TODO: use a crafty state switch to avoid the block duplicated here from above

                    // if we landed on the beginnng of the block, then decode the first record in the block
                    int new_record_start = 0;
                    this.datastream.Seek(new_record_start, SeekOrigin.Begin);
                    rloc.record = SegmentBlockBasicDecoder._decodeRecordFromBlock(this.datastream);
                    rloc.after_end_pos = (int)this.datastream.Position;
                    if (rloc.after_end_pos != rloc.start_pos) {
                        // if this decode didn't bring us to the start of the record we were
                        // ..handed, then something is WRONG!
                        throw new Exception("_prevRecord() INTERNAL scan error");
                    }
                    rloc.have_record = true;
                    rloc.start_pos = new_record_start;
                    return;
                }

                // backup to the next range
                cur_stream_pos = Math.Max(0, cur_stream_pos - search_buffer.Length);
            };
            throw new Exception("_prevRecord() INTERNAL scan error, dropout");
        }