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 2024/12/18 10:18:22 UTC

svn commit: r1922579 - in /pdfbox/branches/3.0/fontbox/src/main/java/org/apache/fontbox/cmap: CMap.java CMapStrings.java

Author: lehmi
Date: Wed Dec 18 10:18:22 2024
New Revision: 1922579

URL: http://svn.apache.org/viewvc?rev=1922579&view=rev
Log:
PDFBOX-5902: provide singleton instances for heavily used Integer and byte[] values to avoid multiple instances

Modified:
    pdfbox/branches/3.0/fontbox/src/main/java/org/apache/fontbox/cmap/CMap.java
    pdfbox/branches/3.0/fontbox/src/main/java/org/apache/fontbox/cmap/CMapStrings.java

Modified: pdfbox/branches/3.0/fontbox/src/main/java/org/apache/fontbox/cmap/CMap.java
URL: http://svn.apache.org/viewvc/pdfbox/branches/3.0/fontbox/src/main/java/org/apache/fontbox/cmap/CMap.java?rev=1922579&r1=1922578&r2=1922579&view=diff
==============================================================================
--- pdfbox/branches/3.0/fontbox/src/main/java/org/apache/fontbox/cmap/CMap.java (original)
+++ pdfbox/branches/3.0/fontbox/src/main/java/org/apache/fontbox/cmap/CMap.java Wed Dec 18 10:18:22 2024
@@ -334,25 +334,6 @@ public class CMap
     }
 
     /**
-     * Convert the given part of a byte array to an integer.
-     * 
-     * @param data   the byte array
-     * @param offset The offset into the byte array.
-     * @param length The length of the data we are getting.
-     * @return the resulting integer
-     */
-    private int getCodeFromArray( byte[] data, int offset, int length )
-    {
-        int code = 0;
-        for( int i=0; i<length; i++ )
-        {
-            code <<= 8;
-            code |= (data[offset+i]+256)%256;
-        }
-        return code;
-    }
-
-    /**
      * This will add a character code to Unicode character sequence mapping.
      *
      * @param codes The character codes to map from.
@@ -360,15 +341,15 @@ public class CMap
      */
     void addCharMapping(byte[] codes, String unicode)
     {
-        unicodeToByteCodes.put(unicode, codes.clone()); // clone needed, bytes is modified later
-        int code = getCodeFromArray(codes, 0, codes.length);
         if (codes.length == 1)
         {
-            charToUnicodeOneByte.put(code, unicode);
+            charToUnicodeOneByte.put(CMapStrings.getIndexValue(codes), unicode);
+            unicodeToByteCodes.put(unicode, CMapStrings.getByteValue(codes)); // clone needed, bytes is modified later
         }
         else if (codes.length == 2)
         {
-            charToUnicodeTwoBytes.put(code, unicode);
+            charToUnicodeTwoBytes.put(CMapStrings.getIndexValue(codes), unicode);
+            unicodeToByteCodes.put(unicode, CMapStrings.getByteValue(codes)); // clone needed, bytes is modified later
         }
         else
         {
@@ -377,7 +358,7 @@ public class CMap
         // fixme: ugly little hack
         if (SPACE.equals(unicode))
         {
-            spaceMapping = code;
+            spaceMapping = toInt(codes);
         }
     }
 

Modified: pdfbox/branches/3.0/fontbox/src/main/java/org/apache/fontbox/cmap/CMapStrings.java
URL: http://svn.apache.org/viewvc/pdfbox/branches/3.0/fontbox/src/main/java/org/apache/fontbox/cmap/CMapStrings.java?rev=1922579&r1=1922578&r2=1922579&view=diff
==============================================================================
--- pdfbox/branches/3.0/fontbox/src/main/java/org/apache/fontbox/cmap/CMapStrings.java (original)
+++ pdfbox/branches/3.0/fontbox/src/main/java/org/apache/fontbox/cmap/CMapStrings.java Wed Dec 18 10:18:22 2024
@@ -30,6 +30,10 @@ public class CMapStrings
     private static final List<String> twoByteMappings = new ArrayList<>(256 * 256);
     private static final List<String> oneByteMappings = new ArrayList<>(256);
 
+    private static final List<Integer> indexValues = new ArrayList<>(256 * 256);
+    private static final List<byte[]> oneByteValues = new ArrayList<>(256);
+    private static final List<byte[]> twoByteValues = new ArrayList<>(256 * 256);
+
     static
     {
         // create all mappings when loading the class to avoid concurrency issues
@@ -48,12 +52,15 @@ public class CMapStrings
             {
                 byte[] bytes = { (byte) i, (byte) j };
                 twoByteMappings.add(new String(bytes, StandardCharsets.UTF_16BE));
+                twoByteValues.add(bytes);
+                indexValues.add((i * 256) + j);
             }
         }
         for (int i = 0; i < 256; i++)
         {
             byte[] bytes = { (byte) i };
             oneByteMappings.add(new String(bytes, StandardCharsets.ISO_8859_1));
+            oneByteValues.add(bytes);
         }
     }
 
@@ -73,4 +80,38 @@ public class CMapStrings
         return bytes.length == 1 ? oneByteMappings.get(CMap.toInt(bytes))
                 : twoByteMappings.get(CMap.toInt(bytes));
     }
+
+    /**
+     * Get an Integer instance of the given combination of bytes. Each value is a singleton to avoid multiple instances
+     * for same value. The values are limited to one and two-byte sequences. Any longer byte sequence produces null as
+     * return value.
+     * 
+     * @param bytes the given combination of bytes
+     * @return the Integer representation for the given combination of bytes
+     */
+    public static Integer getIndexValue(byte[] bytes)
+    {
+        if (bytes.length > 2)
+        {
+            return null;
+        }
+        return indexValues.get(CMap.toInt(bytes));
+    }
+
+    /**
+     * Get a singleton instance of the given combination of bytes to avoid multiple instances for same value. The values
+     * are limited to one and two-byte sequences. Any longer byte sequence produces null as return value.
+     * 
+     * @param bytes the given combination of bytes
+     * @return a singleton instance for the given combination of bytes
+     */
+    public static byte[] getByteValue(byte[] bytes)
+    {
+        if (bytes.length > 2)
+        {
+            return null;
+        }
+        return bytes.length == 1 ? oneByteValues.get(CMap.toInt(bytes))
+                : twoByteValues.get(CMap.toInt(bytes));
+    }
 }