Beispiel #1
0
// Does not reset slice->sent, so must be used *only* after Copy().
void RequestQueue::Shuffle(bt_index_t idx)
{
  PIECE *piece;
  SLICE *slice, *prev, *end = (SLICE *)0, *snext, *temp;
  SLICE start;
  int len, shuffle;
  bt_offset_t firstoff;

  if( !(piece = FindPiece(idx)) ) return;
  len = piece->count;
  if( len == 1 ) return;
  firstoff = piece->slices->offset;

  start.next = piece->slices;
  shuffle = RandBits(3) + 2;
  if( shuffle > len/2 ) shuffle = len/2;
  for( ; shuffle; shuffle-- ){
    // Undock the list, then randomly re-insert each slice.
    prev = &start;             // the slice before the last insertion
    slice = start.next->next;  // first one is a no-op
    end = start.next;
    start.next->next = (SLICE *)0;
    for( ; slice; slice = snext ){
      snext = slice->next;
      if( RandBits(1) ){  // beginning or end of list
        if( RandBits(1) ){
          prev = end;
          slice->next = (SLICE *)0;
          end->next = slice;
          end = slice;
        }else{
          slice->next = start.next;
          start.next = slice;
          prev = &start;
        }
      }else{  // before or after previous insertion
        if( RandBits(1) ){  // put after prev->next
          if( end == prev->next ) end = slice;
          temp = prev->next;
          slice->next = prev->next->next;
          prev->next->next = slice;
          prev = temp;
        }else{  // put after prev (before prev->next)
          slice->next = prev->next;
          prev->next = slice;
        }
      }
    }
  }  // shuffle loop
  piece->slices = start.next;

  // If first slice is the same as in the original, move it to the end.
  if( piece->slices->offset == firstoff ){
    end->next = piece->slices;
    piece->slices = piece->slices->next;
    end = end->next;
    end->next = (SLICE *)0;
  }
  if( rq_send->index == piece->slices->index ) rq_send = piece->slices;
}
Beispiel #2
0
// Counts only slices from one piece.
dt_count_t RequestQueue::Qlen(bt_index_t idx) const
{
  dt_count_t total = 0;
  const PIECE *piece;

  if( (piece = FindPiece(idx)) ){
    total = piece->count;
  }
  return total;
}
Beispiel #3
0
// This function is a failsafe.
SLICE *RequestQueue::FixSend()
{
  PIECE *piece;
  SLICE *original = rq_send;
  bool report = true;

  if( !rq_head ){
    rq_send = (SLICE *)0;
    return rq_send;
  }

  if( !rq_send || !(piece = FindPiece(rq_send->index)) ){
    if( rq_send ){
      CONSOLE.Debug("%p rq_send invalid:  %d/%d/%d", this,
        (int)rq_send->index, (int)rq_send->offset, (int)rq_send->length);
    }
    rq_send = rq_head->slices;
    report = false;
  }
  while( rq_send && rq_send->sent ){  // rq_send is wrong, fix it
    if( report ){
      CONSOLE.Debug("%p rq_send wrong:  %d/%d/%d", this,
        (int)rq_send->index, (int)rq_send->offset, (int)rq_send->length);
      report = false;
    }
    if( rq_send->next ) rq_send = rq_send->next;
    else{
      piece = FindPiece(rq_send->index);
      rq_send = (piece && piece->next) ? piece->next->slices : (SLICE *)0;
    }
  }

  if( rq_send != original ){
    if( !original ) CONSOLE.Debug("%p rq_send was null", this);
    if( !rq_send ) CONSOLE.Debug("%p rq_send corrected to null", this);
    else{
      CONSOLE.Debug("%p rq_send corrected:  %d/%d/%d", this,
        (int)rq_send->index, (int)rq_send->offset, (int)rq_send->length);
    }
  }
  return rq_send;
}
Beispiel #4
0
bool RequestQueue::PeekPiece(bt_index_t idx, bt_offset_t *poff,
  bt_length_t *plen, bool *psent) const
{
  const PIECE *piece;

  if( !(piece = FindPiece(idx)) ) return false;
  m_peek = piece->slices;
  if( poff ) *poff = m_peek->offset;
  if( plen ) *plen = m_peek->length;
  if( psent ) *psent = m_peek->sent;
  return true;
}
Beispiel #5
0
bool RequestQueue::Delete(bt_index_t idx)
{
  PIECE *piece, *prev;

  if( !(piece = FindPiece(idx, &prev)) ) return false;
  if( prev ) prev->next = piece->next;
  else rq_head = piece->next;

  if( rq_send && rq_send->index == idx )
    rq_send = piece->next ? piece->next->slices : (SLICE *)0;

  piece->next = (PIECE *)0;
  _empty_slice_list(&piece);
  return true;
}
Beispiel #6
0
// If prev is given/non-null, it will point to the slice preceding the target.
SLICE *RequestQueue::FindSlice(bt_index_t idx, bt_offset_t off,
  bt_length_t len, SLICE **prev) const
{
  PIECE *piece;
  SLICE *slice = (SLICE *)0;

  if( prev ) *prev = (SLICE *)0;
  if( (piece = FindPiece(idx)) ){
    for( slice = piece->slices; slice; slice = slice->next ){
      if( slice->index == idx && slice->offset == off && slice->length == len )
        break;
      if( prev ) *prev = slice;
    }
  }
  return slice;
}
Beispiel #7
0
bool RequestQueue::Append(PIECE *piece)
{
  PIECE *last;
  SLICE *slice;

  if( FindPiece(piece->slices->index, &last) ) return false;

  if( last ) last->next = piece;
  else rq_head = piece;

  for( slice = piece->slices; slice && slice->sent; slice = slice->next ){
    slice->sent = false;
  }
  if( !rq_send ) rq_send = piece->slices;
  return true;
}
Beispiel #8
0
// Note that -1 indicates a failure to copy/add, not in the source (this).
int RequestQueue::Copy(RequestQueue &dstq, bt_index_t idx) const
{
  const PIECE *piece;
  const SLICE *slice;

  if( dstq.FindPiece(idx) ) return 0;

  if( !(piece = FindPiece(idx)) ) return 0;
  for( slice = piece->slices; slice; slice = slice->next ){
    if( !dstq.Add(slice->index, slice->offset, slice->length) ){
      dstq.Delete(idx);
      return -1;
    }
  }
  return 1;
}
Beispiel #9
0
bool RequestQueue::PeekNextPiece(bt_index_t *pidx, bt_offset_t *poff,
  bt_length_t *plen) const
{
  const PIECE *piece;

  if( !m_peek ) return PeekNext(pidx, poff, plen);

  if( !(piece = FindPiece(m_peek->index)) ) return false;
  piece = piece->next;
  m_peek = piece ? piece->slices : (SLICE *)0;
  if( m_peek ){
    if( pidx ) *pidx = m_peek->index;
    if( poff ) *poff = m_peek->offset;
    if( plen ) *plen = m_peek->length;
  }
  return m_peek ? true : false;
}
Beispiel #10
0
// Move the slice to the end of its piece sequence.
void RequestQueue::MoveLast(bt_index_t idx, bt_offset_t off, bt_length_t len)
{
  PIECE *piece;
  SLICE *slice, *point;

  if( !(piece = FindPiece(idx)) ) return;
  slice = FindSlice(idx, off, len, &point);
  if( !slice || !slice->next ) return;

  if( rq_send == slice ) rq_send = slice->next;
  if( point ) point->next = slice->next;
  else piece->slices = slice->next;
  slice->sent = false;

  for( point = slice->next; point->next; point = point->next );
  point->next = slice;
  slice->next = (SLICE *)0;
}
Beispiel #11
0
void RequestQueue::Sent(time_t timestamp, SLICE *slice)
{
  if( !slice && !(slice = rq_send) && !(slice = FixSend()) ){
    CONSOLE.Warning(1,
      "RequestQueue error:  Sent() called but nothing to send");
    return;
  }

  slice->reqtime = timestamp;
  slice->sent = true;

  if( rq_send == slice ){
    rq_send = slice->next;
    if( !rq_send ){
      const PIECE *piece = FindPiece(slice->index);
      if( piece->next ) rq_send = piece->next->slices;
    }
  }
}
Beispiel #12
0
// Returns true if the piece was moved successfully.
bool RequestQueue::Transfer(RequestQueue &dstq, bt_index_t idx)
{
  bool result = true;
  PIECE *piece, *prev;

  if( !(piece = FindPiece(idx, &prev)) ) return true;

  if( rq_send && rq_send->index == idx )
    rq_send = piece->next ? piece->next->slices : (SLICE *)0;

  if( prev ) prev->next = piece->next;
  else rq_head = piece->next;
  piece->next = (PIECE *)0;

  if( (&PENDING == &dstq && piece->count >= NSlices(piece->slices->index)) ||
      !dstq.Append(piece) ){
    _empty_slice_list(&piece);
    result = false;
  }
  return result;
}
Beispiel #13
0
bool RequestQueue::Add(bt_index_t idx, bt_offset_t off, bt_length_t len)
{
  PIECE *piece, *last;
  SLICE *slice, *point = (SLICE *)0;

  piece = FindPiece(idx, &last);

  if( !(slice = new SLICE) ){
    errno = ENOMEM;
    return false;
  }
  if( piece ){
    for( point = piece->slices; point && point->next; point = point->next );
  }else{
    if( !(piece = new PIECE) ){
      delete slice;
      errno = ENOMEM;
      return false;
     }
    piece->count = 0;
    piece->slices = (SLICE *)0;
    piece->next = (PIECE *)0;
    if( last ) last->next = piece;
    else rq_head = piece;
  }

  slice->next = (SLICE *)0;
  slice->index = idx;
  slice->offset = off;
  slice->length = len;
  slice->reqtime = (time_t) 0;
  slice->sent = false;

  if( point ) point->next = slice;
  else piece->slices = slice;
  piece->count++;

  if( !rq_send && !piece->next ) rq_send = slice;
  return true;
}
Beispiel #14
0
/* Peek() or PeekPiece() must be called first, to insure m_peek is initialized
   to a valid state.  The queue must not be changed between calls to
   PeekNext(). */
bool RequestQueue::PeekNext(bt_index_t *pidx, bt_offset_t *poff,
  bt_length_t *plen, bool *psent) const
{
  const SLICE *slice = (SLICE *)0;

  if( m_peek ){
    slice = m_peek->next;
    if( !slice ){
      const PIECE *piece;
      if( (piece = FindPiece(m_peek->index)) ){
        piece = piece->next;
        if( piece ) slice = piece->slices;
      }
    }
  }else if( rq_head ) slice = rq_head->slices;
  if( slice ){
    if( pidx ) *pidx = slice->index;
    if( poff ) *poff = slice->offset;
    if( plen ) *plen = slice->length;
    if( psent ) *psent = slice->sent;
  }
  m_peek = slice;
  return slice ? true : false;
}
Beispiel #15
0
bool RequestQueue::Remove(bt_index_t idx, bt_offset_t off, bt_length_t len)
{
  PIECE *piece, *prevpiece = (PIECE *)0;
  SLICE *slice, *prev = (SLICE *)0;

  if( !(piece = FindPiece(idx, &prevpiece)) ) return false;
  if( !(slice = FindSlice(idx, off, len, &prev)) ) return false;

  if( prev ) prev->next = slice->next;
  else piece->slices = slice->next;
  if( rq_send == slice ){
    rq_send = slice->next;
    if( !rq_send && piece->next ) rq_send = piece->next->slices;
  }
  delete slice;
  piece->count--;

  if( !piece->slices ){
    if( prevpiece ) prevpiece->next = piece->next;
    else rq_head = piece->next;
    delete piece;
  }
  return true;
}
Beispiel #16
0
/*
 * Function:
 *	Search
 *
 * Parameters:
 *	w	 - AsciiSource object
 *	position - the position to start scanning
 *	dir	 - direction to scan
 *	text	 - text block to search for
 *
 * Description:
 *	Searchs the text source for the text block passed.
 *
 * Returns:
 *	The position of the item found
 */
static XawTextPosition 
Search(Widget w, register XawTextPosition position, XawTextScanDirection dir,
       XawTextBlock *text)
{
    AsciiSrcObject src = (AsciiSrcObject)w;
    register int count = 0;
    register char *ptr, c;
    char *str;
    Piece *piece;
    char *buf;
    XawTextPosition first;
    int cnt, case_sensitive;

    if (dir == XawsdLeft) {
	if (position == 0)
	    return (XawTextSearchError);
	position--;
    }

    buf = XtMalloc((unsigned)sizeof(unsigned char) * text->length);
    memcpy(buf, text->ptr, (unsigned)text->length);
    piece = FindPiece(src, position, &first);
    ptr = (position - first) + piece->text;
    case_sensitive = text->firstPos;

    if (dir == XawsdRight) {
	str = buf;
	c = *str;
	/*CONSTCOND*/
	while (1) {
	    if (*ptr++ == c
		|| (case_sensitive && isalpha(c) && isalpha(ptr[-1])
		    && toupper(c) == toupper(ptr[-1]))) {
		if (++count == text->length)
		    break;
		c = *++str;
	    }
	    else if (count) {
		ptr -= count;
		str -= count;
		position -= count;
		count = 0;
		c = *str;

		if (ptr < piece->text) {
		    do {
			cnt = piece->text - ptr;
			piece = piece->prev;
			if (piece == NULL) {
			    XtFree(buf);
			    return (XawTextSearchError);
			}
			ptr = piece->text + piece->used - cnt;
		    } while (ptr < piece->text);
		}
	    }
	    position++;
	    if (ptr >= (piece->text + piece->used)) {
		do {
		    cnt = ptr - (piece->text + piece->used);
		    piece = piece->next;
		    if (piece == NULL) {
			XtFree(buf);
			return (XawTextSearchError);
		    }
		    ptr = piece->text + cnt;
		} while (ptr >= (piece->text + piece->used));
	    }
	}

	position -= text->length - 1;
    }
    else {
	str = buf + text->length - 1;
	c = *str;
	/*CONSTCOND*/
	while (1) {
	    if (*ptr-- == c
		|| (case_sensitive && isalpha(c) && isalpha(ptr[1])
		    && toupper(c) == toupper(ptr[1]))) {
		if (++count == text->length)
		    break;
		c = *--str;
	    }
	    else if (count) {
		ptr += count;
		str += count;
		position += count;
		count = 0;
		c = *str;

		if (ptr >= (piece->text + piece->used)) {
		    do {
			cnt = ptr - (piece->text + piece->used);
			piece = piece->next;
			if (piece == NULL) {
			    XtFree(buf);
			    return (XawTextSearchError);
			}
			ptr = piece->text + cnt;
		    } while (ptr >= (piece->text + piece->used));
		}
	    }
	    position--;
	    if (ptr < piece->text) {
		do {
		    cnt = piece->text - ptr;
		    piece = piece->prev;
		    if (piece == NULL) {
			XtFree(buf);
			return (XawTextSearchError);
		    }
		    ptr = piece->text + piece->used - cnt;
		} while (ptr < piece->text);
	    }
	}
    }

    XtFree(buf);

    return (position);
}
Beispiel #17
0
/*
 * Function:
 *	Scan
 *
 * Parameters:
 *	w	 - AsciiSource object
 *	position - position to start scanning
 *	type	 - type of thing to scan for
 *	dir	 - direction to scan
 *		   count - which occurance if this thing to search for.
 *		   include - whether or not to include the character found in
 *		   the position that is returned
 *
 * Description:
 *	Scans the text source for the number and type of item specified.
 *
 * Returns:
 *	The position of the item found
 *
 * Note:
 *	  While there are only 'n' characters in the file there are n+1
 *	 possible cursor positions (one before the first character and
 *	one after the last character
 */
static XawTextPosition
Scan(Widget w, register XawTextPosition position, XawTextScanType type,
     XawTextScanDirection dir, int count, Bool include)
{
    AsciiSrcObject src = (AsciiSrcObject)w;
    Piece *piece;
    XawTextPosition first, first_eol_position = 0;
    register char *ptr, *lim;
    register int cnt = count;
    register unsigned char c;

    if (dir == XawsdLeft) {
	if (position <= 0)
	    return (0);
	--position;
    }
    else if (position >= src->ascii_src.length)
	return (src->ascii_src.length);

    piece = FindPiece(src, position, &first);
    if (piece->used == 0)
	return (0);

    ptr = (position - first) + piece->text;

    if (dir == XawsdRight) {
	lim = piece->text + piece->used;
	switch (type) {
	    case XawstEOL:
	    case XawstParagraph:
	    case XawstWhiteSpace:
	    case XawstAlphaNumeric:
		for (; cnt > 0; cnt--) {
		    Bool non_space = False, first_eol = True;

		    /*CONSTCOND*/
		    while (True) {
			if (ptr >= lim) {
			    piece = piece->next;
			    if (piece == NULL)	/* End of text */
				return (src->ascii_src.length);
			    ptr = piece->text;
			    lim = piece->text + piece->used;
			}

			c = *ptr++;
			++position;

			if (type == XawstEOL) {
			    if (c == '\n')
				break;
			}
			else if (type == XawstAlphaNumeric) {
			    if (!isalnum(c)) {
				if (non_space)
				    break;
			    }
			    else
				non_space = True;
			}
			else if (type == XawstWhiteSpace) {
			    if (isspace(c)) {
				if (non_space)
				    break;
			    }
			    else
				non_space = True;
			}
			else {	/* XawstParagraph */
			    if (first_eol) {
				if (c == '\n') {
				    first_eol_position = position;
				    first_eol = False;
				}
			    }
			    else if (c == '\n')
				break;
			    else if (!isspace(c))
				first_eol = True;
			}
		    }
		}
		break;
	    case XawstPositions:
		position += count;
		return (position < src->ascii_src.length ?
			position : src->ascii_src.length);
	    case XawstAll:
		return (src->ascii_src.length);
	    default:
		break;
	}
	if (!include) {
	    if (type == XawstParagraph)
		position = first_eol_position;
	    if (count)
		--position;
	}
    }
    else {
	lim = piece->text;
	switch (type) {
	    case XawstEOL:
	    case XawstParagraph:
	    case XawstWhiteSpace:
	    case XawstAlphaNumeric:
		for (; cnt > 0; cnt--) {
		    Bool non_space = False, first_eol = True;

		    /*CONSTCOND*/
		    while (True) {
			if (ptr < lim) {
			    piece = piece->prev;
			    if (piece == NULL)	/* Begining of text */
				return (0);
			    ptr = piece->text + piece->used - 1;
			    lim = piece->text;
			}

			c = *ptr--;
			--position;

			if (type == XawstEOL) {
			    if (c == '\n')
				break;
			}
			else if (type == XawstAlphaNumeric) {
			    if (!isalnum(c)) {
				if (non_space)
				    break;
			    }
			    else
				non_space = True;
			}
			else if (type == XawstWhiteSpace) {
			    if (isspace(c)) {
				if (non_space)
				    break;
			    }
			    else
				non_space = True;
			}
			else {	/* XawstParagraph */
			    if (first_eol) {
				if (c == '\n') {
				    first_eol_position = position;
				    first_eol = False;
				}
			    }
			    else if (c == '\n')
				break;
			    else if (!isspace(c))
				first_eol = True;
			}
		    }
		}
		break;
	    case XawstPositions:
		position -= count - 1;
		return (position > 0 ? position : 0);
	    case XawstAll:
		return (0);
	    default:
		break;
	}
	if (!include) {
	    if (type == XawstParagraph)
		position = first_eol_position;
	    if (count)
		++position;
	}
	position++;
    }

    return (position);
}
Beispiel #18
0
/*ARGSUSED*/
static int
ReplaceText(Widget w, XawTextPosition startPos, XawTextPosition endPos,
	    XawTextBlock *text)
{
    AsciiSrcObject src = (AsciiSrcObject)w;
    Piece *start_piece, *end_piece, *temp_piece;
    XawTextPosition start_first, end_first;
    int length, firstPos;

    /*
     * Editing a read only source is not allowed
     */
    if (src->text_src.edit_mode == XawtextRead) 
	return (XawEditError);

    start_piece = FindPiece(src, startPos, &start_first);
    end_piece = FindPiece(src, endPos, &end_first);

#ifndef OLDXAW
    /*
     * This is a big hack, but I can't think about a clever way to know
     * if the character being moved forward has a negative lbearing.
     *
     */
    if (start_piece->used) {
	int i;

	for (i = 0; i < src->text_src.num_text; i++) {
	    int line;
	    TextWidget ctx = (TextWidget)src->text_src.text[i];

	    for (line = 0; line < ctx->text.lt.lines; line++)
		if (startPos < ctx->text.lt.info[line + 1].position)
		    break;
	    if (i < ctx->text.lt.lines &&
		startPos > ctx->text.lt.info[i].position) {
		AsciiSinkObject sink = (AsciiSinkObject)ctx->text.sink;
		XawTextAnchor *anchor;
		XawTextEntity *entity;
		XawTextProperty *property;
		XFontStruct *font;

		if (XawTextSourceAnchorAndEntity(w, startPos, &anchor, &entity) &&
		    (property = XawTextSinkGetProperty(ctx->text.sink,
						       entity->property)) != NULL &&
		    (property->mask & XAW_TPROP_FONT))
		    font = property->font;
		else
		    font = sink->ascii_sink.font;

		if (font->min_bounds.lbearing < 0) {
		    int lbearing = font->min_bounds.lbearing;
		    unsigned char c = *(unsigned char*)
			(start_piece->text + (startPos - start_first));

		    if (c == '\t' || c == '\n')
			c = ' ';
		    else if ((c & 0177) < XawSP || c == 0177) {
			if (sink->ascii_sink.display_nonprinting)
			    c = c > 0177 ? '\\' : c + '^';
			else
			    c = ' ';
		    }
		    if (font->per_char &&
			(c >= font->min_char_or_byte2 && c <= font->max_char_or_byte2))
			lbearing = font->per_char[c - font->min_char_or_byte2].lbearing;
		    if (lbearing < 0)
			_XawTextNeedsUpdating(ctx, startPos - 1, startPos);
		}
	    }
	}
    }


#endif

    /*
     * Remove Old Stuff
     */
    if (start_piece != end_piece) {
	temp_piece = start_piece->next;

	/*
	 * If empty and not the only piece then remove it.
	 */
	if (((start_piece->used = startPos - start_first) == 0)
	    && !(start_piece->next == NULL && start_piece->prev == NULL))
	    RemovePiece(src, start_piece);

	while (temp_piece != end_piece) {
	    temp_piece = temp_piece->next;
	    RemovePiece(src, temp_piece->prev);
	}

	end_piece->used -= endPos - end_first;
	if (end_piece->used != 0)
	    memmove(end_piece->text, end_piece->text + endPos - end_first,
		    (unsigned)end_piece->used);
    }
    else {		    /* We are fully in one piece */
	if ((start_piece->used -= endPos - startPos) == 0) {
	    if (!(start_piece->next == NULL && start_piece->prev == NULL))
		RemovePiece(src, start_piece);
	}
	else {
	    memmove(start_piece->text + (startPos - start_first),
		    start_piece->text + (endPos - start_first),
		    (unsigned)(start_piece->used - (startPos - start_first)));
	    if (src->ascii_src.use_string_in_place
		&& src->ascii_src.length - (endPos - startPos)
		< src->ascii_src.piece_size - 1)
		start_piece->text[src->ascii_src.length - (endPos - startPos)] =
		    '\0';
	}
    }

    src->ascii_src.length += -(endPos - startPos) + text->length;

    if ( text->length != 0) {
	/* 
	 * Put in the New Stuff
	 */
	start_piece = FindPiece(src, startPos, &start_first);

	length = text->length;
	firstPos = text->firstPos;

	while (length > 0) {
	    char *ptr;
	    int fill;

	    if (src->ascii_src.use_string_in_place) {
		if (start_piece->used == src->ascii_src.piece_size - 1) {
		    /*
		     * If we are in ascii string emulation mode. Then the
		     *	string is not allowed to grow
		     */
		    start_piece->used = src->ascii_src.length =
			src->ascii_src.piece_size - 1;
		    start_piece->text[src->ascii_src.length] = '\0';
		    return (XawEditError);
		}
	    }

	    if (start_piece->used == src->ascii_src.piece_size) {
		BreakPiece(src, start_piece);
		start_piece = FindPiece(src, startPos, &start_first);
	    }

	    fill = Min((int)(src->ascii_src.piece_size - start_piece->used),
		       length);

	    ptr = start_piece->text + (startPos - start_first);
	    memmove(ptr + fill, ptr,
		    (unsigned)(start_piece->used - (startPos - start_first)));
	    memcpy(ptr, text->ptr + firstPos, (unsigned)fill);

	    startPos += fill;
	    firstPos += fill;
	    start_piece->used += fill;
	    length -= fill;
	}
    }

    if (src->ascii_src.use_string_in_place)
	start_piece->text[start_piece->used] = '\0';

#ifdef OLDXAW
    src->ascii_src.changes = True;
    XtCallCallbacks(w, XtNcallback, NULL);
#endif

    return (XawEditDone);
}
Beispiel #19
0
/*
 * Function:
 *	ReadText
 *
 * Parameters:
 *	w	- AsciiSource widget
 *	pos	- position of the text to retreive.
 *	text	- text block that will contain returned text
 *	length	- maximum number of characters to read
 *
 * Description:
 *	This function reads the source.
 *
 * Returns:
 *	The character position following the retrieved text.
 */
static XawTextPosition
ReadText(Widget w, XawTextPosition pos, XawTextBlock *text, int length)
{
    AsciiSrcObject src = (AsciiSrcObject)w;
    XawTextPosition count, start;
    Piece *piece;
#ifndef OLDXAW 
    XawTextAnchor *anchor;
    XawTextEntity *entity;
    XawTextPosition offset, end = pos + length;
    Bool state;

    end = XawMin(end, src->ascii_src.length);
    while ((state = XawTextSourceAnchorAndEntity(w, pos, &anchor, &entity)) &&
	(entity->flags & XAW_TENTF_HIDE))
	pos = anchor->position + entity->offset + entity->length;
    if (state == False ||
	!(entity->flags & XAW_TENTF_REPLACE)) {
	while (entity) {
	    offset = anchor->position + entity->offset;
	    if (offset >= end)
		break;
	    if (offset > pos &&
		(entity->flags & (XAW_TENTF_HIDE | XAW_TENTF_REPLACE))) {
		end = XawMin(end, offset);
		break;
	    }
	    if ((entity = entity->next) == NULL &&
		(anchor = XawTextSourceNextAnchor(w, anchor)) != NULL)
		entity = anchor->entities;
	}
    }
    else if (state && (entity->flags & XAW_TENTF_REPLACE) && pos < end) {
	XawTextBlock *block = (XawTextBlock*)entity->data;

	offset = anchor->position + entity->offset;
	end = XawMin(end, offset + block->length);
	if ((length = end - pos) < 0)
	    length = 0;
	text->length = length;
	text->format = XawFmt8Bit;
	if (length == 0) {
	    text->firstPos = end = offset + entity->length;
	    text->ptr = "";
	}
	else {
	    text->firstPos = pos;
	    text->ptr = block->ptr + (pos - offset);
	    if (pos + length < offset + block->length)
		end = pos + length;	/* there is data left to be read */
	    else
		end = offset + entity->length;
	}

	return (end);
    }

    if ((length = end - pos) < 0)
	length = 0;
#endif

    piece = FindPiece(src, pos, &start);
    text->firstPos = pos;
    text->ptr = piece->text + (pos - start);
    count = piece->used - (pos - start);
    text->length = Max(0, (length > count) ? count : length);
    text->format = XawFmt8Bit;

    return (pos + text->length);
}