/**
* JHOVE2 - Next-generation architecture for format-aware characterization
*
* Copyright (c) 2009 by The Regents of the University of California,
* Ithaka Harbors, Inc., and The Board of Trustees of the Leland Stanford
* Junior University.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* o Neither the name of the University of California/California Digital
* Library, Ithaka Harbors/Portico, or Stanford University, nor the names of
* its contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package org.jhove2.module.identify.file;
import java.nio.Buffer;
import org.jhove2.core.JHOVE2Exception;
import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.NativeLong;
import com.sun.jna.Platform;
import com.sun.jna.Pointer;
/**
* A wrapper for the libmagic library that relies on JNA.
*
* @author hbian
*/
public class LibmagicJnaWrapper {
public interface LibmagicDll extends Library {
String LIBRARY_NAME = (Platform.isWindows())? "magic1": "magic";
LibmagicDll BASE = (LibmagicDll)
Native.loadLibrary(LIBRARY_NAME, LibmagicDll.class);
LibmagicDll INSTANCE = (LibmagicDll)Native.synchronizedLibrary(BASE);
Pointer magic_open(int flags);
void magic_close(Pointer cookie);
int magic_setflags(Pointer cookie, int flags);
String magic_file(Pointer cookie, String fileName);
String magic_buffer(Pointer cookie, Buffer buffer, NativeLong length);
int magic_compile(Pointer cookie, String magicFileName);
int magic_check(Pointer cookie, String magicFileName);
int magic_load(Pointer cookie, String magicFileName);
int magic_errno(Pointer cookie);
String magic_error(Pointer cookie);
}
/** Libmagic flag: No flags. */
public final static int MAGIC_NONE = 0x000000;
/** Libmagic flag: Turn on debugging. */
public final static int MAGIC_DEBUG = 0x000001;
/** Libmagic flag: Follow symlinks. */
public final static int MAGIC_SYMLINK = 0x000002;
/** Libmagic flag: Check inside compressed files. */
public final static int MAGIC_COMPRESS = 0x000004;
/** Libmagic flag: Look at the contents of devices. */
public final static int MAGIC_DEVICES = 0x000008;
/** Libmagic flag: Return the MIME type. */
public final static int MAGIC_MIME_TYPE = 0x000010;
/** Libmagic flag: Return all matches. */
public final static int MAGIC_CONTINUE = 0x000020;
/** Libmagic flag: Print warnings to stderr. */
public final static int MAGIC_CHECK = 0x000040;
/** Libmagic flag: Restore access time on exit. */
public final static int MAGIC_PRESERVE_ATIME = 0x000080;
/** Libmagic flag: Don't translate unprintable chars. */
public final static int MAGIC_RAW = 0x000100;
/** Libmagic flag: Handle ENOENT etc as real errors. */
public final static int MAGIC_ERROR = 0x000200;
/** Libmagic flag: Return the MIME encoding. */
public final static int MAGIC_MIME_ENCODING = 0x000400;
/** Libmagic flag: Return both MIME type and encoding. */
public final static int MAGIC_MIME =
(MAGIC_MIME_TYPE | MAGIC_MIME_ENCODING);
/** Libmagic flag: Return the Apple creator and type. */
public final static int MAGIC_APPLE = 0x000800;
/** Libmagic flag: Don't check for compressed files. */
public final static int MAGIC_NO_CHECK_COMPRESS = 0x001000;
/** Libmagic flag: Don't check for tar files. */
public final static int MAGIC_NO_CHECK_TAR = 0x002000;
/** Libmagic flag: Don't check magic entries. */
public final static int MAGIC_NO_CHECK_SOFT = 0x004000;
/** Libmagic flag: Don't check application type. */
public final static int MAGIC_NO_CHECK_APPTYPE = 0x008000;
/** Libmagic flag: Don't check for elf details. */
public final static int MAGIC_NO_CHECK_ELF = 0x010000;
/** Libmagic flag: Don't check for text files. */
public final static int MAGIC_NO_CHECK_TEXT = 0x020000;
/** Libmagic flag: Don't check for cdf files. */
public final static int MAGIC_NO_CHECK_CDF = 0x040000;
/** Libmagic flag: Don't check tokens. */
public final static int MAGIC_NO_CHECK_TOKENS = 0x100000;
/** Libmagic flag: Don't check text encodings. */
public final static int MAGIC_NO_CHECK_ENCODING = 0x200000;
/** Magic cookie pointer. */
private final Pointer cookie;
/**
* Creates a new instance returning the default information: MIME
* type and character encoding.
*
* @throws JHOVE2Exception if any error occurred while
* initializing the libmagic.
*
* @see #LibmagicJnaWrapper(int)
* @see #MAGIC_MIME
*/
public LibmagicJnaWrapper() throws JHOVE2Exception {
this(MAGIC_MIME | MAGIC_SYMLINK);
}
/**
* Creates a new instance returning the information specified in
* the <code>flag</code> argument
*
* @throws JHOVE2Exception if any error occurred while
* initializing the libmagic.
*/
public LibmagicJnaWrapper(int flag) throws JHOVE2Exception {
this.cookie = LibmagicDll.INSTANCE.magic_open(flag);
if (this.cookie == null) {
throw new JHOVE2Exception("Libmagic initialization failed");
}
}
/**
* Closes the magic database and deallocates any resources used.
*/
public void close() {
LibmagicDll.INSTANCE.magic_close(cookie);
}
/**
* Returns a textual explanation of the last error.
* @return the textual description of the last error, or
* <code>null</code> if there was no error.
*/
public String getError() {
return LibmagicDll.INSTANCE.magic_error(cookie);
}
/**
* Returns the textual description of the contents of the
* specified file.
* @param filePath the path of the file to be identified.
*
* @return the textual description of the file, or
* <code>null</code> if an error occurred.
*/
public String getMimeType(String filePath) {
if ((filePath == null) || (filePath.length() == 0)) {
throw new IllegalArgumentException("filePath");
}
return LibmagicDll.INSTANCE.magic_file(cookie, filePath);
}
/**
* Returns textual description of the contents of the
* <code>buffer</code> argument.
* @param buffer the data to analyze.
* @param length the length, in bytes, of the buffer.
*
* @return the textual description of the buffer data, or
* <code>null</code> if an error occurred.
*/
public String getMimeType(Buffer buffer, long length) {
return LibmagicDll.INSTANCE.magic_buffer(cookie, buffer,
new NativeLong(length));
}
/**
* Compiles the colon-separated list of database text files passed
* in as <code>magicFiles</code>.
* @param magicFiles the magic database file(s), or
* <code>null</code> to use the default
* database.
* @return 0 on success and -1 on failure.
*/
public int compile(String magicFiles) {
return LibmagicDll.INSTANCE.magic_compile(cookie, magicFiles);
}
/**
* Loads the colon-separated list of database files passed in as
* <code>magicFiles</code>. This method must be used before any
* magic queries be performed.
* @param magicFiles the magic database file(s), or
* <code>null</code> to use the default
* database.
* @return 0 on success and -1 on failure.
*/
public int load(String magicFiles) {
return LibmagicDll.INSTANCE.magic_load(cookie, magicFiles);
}
}