umagesh     2003/04/14 08:37:48

  Modified:    .        WHATSNEW
               docs/manual/CoreTypes filterchain.html
               src/main/org/apache/tools/ant/filters HeadFilter.java
                        TailFilter.java
  Added:       src/etc/testcases/filters head-tail.xml
               src/etc/testcases/filters/expected head-tail.head.test
                        head-tail.headAllSkip.test head-tail.headLines.test
                        head-tail.headLinesSkip.test
                        head-tail.headSkip.test head-tail.headtail.test
                        head-tail.tail.test head-tail.tailAllSkip.test
                        head-tail.tailLines.test
                        head-tail.tailLinesSkip.test
                        head-tail.tailSkip.test
               src/etc/testcases/filters/input head-tail.small.test
                        head-tail.test
               src/testcases/org/apache/tools/ant/filters HeadTailTest.java
  Log:
  New "skip" attribute for HeadFilter and TailFilter
  
  PR: 18849
  
  Submitted by: [EMAIL PROTECTED] (Jan Matèrne)
  
  Revision  Changes    Path
  1.396     +3 -0      ant/WHATSNEW
  
  Index: WHATSNEW
  ===================================================================
  RCS file: /home/cvs/ant/WHATSNEW,v
  retrieving revision 1.395
  retrieving revision 1.396
  diff -u -r1.395 -r1.396
  --- WHATSNEW  14 Apr 2003 07:53:06 -0000      1.395
  +++ WHATSNEW  14 Apr 2003 15:37:42 -0000      1.396
  @@ -32,6 +32,9 @@
   
   Fixed bugs:
   -----------
  +* A new attribute named skip is added to the TailFilter and
  +  HeadFilter filter readers.
  +  
   * Expand tasks did not behave as expected with PatternSets.
   
   * <property environment=... /> now works on OS/400.
  
  
  
  1.6       +133 -2    ant/docs/manual/CoreTypes/filterchain.html
  
  Index: filterchain.html
  ===================================================================
  RCS file: /home/cvs/ant/docs/manual/CoreTypes/filterchain.html,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- filterchain.html  14 Mar 2003 13:45:16 -0000      1.5
  +++ filterchain.html  14 Apr 2003 15:37:44 -0000      1.6
  @@ -240,7 +240,14 @@
     <TR>
       <TD vAlign=top>lines</TD>
       <TD vAlign=top align="center">Number of lines to be read.
  -    Defaults to &quot;10&quot;</TD>
  +    Defaults to &quot;10&quot; <BR> A negative value means that all lines are
  +    passed (useful with <I>skip</I>)</TD>
  +    <TD vAlign=top align="center">No</TD>
  +  </TR>
  +  <TR>
  +    <TD vAlign=top>skip</TD>
  +    <TD vAlign=top align="center">Number of lines to be skipped (from the 
beginning).
  +    Defaults to &quot;0&quot;</TD>
       <TD vAlign=top align="center">No</TD>
     </TR>
   </TABLE>
  @@ -267,6 +274,19 @@
   &lt;/loadfile&gt;
   </PRE></BLOCKQUOTE>
   
  +This stores the first 15 lines, skipping the first 2 lines, of the supplied 
data
  +in the porperty ${src.file.head}. (Means: lines 3-17)
  +<BLOCKQUOTE><PRE>
  +&lt;loadfile srcfile=&quot;${src.file}&quot; 
property=&quot;${src.file.head}&quot;&gt;
  +  &lt;filterchain&gt;
  +    &lt;headfilter lines=&quot;15&quot; skip=&quot;2&quot;/&gt;
  +  &lt;/filterchain&gt;
  +&lt;/loadfile&gt;
  +</PRE></BLOCKQUOTE>
  +
  +See the testcases for more examples 
(<I>src\etc\testcases\filters\head-tail.xml</I> in the
  +source distribution).
  +
   <H3><a name="linecontains">LineContains</a></H3>
   
   This filter includes only those lines that contain all the user-specified
  @@ -602,11 +622,110 @@
     <TR>
       <TD vAlign=top>lines</TD>
       <TD vAlign=top align="center">Number of lines to be read.
  -    Defaults to &quot;10&quot;</TD>
  +    Defaults to &quot;10&quot; <BR> A negative value means that all lines are
  +    passed (useful with <I>skip</I>)</TD>
  +    <TD vAlign=top align="center">No</TD>
  +  </TR>
  +  <TR>
  +    <TD vAlign=top>skip</TD>
  +    <TD vAlign=top align="center">Number of lines to be skipped (from the 
end).
  +    Defaults to &quot;0&quot; </TD>
       <TD vAlign=top align="center">No</TD>
     </TR>
   </TABLE>
   <P>
  +
  +<H4>Background:</H4>
  +With HeadFilter and TailFilter you can extract each part of a text file you 
want.
  +This graphic shows the dependencies:
  +
  +<TABLE cellSpacing=0 cellPadding=2 border=1>
  +<TR>
  + <TH> Content </TH>
  + <TH></TH>
  + <TH></TH>
  + <TH></TH>
  + <TH> Filter </TH>
  +</TR>
  +<TR>
  + <TD> Line 1 </TD>
  + <TD rowspan="2" bgcolor="#C0C0C0">&nbsp;</TD>
  + <TD rowspan="9" bgcolor="#FF00FF">&nbsp;</TD>
  + <TD rowspan="4">&nbsp;</TD>
  + <TD rowspan="11">
  +    <TABLE>
  +    <TR>
  +     <TD bgcolor="#C0C0C0">&nbsp;</TD>
  +     <TD><PRE>&lt;filterchain>
  +    &lt;headfilter lines="2"/&gt;
  +&lt;/filterchain></PRE></TD>
  +    </TR>
  +    <TR>
  +     <TD bgcolor="#FF00FF">&nbsp;</TD>
  +     <TD><PRE>&lt;filterchain>
  +    &lt;tailfilter lines="-1" skip="2"/&gt;
  +&lt;/filterchain></PRE></TD>
  +    </TR>
  +    <TR>
  +     <TD bgcolor="#008000">&nbsp;</TD>
  +     <TD><PRE>&lt;filterchain>
  +    &lt;headfilter lines="-1" skip="2"/&gt;
  +&lt;/filterchain></PRE></TD>
  +    </TR>
  +    <TR>
  +     <TD bgcolor="#0000FF">&nbsp;</TD>
  +     <TD><PRE>&lt;filterchain>
  +    &lt;headfilter lines="-1" skip="2"/>
  +    &lt;tailfilter lines="-1" skip="2"/>
  +&lt;/filterchain></PRE></TD>
  +    </TR>
  +    <TR>
  +     <TD bgcolor="#00FF00">&nbsp;</TD>
  +     <TD><PRE>&lt;filterchain>
  +    &lt;tailfilter lines="2"/&gt;
  +&lt;/filterchain></PRE></TD>
  +    </TR>
  +    </TABLE>
  + </TD>
  +</TR>
  +<TR>
  + <TD> Line 2 </TD>
  +</TR>
  +<TR>
  + <TD> Line 3 </TD>
  + <TD rowspan="9" bgcolor="#008000">&nbsp;</TD>
  +</TR>
  +<TR>
  + <TD> Line 4 </TD>
  +</TR>
  +<TR>
  + <TD> Line 5 </TD>
  + <TD rowspan="3" bgcolor="#0000FF">&nbsp;</TD>
  +</TR>
  +<TR>
  + <TD> Lines ... </TD>
  +</TR>
  +<TR>
  + <TD> Line 95 </TD>
  +</TR>
  +<TR>
  + <TD> Line 96 </TD>
  + <TD rowspan="4">&nbsp;</TD>
  +</TR>
  +<TR>
  + <TD> Line 97 </TD>
  +</TR>
  +<TR>
  + <TD> Line 98 </TD>
  + <TD rowspan="2" bgcolor="#00FF00">&nbsp;</TD>
  +</TR>
  +<TR>
  + <TD> Line 99 </TD>
  +</TR>
  +</TABLE>
  +
  +
  +
   <H4>Examples:</H4>
   
   This stores the last 15 lines of the supplied data in the property 
${src.file.tail}
  @@ -651,6 +770,18 @@
     &lt;filterchain&gt;
       &lt;headfilter lines=&quot;15&quot;/&gt;
       &lt;tailfilter lines=&quot;5&quot;/&gt;
  +  &lt;/filterchain&gt;
  +&lt;/loadfile&gt;
  +</PRE></BLOCKQUOTE>
  +
  +
  +This stores the last 10 lines, skipping the last 2 lines, of the supplied 
data
  +in the porperty ${src.file.head}. (Means: if supplied data contains 60 lines,
  +lines 49-58 are extracted)
  +<BLOCKQUOTE><PRE>
  +&lt;loadfile srcfile=&quot;${src.file}&quot; 
property=&quot;${src.file.head}&quot;&gt;
  +  &lt;filterchain&gt;
  +    &lt;tailfilter lines=&quot;10&quot; skip=&quot;2&quot;/&gt;
     &lt;/filterchain&gt;
   &lt;/loadfile&gt;
   </PRE></BLOCKQUOTE>
  
  
  
  1.1                  ant/src/etc/testcases/filters/head-tail.xml
  
  Index: head-tail.xml
  ===================================================================
  <?xml version="1.0"?>
  <project default="cleanup" basedir=".">
  
    <target name="init">
      <mkdir dir="result" />
    </target>
  
    <target name="cleanup">
      <delete dir="result"/>
    </target>
  
    <!-- Testcases for HeadFilter -->
  
    <target name="testHead" depends="init">
      <copy file="input/head-tail.test" tofile="result/head-tail.head.test">
        <filterchain>
          <headfilter/>
        </filterchain>
      </copy>
    </target>
  
    <target name="testHeadLines" depends="init">
      <copy file="input/head-tail.test" 
tofile="result/head-tail.headLines.test">
        <filterchain>
          <headfilter lines="2"/>
        </filterchain>
      </copy>
    </target>
  
    <target name="testHeadSkip" depends="init">
      <copy file="input/head-tail.test" tofile="result/head-tail.headSkip.test">
        <filterchain>
          <headfilter skip="2"/>
        </filterchain>
      </copy>
    </target>
  
    <target name="testHeadLinesSkip" depends="init">
      <copy file="input/head-tail.test" 
tofile="result/head-tail.headLinesSkip.test">
        <filterchain>
          <headfilter lines="2" skip="2"/>
        </filterchain>
      </copy>
    </target>
  
    <target name="testHeadAllSkip" depends="init">
      <copy file="input/head-tail.test" 
tofile="result/head-tail.headAllSkip.test">
        <filterchain>
          <headfilter lines="-1" skip="2"/>
        </filterchain>
      </copy>
    </target>
  
    <!-- Testcases for TailFilter -->
  
    <target name="testTail" depends="init">
      <copy file="input/head-tail.test" tofile="result/head-tail.tail.test">
        <filterchain>
          <tailfilter/>
        </filterchain>
      </copy>
    </target>
  
    <target name="testTailLines" depends="init">
      <copy file="input/head-tail.test" 
tofile="result/head-tail.tailLines.test">
        <filterchain>
          <tailfilter lines="2"/>
        </filterchain>
      </copy>
    </target>
  
    <target name="testTailSkip" depends="init">
      <copy file="input/head-tail.test" tofile="result/head-tail.tailSkip.test">
        <filterchain>
          <tailfilter skip="2"/>
        </filterchain>
      </copy>
    </target>
  
    <target name="testTailLinesSkip" depends="init">
      <copy file="input/head-tail.test" 
tofile="result/head-tail.tailLinesSkip.test">
        <filterchain>
          <tailfilter lines="2" skip="2"/>
        </filterchain>
      </copy>
    </target>
  
    <target name="testTailAllSkip" depends="init">
      <copy file="input/head-tail.test" 
tofile="result/head-tail.tailAllSkip.test">
        <filterchain>
          <tailfilter lines="-1" skip="2"/>
        </filterchain>
      </copy>
    </target>
  
    <!-- Testcases for combined scenarios -->
  
    <target name="testHeadTail" depends="init">
      <copy file="input/head-tail.test" tofile="result/head-tail.headtail.test">
        <filterchain>
          <headfilter lines="4"/>
          <tailfilter lines="2"/>
        </filterchain>
      </copy>
    </target>
  
  </project>
  
  
  
  1.1                  
ant/src/etc/testcases/filters/expected/head-tail.head.test
  
  Index: head-tail.head.test
  ===================================================================
  Line  1
  Line  2
  Line  3
  Line  4
  Line  5
  Line  6
  Line  7
  Line  8
  Line  9
  Line 10
  
  
  
  1.1                  
ant/src/etc/testcases/filters/expected/head-tail.headAllSkip.test
  
  Index: head-tail.headAllSkip.test
  ===================================================================
  Line  3
  Line  4
  Line  5
  Line  6
  Line  7
  Line  8
  Line  9
  Line 10
  Line 11
  Line 12
  Line 13
  Line 14
  Line 15
  Line 16
  Line 17
  Line 18
  Line 19
  Line 20
  Line 21
  Line 22
  Line 23
  Line 24
  Line 25
  Line 26
  Line 27
  Line 28
  Line 29
  Line 30
  Line 31
  Line 32
  Line 33
  Line 34
  Line 35
  Line 36
  Line 37
  Line 38
  Line 39
  Line 40
  Line 41
  Line 42
  Line 43
  Line 44
  Line 45
  Line 46
  Line 47
  Line 48
  Line 49
  Line 50
  Line 51
  Line 52
  Line 53
  Line 54
  Line 55
  Line 56
  Line 57
  Line 58
  Line 59
  Line 60
  
  
  
  1.1                  
ant/src/etc/testcases/filters/expected/head-tail.headLines.test
  
  Index: head-tail.headLines.test
  ===================================================================
  Line  1
  Line  2
  
  
  
  1.1                  
ant/src/etc/testcases/filters/expected/head-tail.headLinesSkip.test
  
  Index: head-tail.headLinesSkip.test
  ===================================================================
  Line  3
  Line  4
  
  
  
  1.1                  
ant/src/etc/testcases/filters/expected/head-tail.headSkip.test
  
  Index: head-tail.headSkip.test
  ===================================================================
  Line  3
  Line  4
  Line  5
  Line  6
  Line  7
  Line  8
  Line  9
  Line 10
  Line 11
  Line 12
  
  
  
  1.1                  
ant/src/etc/testcases/filters/expected/head-tail.headtail.test
  
  Index: head-tail.headtail.test
  ===================================================================
  Line  4
  
  
  
  1.1                  
ant/src/etc/testcases/filters/expected/head-tail.tail.test
  
  Index: head-tail.tail.test
  ===================================================================
  Line 51
  Line 52
  Line 53
  Line 54
  Line 55
  Line 56
  Line 57
  Line 58
  Line 59
  Line 60
  
  
  
  1.1                  
ant/src/etc/testcases/filters/expected/head-tail.tailAllSkip.test
  
  Index: head-tail.tailAllSkip.test
  ===================================================================
  Line  1
  Line  2
  Line  3
  Line  4
  Line  5
  Line  6
  Line  7
  Line  8
  Line  9
  Line 10
  Line 11
  Line 12
  Line 13
  Line 14
  Line 15
  Line 16
  Line 17
  Line 18
  Line 19
  Line 20
  Line 21
  Line 22
  Line 23
  Line 24
  Line 25
  Line 26
  Line 27
  Line 28
  Line 29
  Line 30
  Line 31
  Line 32
  Line 33
  Line 34
  Line 35
  Line 36
  Line 37
  Line 38
  Line 39
  Line 40
  Line 41
  Line 42
  Line 43
  Line 44
  Line 45
  Line 46
  Line 47
  Line 48
  Line 49
  Line 50
  Line 51
  Line 52
  Line 53
  Line 54
  Line 55
  Line 56
  Line 57
  Line 58
  
  
  
  1.1                  
ant/src/etc/testcases/filters/expected/head-tail.tailLines.test
  
  Index: head-tail.tailLines.test
  ===================================================================
  Line 59
  Line 60
  
  
  
  1.1                  
ant/src/etc/testcases/filters/expected/head-tail.tailLinesSkip.test
  
  Index: head-tail.tailLinesSkip.test
  ===================================================================
  Line 57
  Line 58
  
  
  
  1.1                  
ant/src/etc/testcases/filters/expected/head-tail.tailSkip.test
  
  Index: head-tail.tailSkip.test
  ===================================================================
  Line 49
  Line 50
  Line 51
  Line 52
  Line 53
  Line 54
  Line 55
  Line 56
  Line 57
  Line 58
  
  
  
  1.1                  ant/src/etc/testcases/filters/input/head-tail.small.test
  
  Index: head-tail.small.test
  ===================================================================
  Line  1
  Line  2
  Line  3
  Line  4
  Line  5
  
  
  1.1                  ant/src/etc/testcases/filters/input/head-tail.test
  
  Index: head-tail.test
  ===================================================================
  Line  1
  Line  2
  Line  3
  Line  4
  Line  5
  Line  6
  Line  7
  Line  8
  Line  9
  Line 10
  Line 11
  Line 12
  Line 13
  Line 14
  Line 15
  Line 16
  Line 17
  Line 18
  Line 19
  Line 20
  Line 21
  Line 22
  Line 23
  Line 24
  Line 25
  Line 26
  Line 27
  Line 28
  Line 29
  Line 30
  Line 31
  Line 32
  Line 33
  Line 34
  Line 35
  Line 36
  Line 37
  Line 38
  Line 39
  Line 40
  Line 41
  Line 42
  Line 43
  Line 44
  Line 45
  Line 46
  Line 47
  Line 48
  Line 49
  Line 50
  Line 51
  Line 52
  Line 53
  Line 54
  Line 55
  Line 56
  Line 57
  Line 58
  Line 59
  Line 60
  
  
  1.8       +46 -11    ant/src/main/org/apache/tools/ant/filters/HeadFilter.java
  
  Index: HeadFilter.java
  ===================================================================
  RCS file: 
/home/cvs/ant/src/main/org/apache/tools/ant/filters/HeadFilter.java,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- HeadFilter.java   10 Feb 2003 14:13:32 -0000      1.7
  +++ HeadFilter.java   14 Apr 2003 15:37:47 -0000      1.8
  @@ -1,7 +1,7 @@
   /*
    * The Apache Software License, Version 1.1
    *
  - * Copyright (c) 2002 The Apache Software Foundation.  All rights
  + * Copyright (c) 2002-2003 The Apache Software Foundation.  All rights
    * reserved.
    *
    * Redistribution and use in source and binary forms, with or without
  @@ -76,15 +76,21 @@
       /** Parameter name for the number of lines to be returned. */
       private static final String LINES_KEY = "lines";
   
  +    /** Parameter name for the number of lines to be skipped. */
  +    private static final String SKIP_KEY = "skip";
  +
       /** Number of lines currently read in. */
       private long linesRead = 0;
   
       /** Number of lines to be returned in the filtered stream. */
       private long lines = 10;
   
  +    /** Number of lines to be skipped. */
  +    private long skip = 0;
  +
       /**
        * Constructor for "dummy" instances.
  -     * 
  +     *
        * @see BaseFilterReader#BaseFilterReader()
        */
       public HeadFilter() {
  @@ -104,14 +110,14 @@
       /**
        * Returns the next character in the filtered stream. If the desired
        * number of lines have already been read, the resulting stream is
  -     * effectively at an end. Otherwise, the next character from the 
  +     * effectively at an end. Otherwise, the next character from the
        * underlying stream is read and returned.
  -     * 
  +     *
        * @return the next character in the resulting stream, or -1
        * if the end of the resulting stream has been reached
  -     * 
  +     *
        * @exception IOException if the underlying stream throws an IOException
  -     * during reading     
  +     * during reading
        */
       public final int read() throws IOException {
           if (!getInitialized()) {
  @@ -121,7 +127,13 @@
   
           int ch = -1;
   
  -        if (linesRead < lines) {
  +        // skip the lines (if set)
  +        while (skip > 0) {
  +            for (int tmp = in.read(); tmp != '\n'; tmp = in.read());
  +            skip--;
  +        }
  +
  +        if ( (linesRead < lines) || (lines < 0) ){
   
               ch = in.read();
   
  @@ -135,7 +147,7 @@
   
       /**
        * Sets the number of lines to be returned in the filtered stream.
  -     * 
  +     *
        * @param lines the number of lines to be returned in the filtered stream
        */
       public final void setLines(final long lines) {
  @@ -144,7 +156,7 @@
   
       /**
        * Returns the number of lines to be returned in the filtered stream.
  -     * 
  +     *
        * @return the number of lines to be returned in the filtered stream
        */
       private final long getLines() {
  @@ -152,18 +164,37 @@
       }
   
       /**
  +     * Sets the number of lines to be skipped in the filtered stream.
  +     *
  +     * @param lines the number of lines to be skipped in the filtered stream
  +     */
  +    public final void setSkip(final long skip) {
  +        this.skip = skip;
  +    }
  +
  +    /**
  +     * Returns the number of lines to be skipped in the filtered stream.
  +     *
  +     * @return the number of lines to be skipped in the filtered stream
  +     */
  +    private final long getSkip() {
  +        return skip;
  +    }
  +
  +    /**
        * Creates a new HeadFilter using the passed in
        * Reader for instantiation.
  -     * 
  +     *
        * @param rdr A Reader object providing the underlying stream.
        *            Must not be <code>null</code>.
  -     * 
  +     *
        * @return a new filter based on this configuration, but filtering
        *         the specified reader
        */
       public final Reader chain(final Reader rdr) {
           HeadFilter newFilter = new HeadFilter(rdr);
           newFilter.setLines(getLines());
  +        newFilter.setSkip(getSkip());
           newFilter.setInitialized(true);
           return newFilter;
       }
  @@ -178,6 +209,10 @@
               for (int i = 0; i < params.length; i++) {
                   if (LINES_KEY.equals(params[i].getName())) {
                       lines = new Long(params[i].getValue()).longValue();
  +                    break;
  +                }
  +                if (SKIP_KEY.equals(params[i].getName())) {
  +                    skip = new Long(params[i].getValue()).longValue();
                       break;
                   }
               }
  
  
  
  1.8       +69 -18    ant/src/main/org/apache/tools/ant/filters/TailFilter.java
  
  Index: TailFilter.java
  ===================================================================
  RCS file: 
/home/cvs/ant/src/main/org/apache/tools/ant/filters/TailFilter.java,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- TailFilter.java   10 Feb 2003 14:13:32 -0000      1.7
  +++ TailFilter.java   14 Apr 2003 15:37:47 -0000      1.8
  @@ -1,7 +1,7 @@
   /*
    * The Apache Software License, Version 1.1
    *
  - * Copyright (c) 2002 The Apache Software Foundation.  All rights
  + * Copyright (c) 2002-2003 The Apache Software Foundation.  All rights
    * reserved.
    *
    * Redistribution and use in source and binary forms, with or without
  @@ -78,12 +78,18 @@
       /** Parameter name for the number of lines to be returned. */
       private static final String LINES_KEY = "lines";
   
  +    /** Parameter name for the number of lines to be skipped. */
  +    private static final String SKIP_KEY = "skip";
  +
       /** Number of lines currently read in. */
       private long linesRead = 0;
   
       /** Number of lines to be returned in the filtered stream. */
       private long lines = 10;
   
  +    /** Number of lines to be skipped. */
  +    private long skip = 0;
  +
       /** Buffer to hold in characters read ahead. */
       private char[] buffer = new char[4096];
   
  @@ -98,7 +104,7 @@
   
       /**
        * Constructor for "dummy" instances.
  -     * 
  +     *
        * @see BaseFilterReader#BaseFilterReader()
        */
       public TailFilter() {
  @@ -121,12 +127,12 @@
        * Otherwise, the stream is read to the end and buffered (with the buffer
        * growing as necessary), then the appropriate position in the buffer is
        * set to read from.
  -     * 
  +     *
        * @return the next character in the resulting stream, or -1
        * if the end of the resulting stream has been reached
  -     * 
  +     *
        * @exception IOException if the underlying stream throws an IOException
  -     * during reading     
  +     * during reading
        */
       public final int read() throws IOException {
           if (!getInitialized()) {
  @@ -152,16 +158,18 @@
                       }
                   }
   
  -                if (ch == '\n' || ch == -1) {
  -                    ++linesRead;
  -
  -                    if (linesRead == lines) {
  -                        int i = 0;
  -                        for (i = returnedCharPos + 1;
  -                            buffer[i] != 0 && buffer[i] != '\n'; i++) {
  +                if (lines > 0) {
  +                    if (ch == '\n' || ch == -1) {
  +                        ++linesRead;
  +
  +                        if ((linesRead == lines + skip)) {
  +                            int i = 0;
  +                            for (i = returnedCharPos + 1;
  +                                buffer[i] != 0 && buffer[i] != '\n'; i++) {
  +                            }
  +                            returnedCharPos = i;
  +                            --linesRead;
                           }
  -                        returnedCharPos = i;
  -                        --linesRead;
                       }
                   }
                   if (ch == -1) {
  @@ -174,6 +182,26 @@
               completedReadAhead = true;
           }
   
  +        // Because the complete stream is read into the buffer I can delete
  +        // the "skip lines" from back to the beginning.
  +        if (skip > 0) {
  +            // searching...
  +            int i;
  +            for (i = buffer.length - 1; skip > 0; i--) {
  +                if (buffer[i]=='\n') {
  +                    skip--;
  +                }
  +            }
  +
  +           // cut the buffer to the new length
  +           char[] newBuffer = new char[i];
  +           System.arraycopy(buffer, 0, newBuffer, 0, i);
  +           buffer = newBuffer;
  +
  +           // don´t forget to set the "lastposition" new
  +           bufferPos = i;
  +        }
  +
           ++returnedCharPos;
           if (returnedCharPos >= bufferPos) {
               return -1;
  @@ -184,7 +212,7 @@
   
       /**
        * Sets the number of lines to be returned in the filtered stream.
  -     * 
  +     *
        * @param lines the number of lines to be returned in the filtered stream
        */
       public final void setLines(final long lines) {
  @@ -193,7 +221,7 @@
   
       /**
        * Returns the number of lines to be returned in the filtered stream.
  -     * 
  +     *
        * @return the number of lines to be returned in the filtered stream
        */
       private final long getLines() {
  @@ -201,18 +229,37 @@
       }
   
       /**
  +     * Sets the number of lines to be skipped in the filtered stream.
  +     *
  +     * @param lines the number of lines to be skipped in the filtered stream
  +     */
  +    public final void setSkip(final long skip) {
  +        this.skip = skip;
  +    }
  +
  +    /**
  +     * Returns the number of lines to be skipped in the filtered stream.
  +     *
  +     * @return the number of lines to be skipped in the filtered stream
  +     */
  +    private final long getSkip() {
  +        return skip;
  +    }
  +
  +    /**
        * Creates a new TailFilter using the passed in
        * Reader for instantiation.
  -     * 
  +     *
        * @param rdr A Reader object providing the underlying stream.
        *            Must not be <code>null</code>.
  -     * 
  +     *
        * @return a new filter based on this configuration, but filtering
        *         the specified reader
        */
       public final Reader chain(final Reader rdr) {
           TailFilter newFilter = new TailFilter(rdr);
           newFilter.setLines(getLines());
  +        newFilter.setSkip(getSkip());
           newFilter.setInitialized(true);
           return newFilter;
       }
  @@ -227,6 +274,10 @@
               for (int i = 0; i < params.length; i++) {
                   if (LINES_KEY.equals(params[i].getName())) {
                       setLines(new Long(params[i].getValue()).longValue());
  +                    break;
  +                }
  +                if (SKIP_KEY.equals(params[i].getName())) {
  +                    skip = new Long(params[i].getValue()).longValue();
                       break;
                   }
               }
  
  
  
  1.1                  
ant/src/testcases/org/apache/tools/ant/filters/HeadTailTest.java
  
  Index: HeadTailTest.java
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2003 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "Ant" and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact [EMAIL PROTECTED]
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  package org.apache.tools.ant.filters;
  
  import java.io.File;
  import java.io.IOException;
  
  import org.apache.tools.ant.BuildFileTest;
  import org.apache.tools.ant.util.FileUtils;
  
  /** JUnit Testcases for TailFilter and HeadFilter
   * @author <a href="mailto:[EMAIL PROTECTED]">Jan Matèrne</a>
   */
  /* I wrote the testcases in one java file because I want also to test the
   * combined behaviour (see end of the class).
  */
  public class HeadTailTest extends BuildFileTest {
  
      public HeadTailTest(String name) {
          super(name);
      }
  
      public void setUp() {
          configureProject("src/etc/testcases/filters/head-tail.xml");
      }
  
      public void tearDown() {
          executeTarget("cleanup");
      }
  
      public void testHead() throws IOException {
          executeTarget("testHead");
          File expected = 
getProject().resolveFile("expected/head-tail.head.test");
          File result = getProject().resolveFile("result/head-tail.head.test");
          FileUtils fu = FileUtils.newFileUtils();
          assertTrue("testHead: Result not like expected", 
fu.contentEquals(expected, result));
      }
  
      public void testHeadLines() throws IOException {
          executeTarget("testHeadLines");
          File expected = 
getProject().resolveFile("expected/head-tail.headLines.test");
          File result = 
getProject().resolveFile("result/head-tail.headLines.test");
          FileUtils fu = FileUtils.newFileUtils();
          assertTrue("testHeadLines: Result not like expected", 
fu.contentEquals(expected, result));
      }
  
      public void testHeadSkip() throws IOException {
          executeTarget("testHeadSkip");
          File expected = 
getProject().resolveFile("expected/head-tail.headSkip.test");
          File result = 
getProject().resolveFile("result/head-tail.headSkip.test");
          FileUtils fu = FileUtils.newFileUtils();
          assertTrue("testHeadSkip: Result not like expected", 
fu.contentEquals(expected, result));
      }
  
      public void testHeadLinesSkip() throws IOException {
          executeTarget("testHeadLinesSkip");
          File expected = 
getProject().resolveFile("expected/head-tail.headLinesSkip.test");
          File result = 
getProject().resolveFile("result/head-tail.headLinesSkip.test");
          FileUtils fu = FileUtils.newFileUtils();
          assertTrue("testHeadLinesSkip: Result not like expected", 
fu.contentEquals(expected, result));
      }
  
      public void testTail() throws IOException {
          executeTarget("testTail");
          File expected = 
getProject().resolveFile("expected/head-tail.tail.test");
          File result = getProject().resolveFile("result/head-tail.tail.test");
          FileUtils fu = FileUtils.newFileUtils();
          assertTrue("testTail: Result not like expected", 
fu.contentEquals(expected, result));
      }
  
      public void testTailLines() throws IOException {
          executeTarget("testTailLines");
          File expected = 
getProject().resolveFile("expected/head-tail.tailLines.test");
          File result = 
getProject().resolveFile("result/head-tail.tailLines.test");
          FileUtils fu = FileUtils.newFileUtils();
          assertTrue("testTailLines: Result not like expected", 
fu.contentEquals(expected, result));
      }
  
      public void testTailSkip() throws IOException {
          executeTarget("testTailSkip");
          File expected = 
getProject().resolveFile("expected/head-tail.tailSkip.test");
          File result = 
getProject().resolveFile("result/head-tail.tailSkip.test");
          FileUtils fu = FileUtils.newFileUtils();
          assertTrue("testTailSkip: Result not like expected", 
fu.contentEquals(expected, result));
      }
  
      public void testTailLinesSkip() throws IOException {
          executeTarget("testTailLinesSkip");
          File expected = 
getProject().resolveFile("expected/head-tail.tailLinesSkip.test");
          File result = 
getProject().resolveFile("result/head-tail.tailLinesSkip.test");
          FileUtils fu = FileUtils.newFileUtils();
          assertTrue("testTailLinesSkip: Result not like expected", 
fu.contentEquals(expected, result));
      }
  
      public void testHeadTail() throws IOException {
          executeTarget("testHeadTail");
          File expected = 
getProject().resolveFile("expected/head-tail.headTail.test");
          File result = 
getProject().resolveFile("result/head-tail.headTail.test");
          FileUtils fu = FileUtils.newFileUtils();
          assertTrue("testHeadTail: Result not like expected", 
fu.contentEquals(expected, result));
      }
  
  }
  
  
  

Reply via email to