You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pdfbox.apache.org by le...@apache.org on 2022/05/15 08:27:08 UTC

svn commit: r1900912 - in /pdfbox/trunk/fontbox/src: main/java/org/apache/fontbox/ttf/ test/java/org/apache/fontbox/ttf/

Author: lehmi
Date: Sun May 15 08:27:08 2022
New Revision: 1900912

URL: http://svn.apache.org/viewvc?rev=1900912&view=rev
Log:
PDFBOX-5434: replace org.apache.fontbox.ttf.BufferedRandomAccessFile with org.apache.pdfbox.io.RandomAccessReadBufferedFile

Removed:
    pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/ttf/BufferedRandomAccessFile.java
    pdfbox/trunk/fontbox/src/test/java/org/apache/fontbox/ttf/BufferedRandomAccessFileTest.java
Modified:
    pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/ttf/RAFDataStream.java
    pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/ttf/TTFParser.java
    pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/ttf/TrueTypeCollection.java
    pdfbox/trunk/fontbox/src/test/java/org/apache/fontbox/ttf/RAFDataStreamTest.java

Modified: pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/ttf/RAFDataStream.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/ttf/RAFDataStream.java?rev=1900912&r1=1900911&r2=1900912&view=diff
==============================================================================
--- pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/ttf/RAFDataStream.java (original)
+++ pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/ttf/RAFDataStream.java Sun May 15 08:27:08 2022
@@ -20,47 +20,42 @@ import java.io.File;
 import java.io.FileInputStream;
 import java.io.IOException;
 import java.io.InputStream;
-import java.io.RandomAccessFile;
+
+import org.apache.pdfbox.io.RandomAccessRead;
+import org.apache.pdfbox.io.RandomAccessReadBufferedFile;
 
 /**
- * An implementation of the TTFDataStream that goes against a RAF.
+ * An implementation of the TTFDataStream using RandomAccessReadBufferedFile .
  * 
  * @author Ben Litchfield
  */
 class RAFDataStream extends TTFDataStream 
 {
-    private RandomAccessFile raf = null;
-    private File ttfFile = null;
-    private static final int BUFFERSIZE = 16384;
+    private final RandomAccessRead randomAccessRead;
+    private final File ttfFile;
     
     /**
      * Constructor.
      * 
-     * @param name The raf file.
-     * @param mode The mode to open the RAF.
-     * 
-     * @throws IOException If there is a problem creating the RAF.
+     * @param name The name of the file to be read.
      * 
-     * @see RandomAccessFile#RandomAccessFile( String, String )
+     * @throws IOException If there is a problem creating the RandomAccessReadBufferedFile.
      */
     RAFDataStream(String name, String mode) throws IOException
     {
-        this( new File( name ), mode );
+        this(new File(name));
     }
-    
+
     /**
      * Constructor.
      * 
-     * @param file The raf file.
-     * @param mode The mode to open the RAF.
+     * @param file The file to be read.
      * 
-     * @throws IOException If there is a problem creating the RAF.
-     * 
-     * @see RandomAccessFile#RandomAccessFile( File, String )
+     * @throws IOException If there is a problem creating the RandomAccessReadBufferedFile.
      */
-    RAFDataStream(File file, String mode) throws IOException
+    RAFDataStream(File file) throws IOException
     {
-        raf = new BufferedRandomAccessFile(file, mode, BUFFERSIZE);
+        randomAccessRead = new RandomAccessReadBufferedFile(file);
         ttfFile = file;
     }
     
@@ -69,12 +64,11 @@ class RAFDataStream extends TTFDataStrea
      * 
      * @return An signed short.
      * @throws IOException If there is an error reading the data.
-     * @see RandomAccessFile#readShort()
      */
     @Override
     public short readSignedShort() throws IOException
     {
-        return raf.readShort();
+        return (short) readUnsignedShort();
     }
     
     /**
@@ -85,7 +79,7 @@ class RAFDataStream extends TTFDataStrea
     @Override
     public long getCurrentPosition() throws IOException
     {
-        return raf.getFilePointer();
+        return randomAccessRead.getPosition();
     }
     
     /**
@@ -96,23 +90,18 @@ class RAFDataStream extends TTFDataStrea
     @Override
     public void close() throws IOException
     {
-        if (raf != null)
-        {
-            raf.close();
-            raf = null;
-        }
+        randomAccessRead.close();
     }
     
     /**
      * Read an unsigned byte.
      * @return An unsigned byte.
      * @throws IOException If there is an error reading the data.
-     * @see RandomAccessFile#read()
      */
     @Override
     public int read() throws IOException
     {
-        return raf.read();
+        return randomAccessRead.read();
     }
     
     /**
@@ -120,12 +109,12 @@ class RAFDataStream extends TTFDataStrea
      * 
      * @return An unsigned short.
      * @throws IOException If there is an error reading the data.
-     * @see RandomAccessFile#readUnsignedShort()
      */
-    @Override
     public int readUnsignedShort() throws IOException
     {
-        return raf.readUnsignedShort();
+        int b1 = read();
+        int b2 = read();
+        return (b1 << 8) + b2;
     }
     
     /**
@@ -133,14 +122,27 @@ class RAFDataStream extends TTFDataStrea
      * 
      * @return eight bytes interpreted as a long.
      * @throws IOException If there is an error reading the data.
-     * @see RandomAccessFile#readLong()    
      */
     @Override
-    public long readLong() throws IOException
+    public final long readLong() throws IOException
     {
-        return raf.readLong();
+        return ((long) (readInt()) << 32) + (readInt() & 0xFFFFFFFFL);
+    }
+
+    /**
+     * Read a signed 32-bit integer.
+     * 
+     * @return 4 bytes interpreted as a int.
+     * @throws IOException If there is an error reading the data.
+     */
+    private long readInt() throws IOException
+    {
+        int b1 = read();
+        int b2 = read();
+        int b3 = read();
+        int b4 = read();
+        return (b1 << 24) + (b2 << 16) + (b3 << 8) + b4;
     }
-    
     /**
      * Seek into the datasource.
      * 
@@ -150,7 +152,7 @@ class RAFDataStream extends TTFDataStrea
     @Override
     public void seek(long pos) throws IOException
     {
-        raf.seek( pos );
+        randomAccessRead.seek(pos);
     }
     
     /**
@@ -167,7 +169,7 @@ class RAFDataStream extends TTFDataStrea
     @Override
     public int read(byte[] b, int off, int len) throws IOException
     {
-        return raf.read(b, off, len);
+        return randomAccessRead.read(b, off, len);
     }
     
     /**

Modified: pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/ttf/TTFParser.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/ttf/TTFParser.java?rev=1900912&r1=1900911&r2=1900912&view=diff
==============================================================================
--- pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/ttf/TTFParser.java (original)
+++ pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/ttf/TTFParser.java Sun May 15 08:27:08 2022
@@ -85,7 +85,7 @@ public class TTFParser
      */
     public TrueTypeFont parse(File ttfFile) throws IOException
     {
-        RAFDataStream raf = new RAFDataStream(ttfFile, "r");
+        RAFDataStream raf = new RAFDataStream(ttfFile);
         try
         {
             return parse(raf);

Modified: pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/ttf/TrueTypeCollection.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/ttf/TrueTypeCollection.java?rev=1900912&r1=1900911&r2=1900912&view=diff
==============================================================================
--- pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/ttf/TrueTypeCollection.java (original)
+++ pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/ttf/TrueTypeCollection.java Sun May 15 08:27:08 2022
@@ -42,7 +42,7 @@ public class TrueTypeCollection implemen
      */
     public TrueTypeCollection(File file) throws IOException
     {
-        this(new RAFDataStream(file, "r"));
+        this(new RAFDataStream(file));
     }
 
     /**

Modified: pdfbox/trunk/fontbox/src/test/java/org/apache/fontbox/ttf/RAFDataStreamTest.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/fontbox/src/test/java/org/apache/fontbox/ttf/RAFDataStreamTest.java?rev=1900912&r1=1900911&r2=1900912&view=diff
==============================================================================
--- pdfbox/trunk/fontbox/src/test/java/org/apache/fontbox/ttf/RAFDataStreamTest.java (original)
+++ pdfbox/trunk/fontbox/src/test/java/org/apache/fontbox/ttf/RAFDataStreamTest.java Sun May 15 08:27:08 2022
@@ -16,7 +16,15 @@
  */
 package org.apache.fontbox.ttf;
 
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
 import java.io.IOException;
+import java.io.OutputStream;
+import java.nio.charset.StandardCharsets;
+
 import org.junit.jupiter.api.Test;
 
 /**
@@ -37,4 +45,127 @@ class RAFDataStreamTest
         raf.close();
         raf.close();
     }
+
+    /**
+     * Before solving PDFBOX-3605, this test never ended.
+     * 
+     * @throws IOException
+     */
+    @Test
+    void ensureReadFinishes() throws IOException
+    {
+        final File file = File.createTempFile("apache-pdfbox", ".dat");
+
+        try (OutputStream outputStream = new BufferedOutputStream(new FileOutputStream(file)))
+        {
+            final String content = "1234567890";
+            outputStream.write(content.getBytes(StandardCharsets.UTF_8));
+            outputStream.flush();
+        }
+
+        final byte[] readBuffer = new byte[2];
+        try (RAFDataStream braf = new RAFDataStream(file))
+        {
+            int amountRead;
+            int totalAmountRead = 0;
+            while ((amountRead = braf.read(readBuffer, 0, 2)) != -1)
+            {
+                totalAmountRead += amountRead;
+            }
+            assertEquals(10, totalAmountRead);
+        }
+        file.delete();
+    }
+
+    /**
+     * Test several reading patterns, both reading within a buffer and across buffer.
+     *
+     * @throws IOException
+     */
+    @Test
+    void testReadBuffer() throws IOException
+    {
+        final File file = File.createTempFile("apache-pdfbox", ".dat");
+
+        try (OutputStream outputStream = new BufferedOutputStream(new FileOutputStream(file)))
+        {
+            final String content = "012345678A012345678B012345678C012345678D";
+            outputStream.write(content.getBytes(StandardCharsets.UTF_8));
+            outputStream.flush();
+        }
+
+        final byte[] readBuffer = new byte[40];
+        try (RAFDataStream braf = new RAFDataStream(file))
+        {
+            int count = 4;
+            int bytesRead = braf.read(readBuffer, 0, count);
+            assertEquals(4, braf.getCurrentPosition());
+            assertEquals(count, bytesRead);
+            assertEquals("0123", new String(readBuffer, 0, count));
+
+            count = 6;
+            bytesRead = braf.read(readBuffer, 0, count);
+            assertEquals(10, braf.getCurrentPosition());
+            assertEquals(count, bytesRead);
+            assertEquals("45678A", new String(readBuffer, 0, count));
+
+            count = 10;
+            bytesRead = braf.read(readBuffer, 0, count);
+            assertEquals(20, braf.getCurrentPosition());
+            assertEquals(count, bytesRead);
+            assertEquals("012345678B", new String(readBuffer, 0, count));
+
+            count = 10;
+            bytesRead = braf.read(readBuffer, 0, count);
+            assertEquals(30, braf.getCurrentPosition());
+            assertEquals(count, bytesRead);
+            assertEquals("012345678C", new String(readBuffer, 0, count));
+
+            count = 10;
+            bytesRead = braf.read(readBuffer, 0, count);
+            assertEquals(40, braf.getCurrentPosition());
+            assertEquals(count, bytesRead);
+            assertEquals("012345678D", new String(readBuffer, 0, count));
+
+            assertEquals(-1, braf.read());
+
+            braf.seek(0);
+            braf.read(readBuffer, 0, 7);
+            assertEquals(7, braf.getCurrentPosition());
+
+            count = 16;
+            bytesRead = braf.read(readBuffer, 0, count);
+            assertEquals(23, braf.getCurrentPosition());
+            assertEquals(count, bytesRead);
+            assertEquals("78A012345678B012", new String(readBuffer, 0, count));
+
+            bytesRead = braf.read(readBuffer, 0, 99);
+            assertEquals(40, braf.getCurrentPosition());
+            assertEquals(17, bytesRead);
+            assertEquals("345678C012345678D", new String(readBuffer, 0, 17));
+
+            assertEquals(-1, braf.read());
+
+            braf.seek(0);
+            braf.read(readBuffer, 0, 7);
+            assertEquals(7, braf.getCurrentPosition());
+
+            count = 23;
+            bytesRead = braf.read(readBuffer, 0, count);
+            assertEquals(30, braf.getCurrentPosition());
+            assertEquals(count, bytesRead);
+            assertEquals("78A012345678B012345678C", new String(readBuffer, 0, count));
+
+            braf.seek(0);
+            braf.read(readBuffer, 0, 10);
+            assertEquals(10, braf.getCurrentPosition());
+            count = 23;
+            bytesRead = braf.read(readBuffer, 0, count);
+            assertEquals(33, braf.getCurrentPosition());
+            assertEquals(count, bytesRead);
+            assertEquals("012345678B012345678C012", new String(readBuffer, 0, count));
+        }
+        file.delete();
+    }
+
 }