/******************************************************************************* * Copyright (c) 2009, 2010 Sven Kiera * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html *******************************************************************************/ package org.phpsrc.eclipse.pti.core.php.source; import java.io.IOException; import java.io.InputStreamReader; import java.util.ArrayList; import org.eclipse.core.resources.IFile; import org.eclipse.core.runtime.Assert; import org.eclipse.core.runtime.CoreException; import org.eclipse.dltk.core.ISourceModule; import org.phpsrc.eclipse.pti.core.PHPToolkitUtil; public class PHPSourceFile implements ISourceFile { private final IFile file; private ArrayList<Integer> lineStarts; private ArrayList<Integer> lineEnds; private ArrayList<Integer> lineStartTabCount; private int linesCount; /** * @since 1.4.0 */ private ISourceModule module; public PHPSourceFile(IFile file) throws CoreException, IOException { Assert.isNotNull(file); this.file = file; determineLinePositions(file); module = PHPToolkitUtil.getSourceModule(file); } private void determineLinePositions(IFile file) throws CoreException, IOException { lineStarts = new ArrayList<Integer>(); lineEnds = new ArrayList<Integer>(); lineStartTabCount = new ArrayList<Integer>(); InputStreamReader isr; isr = new InputStreamReader(file.getContents()); int last = -1; int i = 0; int c; boolean countTabs = true; int tabCount = 0; while ((c = isr.read()) != -1) { if ((char) c == '\n') { lineStarts.add(new Integer(last + 1)); lineEnds.add(new Integer(i)); lineStartTabCount.add(new Integer(tabCount)); ++linesCount; last = i; countTabs = true; tabCount = 0; } else if (countTabs && (char) c == '\t') { ++tabCount; } else if ((char) c != ' ') { countTabs = false; } i++; } lineStarts.add(new Integer(last + 1)); lineEnds.add(new Integer(i)); lineStartTabCount.add(new Integer(tabCount)); ++linesCount; } public int lineStart(int lineNumber) throws IndexOutOfBoundsException { return lineStarts.get(lineNumber - 1); } public int lineEnd(int lineNumber) throws IndexOutOfBoundsException { return lineEnds.get(lineNumber - 1); } public int lineStartTabCount(int lineNumber) throws IndexOutOfBoundsException { return lineStartTabCount.get(lineNumber - 1); } public IFile getFile() { return file; } public int getNumberOfLines() { return linesCount; } /** * @since 1.4.0 */ public ISourceModule getSourceModule() { return module; } /** * @since 1.4.0 */ public int findLineNumberForOffset(int offset) throws IndexOutOfBoundsException { if (offset < 0) throw new IndexOutOfBoundsException(); if (offset == 0) return 1; int count = lineEnds.size(); for (int i = 0; i < count; ++i) { int end = lineEnds.get(i); if (end > offset) return i + 1; } throw new IndexOutOfBoundsException(); } }