/* * JCarder -- cards Java programs to keep threads disentangled * * Copyright (C) 2006-2007 Enea AB * Copyright (C) 2007 Ulrik Svensson * Copyright (C) 2007 Joel Rosdahl * * This program is made available under the GNU GPL version 2, with a special * exception for linking with JUnit. See the accompanying file LICENSE.txt for * details. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. */ package com.enea.jcarder.common.events; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; import com.enea.jcarder.util.logging.Logger; public final class EventFileReader { private static final int INT_LENGTH = 4; private static final int LONG_LENGTH = 8; private final Logger mLogger; static final int EVENT_LENGTH = (INT_LENGTH * 4) + LONG_LENGTH; static final long MAGIC_COOKIE = 2153191828159737167L; static final int MAJOR_VERSION = 1; static final int MINOR_VERSION = 0; public EventFileReader(Logger logger) { mLogger = logger; } public void parseFile(File file, LockEventListenerIfc eventReceiver) throws IOException { int numberOfParsedEvents = 0; FileInputStream fis = new FileInputStream(file); final String path = file.getCanonicalPath(); mLogger.info("Opening for reading: " + path); FileChannel fileChannel = fis.getChannel(); validateHeader(fileChannel, path); final ByteBuffer buffer = ByteBuffer.allocate(EVENT_LENGTH); while (fileChannel.read(buffer) == EVENT_LENGTH) { buffer.rewind(); parseLockEvent(buffer, eventReceiver); buffer.rewind(); numberOfParsedEvents++; } mLogger.fine("Loaded " + numberOfParsedEvents + " lock events from file."); } private void validateHeader(FileChannel channel, String filename) throws IOException { final ByteBuffer buffer = ByteBuffer.allocate(8 + 4 + 4); channel.read(buffer); buffer.flip(); if (MAGIC_COOKIE != buffer.getLong()) { throw new IOException("Invalid file contents in: " + filename); } final int majorVersion = buffer.getInt(); final int minorVersion = buffer.getInt(); if (majorVersion != MAJOR_VERSION) { throw new IOException("Incompatible version: " + majorVersion + "." + minorVersion + " in: " + filename); } } private static void parseLockEvent(ByteBuffer lockEventBuffer, LockEventListenerIfc eventReceiver) throws IOException { final int lockId = lockEventBuffer.getInt(); final int lockingContextId = lockEventBuffer.getInt(); final int lastTakenLockId = lockEventBuffer.getInt(); final int lastTakenLockingContextId = lockEventBuffer.getInt(); final long threadId = lockEventBuffer.getLong(); eventReceiver.onLockEvent(lockId, lockingContextId, lastTakenLockId, lastTakenLockingContextId, threadId); } }