private List loadDiskCache()

in pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/FileSystemFontProvider.java [493:652]


    private List<FSFontInfo> loadDiskCache(List<File> files)
    {
        Set<String> pending = new HashSet<>(files.size());
        for (File file : files)
        {
            pending.add(file.getAbsolutePath());
        }
        
        List<FSFontInfo> results = new ArrayList<>();
        
        // Get the disk cache
        File diskCacheFile = null;
        boolean fileExists = false;
        try
        {
            diskCacheFile = getDiskCacheFile();
            fileExists = diskCacheFile.exists();
        }
        catch (SecurityException e)
        {
            LOG.debug("Error checking for file existence", e);
        }

        if (fileExists)
        {
            try (BufferedReader reader = new BufferedReader(new FileReader(diskCacheFile)))
            {
                // consequent lines usually share the same font file (e.g. "Courier", "Courier-Bold", "Courier-Oblique").
                // unused if SKIP_CHECKSUMS
                File lastFile = null;
                String lastHash = null;
                //
                String line;
                while ((line = reader.readLine()) != null)
                {
                    String[] parts = line.split("\\|", 12);
                    if (parts.length < 10)
                    {
                        LOG.warn("Incorrect line '{}' in font disk cache is skipped", line);
                        continue;
                    }

                    String postScriptName;
                    FontFormat format;
                    CIDSystemInfo cidSystemInfo = null;
                    int usWeightClass = -1;
                    int sFamilyClass = -1;
                    int ulCodePageRange1;
                    int ulCodePageRange2;
                    int macStyle = -1;
                    byte[] panose = null;
                    File fontFile;
                    String hash = "";
                    long lastModified = 0;
                    
                    postScriptName = parts[0];
                    format = FontFormat.valueOf(parts[1]);
                    if (!parts[2].isEmpty())
                    {
                        String[] ros = parts[2].split("-");
                        cidSystemInfo = new CIDSystemInfo(ros[0], ros[1], Integer.parseInt(ros[2]));
                    }
                    if (!parts[3].isEmpty())
                    {
                        usWeightClass = (int)Long.parseLong(parts[3], 16);
                    }
                    if (!parts[4].isEmpty())
                    {
                        sFamilyClass = (int)Long.parseLong(parts[4], 16);
                    }
                    ulCodePageRange1 = (int)Long.parseLong(parts[5], 16);
                    ulCodePageRange2 = (int)Long.parseLong(parts[6], 16);
                    if (!parts[7].isEmpty())
                    {
                        macStyle = (int)Long.parseLong(parts[7], 16);
                    }
                    if (!parts[8].isEmpty())
                    {
                        panose = new byte[10];
                        for (int i = 0; i < 10; i ++)
                        {
                            String str = parts[8].substring(i * 2, i * 2 + 2);
                            int b = Integer.parseInt(str, 16);
                            panose[i] = (byte)(b & 0xff);
                        }
                    }
                    fontFile = new File(parts[9]);
                    if (parts.length >= 12 && !parts[10].isEmpty() && !parts[11].isEmpty())
                    {
                        hash = parts[10];
                        lastModified = Long.parseLong(parts[11]);
                    }
                    if (fontFile.exists())
                    {
                        // if the file exists, find out whether it's the same file.
                        // first check whether time is different and if yes, whether hash is different
                        boolean keep = fontFile.lastModified() == lastModified;
                        if (!keep && !SKIP_CHECKSUMS)
                        {
                            String newHash;
                            if (hash.equals(lastHash) && fontFile.equals(lastFile))
                            {
                                newHash = lastHash; // already computed
                            }
                            else
                            {
                                try
                                {
                                    newHash = computeHash(Files.newInputStream(fontFile.toPath()));
                                    lastFile = fontFile;
                                    lastHash = newHash;
                                }
                                catch (IOException ex)
                                {
                                    LOG.debug(() -> "Error reading font file " + fontFile.getAbsolutePath(), ex);
                                    newHash = "<err>";
                                }
                            }
                            if (hash.equals(newHash))
                            {
                                keep = true;
                                lastModified = fontFile.lastModified();
                            }
                        }
                        if (keep)
                        {
                            FSFontInfo info = new FSFontInfo(fontFile, format, postScriptName,
                                    cidSystemInfo, usWeightClass, sFamilyClass, ulCodePageRange1,
                                    ulCodePageRange2, macStyle, panose, this, hash, lastModified);
                            results.add(info);
                        }
                        else
                        {
                            LOG.debug("Font file {} is different", fontFile.getAbsolutePath());
                            continue; // don't remove from "pending"
                        }
                    }
                    else
                    {
                        LOG.debug("Font file {} not found, skipped", fontFile.getAbsolutePath());
                    }
                    pending.remove(fontFile.getAbsolutePath());
                }
            }
            catch (IOException e)
            {
                LOG.warn("Error loading font cache, will be re-built", e);
                return null;
            }
        }
        
        if (!pending.isEmpty())
        {
            // re-build the entire cache if we encounter un-cached fonts (could be optimised)
            LOG.info("{} new font files found, font cache will be re-built", pending.size());
            return null;
        }
        
        return results;
    }