private void getLine()

in org.eclipse.egit.core/src/org/eclipse/egit/core/internal/efs/OursVersionInputStream.java [175:296]


	private void getLine() throws IOException {
		for (;;) {
			if (pos == end) {
				pos = 0;
				end = IO.readFully(in, buffer, 0);
				if (end == 0) {
					pos = -1;
					break;
				}
			}
			// Find the next LF
			int lf = -1;
			for (int i = pos; i < end; i++) {
				if (buffer[i] == '\n') {
					lf = i;
					break;
				}
			}
			boolean wasFullLine = isFullLine;
			if (lf < 0) {
				isFullLine = false;
				lineEnd = end;
			} else {
				lineEnd = lf + 1;
				isFullLine = true;
			}
			if (!wasFullLine) {
				// We had a partial line before. Previous state determines fate.
				switch (state) {
				case MARKER:
					pos = lineEnd;
					if (isFullLine) {
						state = nextState;
						nextState = null;
					}
					continue;
				case MERGED:
				case OURS:
					return;
				case BASE:
				case THEIRS:
					// Skip it
					pos = lineEnd;
					continue;
				default:
					throw new IllegalStateException();
				}
			}
			// 'pos' is at the beginning of a new line.
			if (!isFullLine && end == buffer.length
					&& end - pos < conflictMarkerSize + 1 && pos > 0) {
				// Copy the partial stuff to the front and re-fill
				System.arraycopy(buffer, pos, buffer, 0, end - pos);
				end -= pos;
				pos = 0;
				int l = IO.readFully(in, buffer, end);
				int i = end;
				end += l;
				lf = -1;
				for (; i < end; i++) {
					if (buffer[i] == '\n') {
						lf = i;
						break;
					}
				}
				if (lf < 0) {
					lineEnd = end;
					isFullLine = false;
				} else {
					lineEnd = lf + 1;
					isFullLine = true;
				}
			}
			switch (state) {
			case MERGED:
				if (isMarker('<')) {
					pos = lineEnd;
					state = State.OURS;
				} else {
					return;
				}
				break;
			case OURS:
				if (diff3Style && isMarker('|')) {
					pos = lineEnd;
					state = State.BASE;
				} else if (isMarker('=')) {
					pos = lineEnd;
					state = State.THEIRS;
				} else {
					return;
				}
				break;
			case BASE:
				if (isMarker('=')) {
					pos = lineEnd;
					state = State.THEIRS;
				} else {
					pos = lineEnd;
					continue;
				}
				break;
			case THEIRS:
				if (isMarker('>')) {
					pos = lineEnd;
					state = State.MERGED;
				} else {
					pos = lineEnd;
					continue;
				}
				break;
			case MARKER:
			default:
				throw new IllegalStateException();
			}
			// We had a marker
			if (!isFullLine) {
				nextState = state;
				state = State.MARKER;
			}
		}
	}