public synchronized void writeDataDirectory()

in jsign-core/src/main/java/net/jsign/pe/PEFile.java [652:709]


    public synchronized void writeDataDirectory(DataDirectoryType type, byte[] data) throws IOException {
        DataDirectory directory = getDataDirectory(type);
        
        if (!directory.exists()) {
            // append the data directory at the end of the file
            long offset = channel.size();
            
            channel.position(offset);
            channel.write(ByteBuffer.wrap(data));
            
            // update the entry in the data directory table
            directory.write(offset, data.length);
            
        } else {
            if (data.length == directory.getSize()) {
                // same size as before, just overwrite
                channel.position(directory.getVirtualAddress());
                channel.write(ByteBuffer.wrap(data));

            } else if (data.length < directory.getSize() && type != DataDirectoryType.CERTIFICATE_TABLE) {
                // the new data is smaller, erase and rewrite in-place
                // this doesn't work with the certificate table since it changes the file digest
                directory.erase();
                channel.position(directory.getVirtualAddress());
                channel.write(ByteBuffer.wrap(data));
                
                // update the size in the data directory table
                directory.write(directory.getVirtualAddress(), data.length);

            } else if (directory.isTrailing()) {
                // the data is at the end of the file, overwrite it
                channel.position(directory.getVirtualAddress());
                channel.write(ByteBuffer.wrap(data));
                channel.truncate(directory.getVirtualAddress() + data.length); // trim the file if the data shrunk
                
                // update the size in the data directory table
                directory.write(directory.getVirtualAddress(), data.length);

            } else {
                if (type == DataDirectoryType.CERTIFICATE_TABLE) {
                    throw new IOException("The certificate table isn't at the end of the file and can't be moved without invalidating the signature");
                }
                
                // the new data is larger, erase and relocate it at the end
                directory.erase();
                
                long offset = channel.size();
                
                channel.position(offset);
                channel.write(ByteBuffer.wrap(data));
                
                // update the entry in the data directory table
                directory.write(offset, data.length);
            }
        }
        
        updateChecksum();
    }