diff --git a/.ci/ci.sh b/.ci/ci.sh
index 88021f5..8fbbba9 100755
--- a/.ci/ci.sh
+++ b/.ci/ci.sh
@@ -7,5 +7,5 @@ if [ "$TRAVIS_REPO_SLUG" == "diffplug/matfilerw" ] && [ "$TRAVIS_PULL_REQUEST" =
# Publish the artifacts
./gradlew publish || exit 1
# Push the javadoc
- ./.ci/push-javadoc.sh
+ ./gradlew publishGhPages || exit 1
fi
diff --git a/.ci/push-javadoc.sh b/.ci/push-javadoc.sh
deleted file mode 100755
index 4a3a307..0000000
--- a/.ci/push-javadoc.sh
+++ /dev/null
@@ -1,37 +0,0 @@
-#!/bin/bash
-
-echo "Pushing javadoc to gh-pages..."
-
-# save the version
-VERSION=$(./gradlew -q printVersion)
-
-# copy javadoc from the build to ~/javadoc-temp
-cp -R build/docs/javadoc $HOME/javadoc-temp
-
-# clone a new copy jmatio to gh-pages
-cd $HOME
-git config --global user.email "travis@travis-ci.org"
-git config --global user.name "travis-ci"
-rm -rf $HOME/gh-pages
-git clone --quiet --branch=gh-pages https://${gh_token}@github.com/diffplug/matfilerw gh-pages > /dev/null
-
-# copy the javadoc into the build
-cd gh-pages
-mkdir -p javadoc
-if [[ "$VERSION" != *SNAPSHOT* ]]; then
- git rm -rf javadoc/${VERSION}
- cp -Rf $HOME/javadoc-temp/ ./javadoc/${VERSION}/
-else
- git rm -rf javadoc/snapshot
- cp -Rf $HOME/javadoc-temp/ ./javadoc/snapshot/
-fi
-
-# add all of the stuff and commit it
-git add -f -A
-git commit -m "Lastest javadoc on successful travis build $TRAVIS_BUILD_NUMBER auto-pushed to gh-pages"
-if ! git push -fq origin gh-pages &> /dev/null; then
- echo "Error pushing javadoc to origin. Bad gh_token? GitHub down?"
- exit 1
-else
- echo "Pushed javadoc to gh-pages."
-fi
diff --git a/.travis.yml b/.travis.yml
index 4048052..a2a7818 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -3,9 +3,9 @@ jdk:
- oraclejdk8
script: "./.ci/ci.sh"
before_cache:
-- rm -f $HOME/.gradle/caches/modules-2/modules-2.lock
+ - rm -f $HOME/.gradle/caches/modules-2/modules-2.lock
+ - rm -fr $HOME/.gradle/caches/*/plugin-resolution/
cache:
directories:
- - "$HOME/.gradle/caches/"
- - "$HOME/.gradle/wrapper/"
- - "build/jdk"
+ - $HOME/.gradle/caches/
+ - $HOME/.gradle/wrapper/
diff --git a/CHANGES.md b/CHANGES.md
index bef0168..f4b2591 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -1,10 +1,61 @@
# MatFileRW releases
-### Version 1.4.0-SNAPSHOT - TBD ([javadoc](http://diffplug.github.io/matfilerw/javadoc/snapshot/), [jcenter](https://oss.sonatype.org/content/repositories/snapshots/com/diffplug/matsim/matfilerw/))
+### Version 3.2.0-SNAPSHOT - TBD ([javadoc](http://diffplug.github.io/matfilerw/javadoc/snapshot/), [snapshot](https://oss.sonatype.org/content/repositories/snapshots/com/diffplug/matsim/matfilerw/))
+
+### Version 3.1.1 - December 28th 2018 ([javadoc](http://diffplug.github.io/matfilerw/javadoc/3.1.1/), [jcenter](https://bintray.com/diffplug/opensource/matfilerw/3.1.1/view))
+
+* Fixed MatFileReader.read(File file) to allow multiple calls(see [#20](https://github.com/diffplug/matfilerw/issues/20)).
+
+### Version 3.1.0 - November 13th 2018 ([javadoc](http://diffplug.github.io/matfilerw/javadoc/3.1.0/), [jcenter](https://bintray.com/diffplug/opensource/matfilerw/3.1.0/view))
+
+* Added support for Jigsaw and Java 9+ (see [#16](https://github.com/diffplug/matfilerw/issues/16)).
+
+### Version 3.0.1 - June 28th 2017 ([javadoc](http://diffplug.github.io/matfilerw/javadoc/3.0.1/), [jcenter](https://bintray.com/diffplug/opensource/matfilerw/3.0.1/view))
+
+* Fixed second-level MCOS property dereferencing (see [#13](https://github.com/diffplug/matfilerw/issues/13)).
+
+### Version 3.0.0 - November 22nd 2016 ([javadoc](http://diffplug.github.io/matfilerw/javadoc/3.0.0/), [jcenter](https://bintray.com/diffplug/opensource/matfilerw/3.0.0/view))
+
+* Fixed multidimensional array indexing (see [#10](https://github.com/diffplug/matfilerw/issues/10)).
+ + For arrays with dimension 1 or 2, there is no change.
+ + For arrays with dimension 3 and up, matfilerw 2.x did not order the dimensions in the column-major format used by MATLAB. In 3.x forward, matfilerw uses the same column-major format as MATLAB.
+* `getImaginary` will always return zero for real arrays.
+
+### Version 2.3.0 - August 18th 2016 ([javadoc](http://diffplug.github.io/matfilerw/javadoc/2.3.0/), [jcenter](https://bintray.com/diffplug/opensource/matfilerw/2.3.0/view))
+
+* Fixed problem where a handle class is encoded within an MLObject.
+* MCOS variables can now be parsed from anywhere within the MAT-File (previously could only be a root variable).
+* Arrays of structs and fields are now enforced to have their fields be in a consistent order element to element.
+
+### Version 2.2.0 - February 9th 2016 ([javadoc](http://diffplug.github.io/matfilerw/javadoc/2.2.0/), [jcenter](https://bintray.com/diffplug/opensource/matfilerw/2.2.0/view))
+
+* Added `MatFile.readFull(ByteBuffer buf, MatFileType type)`
+* Added `MLArray.getIndex(int...)` and `MLNumericArray.set(T value, int...)` and `T get(int...)` for N-dimensional indices.
+* Fixed the JRE6 download in the build file.
+
+### Version 2.1.0 - December 10th 2015 ([javadoc](http://diffplug.github.io/matfilerw/javadoc/2.1.0/), [jcenter](https://bintray.com/diffplug/opensource/matfilerw/2.1.0/view))
+
+* Fixed support for reading UTF fields (closes [#2](https://github.com/diffplug/matfilerw/issues/2))
+
+### Version 2.0.0 - October 25th 2015 ([javadoc](http://diffplug.github.io/matfilerw/javadoc/2.0.0/), [jcenter](https://bintray.com/diffplug/opensource/matfilerw/2.0.0/view))
+
+* Incorporated all changes from `codesourcery/JMatIO`.
+ + Adds support for MCOS Objects.
+ + Adds a Simulink decoder for reading files from Simulink MDL files.
+ + Improved performance.
+* `MLObject` and `MLStructure` now share `MLStructureObjectBase` as a base class. This caused a small breaking change to `MLObject`s API.
+* `MatFileHeader` now wraps up the whole endianness mess, which also required a small breaking change.
+
+### Version 2.0.0.TRANSITION - October 25th 2015 ([javadoc](http://diffplug.github.io/matfilerw/javadoc/2.0.TRANSITION/), [jcenter](https://bintray.com/diffplug/opensource/matfilerw/2.0.TRANSITION/view))
+
+Only pertinent for people who are migrating from a JMatIO fork whose packages were renamed to `ca.mjdsystems.jmatio`.
+
+* `ca.mjdsystems.jmatio` code is included umodified, but marked as deprecated.
+* `com.jmatio` code is identitical to `2.0.0`.
### Version 1.3.1 - October 16th 2015 ([javadoc](http://diffplug.github.io/matfilerw/javadoc/1.3.1/), [jcenter](https://bintray.com/diffplug/opensource/matfilerw/1.3.1/view))
-- Corrected the license in the maven metadata.
+* Corrected the license in the maven metadata.
### Version 1.3.0 - October 16th 2015 ([javadoc](http://diffplug.github.io/matfilerw/javadoc/1.3.0/), [jcenter](https://bintray.com/diffplug/opensource/matfilerw/1.3.0/view))
diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md
new file mode 100644
index 0000000..4be4ecf
--- /dev/null
+++ b/CODE_OF_CONDUCT.md
@@ -0,0 +1,46 @@
+# Contributor Covenant Code of Conduct
+
+## Our Pledge
+
+In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
+
+## Our Standards
+
+Examples of behavior that contributes to creating a positive environment include:
+
+* Using welcoming and inclusive language
+* Being respectful of differing viewpoints and experiences
+* Gracefully accepting constructive criticism
+* Focusing on what is best for the community
+* Showing empathy towards other community members
+
+Examples of unacceptable behavior by participants include:
+
+* The use of sexualized language or imagery and unwelcome sexual attention or advances
+* Trolling, insulting/derogatory comments, and personal or political attacks
+* Public or private harassment
+* Publishing others' private information, such as a physical or electronic address, without explicit permission
+* Other conduct which could reasonably be considered inappropriate in a professional setting
+
+## Our Responsibilities
+
+Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
+
+Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
+
+## Scope
+
+This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
+
+## Enforcement
+
+Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at community@diffplug.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
+
+Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
+
+## Attribution
+
+This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
+
+[homepage]: http://contributor-covenant.org
+[version]: http://contributor-covenant.org/version/1/4/
diff --git a/META-INF/MANIFEST.MF b/META-INF/MANIFEST.MF
index c8a1d5e..bc1ccab 100644
--- a/META-INF/MANIFEST.MF
+++ b/META-INF/MANIFEST.MF
@@ -1,16 +1,17 @@
Manifest-Version: 1.0
Bundle-Description: MatFileRW - Read and write .mat files
Bundle-DocURL: https://github.com/diffplug/matfilerw
-Bundle-License: https://github.com/diffplug/matfilerw/blob/v1.3.0/LICENS
- E
+Bundle-License: https://github.com/diffplug/matfilerw/blob/v3.1.0-SNAP
+ SHOT/LICENSE
Bundle-ManifestVersion: 2
Bundle-SymbolicName: com.diffplug.matsim.matfilerw
Bundle-Vendor: DiffPlug
-Bundle-Version: 1.3.0
-Export-Package: com.jmatio.common;version="1.3.0",com.jmatio.common.util
- ;uses:="com.jmatio.types";version="1.3.0",com.jmatio.io;uses:="com.jmat
- io.types";version="1.3.0",com.jmatio.io.stream;uses:="com.jmatio.types"
- ;version="1.3.0",com.jmatio.types;version="1.3.0"
-Import-Package: com.jmatio.common,com.jmatio.io.stream,com.jmatio.types,
- sun.misc
+Bundle-Version: 3.1.0.I201706282450
+Export-Package: com.jmatio.common;version="3.1.0",com.jmatio.common.ut
+ il;uses:="com.jmatio.types";version="3.1.0",com.jmatio.io;uses:="com.
+ jmatio.types";version="3.1.0",com.jmatio.io.stream;uses:="com.jmatio.
+ types";version="3.1.0",com.jmatio.types;uses:="com.jmatio.common";ver
+ sion="3.1.0"
+Import-Package: sun.misc;resolution:=optional,com.jmatio.common,com.jm
+ atio.io.stream,com.jmatio.types
Require-Capability: osgi.ee;filter:="(&(osgi.ee=JavaSE)(version=1.6))"
diff --git a/MatlabClasses/HandleClass.m b/MatlabClasses/HandleClass.m
new file mode 100644
index 0000000..7501426
--- /dev/null
+++ b/MatlabClasses/HandleClass.m
@@ -0,0 +1,6 @@
+% http://stackoverflow.com/questions/36025747/matlab-documentation-on-handle-variables-and-mat-files
+classdef HandleClass < handle
+properties
+ myPropA
+end % properties
+end % classdef
diff --git a/MatlabClasses/OtherClass.m b/MatlabClasses/OtherClass.m
new file mode 100644
index 0000000..44016cf
--- /dev/null
+++ b/MatlabClasses/OtherClass.m
@@ -0,0 +1,6 @@
+% http://stackoverflow.com/questions/36025747/matlab-documentation-on-handle-variables-and-mat-files
+classdef OtherClass
+properties
+ myObjA
+end % properties
+end % classdef
diff --git a/MatlabClasses/SimpleEmpty.m b/MatlabClasses/SimpleEmpty.m
index 3cc91c1..eb0685e 100644
--- a/MatlabClasses/SimpleEmpty.m
+++ b/MatlabClasses/SimpleEmpty.m
@@ -1,11 +1,10 @@
classdef SimpleEmpty
- %SIMPLEEMPTY A simple empty class definition.
-
- properties
- end
-
- methods
- end
-
-end
+ %SIMPLEEMPTY A simple empty class definition.
+
+ properties
+ end
+ methods
+ end
+
+end
diff --git a/MatlabClasses/SimpleSingleText.m b/MatlabClasses/SimpleSingleText.m
index fa5168b..6f46b74 100644
--- a/MatlabClasses/SimpleSingleText.m
+++ b/MatlabClasses/SimpleSingleText.m
@@ -1,13 +1,12 @@
classdef SimpleSingleText
- %SIMPLESINGLETEXT Summary of this class goes here
- % Detailed explanation goes here
-
- properties
- test_text = 'Default text'
- end
-
- methods
- end
-
-end
+ %SIMPLESINGLETEXT Summary of this class goes here
+ % Detailed explanation goes here
+
+ properties
+ test_text = 'Default text'
+ end
+ methods
+ end
+
+end
diff --git a/MatlabClasses/TestHandleClass.m b/MatlabClasses/TestHandleClass.m
new file mode 100644
index 0000000..1b38647
--- /dev/null
+++ b/MatlabClasses/TestHandleClass.m
@@ -0,0 +1,18 @@
+% http://stackoverflow.com/questions/36025747/matlab-documentation-on-handle-variables-and-mat-files
+
+%% create and save the objects
+% Create 2 object variables. 2nd
+% one has a property that refers to
+% same object as the first one
+objA = HandleClass;
+objA.myPropA = 5;
+objB = OtherClass;
+objB.myObjA = objA;
+objC = HandleClass;
+objC.myPropA = objA;
+
+save('../src/test/resources/handles.mat', 'objA', 'objB', 'objC');
+
+%% clear and load them back
+clear
+load('../src/test/resources/handles.mat')
diff --git a/PULL_REQUEST_TEMPLATE.md b/PULL_REQUEST_TEMPLATE.md
new file mode 100644
index 0000000..89d5062
--- /dev/null
+++ b/PULL_REQUEST_TEMPLATE.md
@@ -0,0 +1,6 @@
+After creating the PR, please add a commit that adds a bullet-point under the `-SNAPSHOT` section of [CHANGES.md](https://github.com/diffplug/matfilerw/blob/master/CHANGES.md) that includes:
+
+- [ ] a summary of the change
+- [ ] a link to the newly created PR
+
+This makes it easier for the maintainers to quickly release your changes.
diff --git a/README.md b/README.md
index 5034456..d6fd5cb 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,15 @@
+## MatFileRW is not abandoned, but we recommend migrating to [HebiRobotics/MFL](https://github.com/HebiRobotics/MFL)
+
+MatFileRW will continue to accept bug reports and PRs. However, we recommend starting new projects with [HebiRobotics/MFL](https://github.com/HebiRobotics/MFL) because it:
+
+- has every testcase from MatFileRW and more
+- has a cleaner and more modern codebase
+- supports concurrent compression and decompression
+- is designed for interoperability with native-Java matrix manipulation
+- has optional [EJML](https://ejml.org) integration
+
+Besides the effort to learn the new API, there are no downsides and quite a few upsides. Migrating a project is a big job, so we will continue to accept bug reports and PR's for MatFileRW to support those who don't choose to migrate.
+
# MatFileRW: Read and write MATLAB MAT-files from Java
[](https://bintray.com/diffplug/opensource/matfilerw/view)
-[](https://github.com/diffplug/matfilerw/releases/latest)
-[](https://diffplug.github.io/matfilerw/javadoc/1.3.1/)
+[](https://github.com/diffplug/matfilerw/releases/latest)
+[](https://diffplug.github.io/matfilerw/javadoc/3.1.1/)
[](https://tldrlegal.com/license/bsd-3-clause-license-(revised))
-[](CHANGES.md)
+[](CHANGES.md)
[](https://travis-ci.org/diffplug/matfilerw)
-MatFileRW is a library which allows reading and writing MAT files. Have a look at [MatIOTest.java](src/test/java/com/jmatio/test/MatIOTest.java?ts=4) to see each part in use.
+MatFileRW is a library which allows reading and writing MAT files. Have a look at [MatIOTest.java](https://github.com/diffplug/matfilerw/blob/master/src/test/java/com/jmatio/io/MatIOTest.java) to see each part in use.
As far as compatibility, the TL;DR is that it will work with any MAT-File with default settings. The dirty details are that this library works with `v6` and `v7`, but not `v4` or `v7.3`.
@@ -30,9 +42,11 @@ As far as compatibility, the TL;DR is that it will work with any MAT-File with d
* MATLAB does not export to v7.3 by default.
* The [Mathworks website](http://www.mathworks.com/help/matlab/import_export/mat-file-versions.html?refresh=true) has more details.
-## codemercenary/jmatio and the status of ca.mjdsystems
+## codemercenary/jmatio and ca.mjdsystems.jmatio
+
+Since JMatIO wasn't updated for a while, lots of people made forks. One of the most prominent was Jason Lokerson's, hosted on GitHub as codemercenary/JMatIO. It included several improvements, but all the packages were renamed to `ca.mjdsystems.jmatio`. Starting with 2.0.0, all of the improvements from MatFileRW and `ca.mjdsystems.jmatio` have been merged into the `com.jmatio` packages.
-Since JMatIO wasn't updated for a while, lots of people made forks. One of the most prominent was Jason Lokerson's, hosted on GitHub as codemercenary/JMatIO. It included several improvements, but all the packages were renamed to "ca.mjdsystems.jmatio". In an effort to bring all JMatIO's under one roof, we have included its source code, unchanged, into MatFileRW. We are working on merging all of its improvements into the main "com.jmatio" classes, and the "ca.mjdsystems" namespace is deprecated, and will be removed in 2.0.
+If you are a user of the `ca.mjdsystems` packages, you should download `com.diffplug.matsim:matfilerw:2.0.0.TRANSITION` from mavenCentral. This contains the `ca.mjdsystems.jmatio` packages unchanged, but marked as deprecated. After you have removed all dependencies on the `ca.mjdsystems.jmatio` packages, you will be able to use the regular `2.0.0` version, and its descendants.
## Acknowledgements
@@ -40,10 +54,23 @@ This project is forked from the JMatIO project originally maintained on [SourceF
We have fixed some bugs and added some features (see the [changelog](CHANGES.md)), and we will maintain this library into the future. We're happy to accept [pull requests](CONTRIBUTING.md) too!
+People whose commits are included in this project
+* Original JMatIO project credit to Wojciech Gradkowski
+* Thanks to Tim Ryan for [finding and fixing](https://github.com/diffplug/matfilerw/pull/9) a multidimensional indexing bug.
+* MLSparse improvements credit to Sina Samangooei
+* Reading from streams credit to Jonathan Hare
+* MCOS and Simulink MAT-File parsing by Matthew Dawson
+* Further MCOS fixes thanks to Piotr Smolinski
+* int32 writing by Gabriel Shubiner
+* ZLIP EOF Exception fix by David Williams
+* Integration work by Jason Lokerson
+* Multidimensional array indexing by Mikael Grev
+* AbstractIterator taken from Google's Guava
+
+Tools used by this project
* Formatted by [spotless](https://github.com/diffplug/spotless), [as such](https://github.com/diffplug/matfilerw/blob/v1.3.1/build.gradle?ts=4#L129-L149).
* Bugs found by [findbugs](http://findbugs.sourceforge.net/), [as such](https://github.com/diffplug/matfilerw/blob/v1.3.1/build.gradle?ts=4#L151-L175).
-* OSGi metadata generated by JRuyi's [osgibnd-gradle-plugin] (https://github.com/jruyi/osgibnd-gradle-plugin), which leverages Peter Kriens' [bnd](http://www.aqute.biz/Bnd/Bnd).
-* Scripts in the `.ci` folder are inspired by [Ben Limmer's work](http://benlimmer.com/2013/12/26/automatically-publish-javadoc-to-gh-pages-with-travis-ci/).
+* OSGi metadata generated by [Goomph](https://github.com/diffplug/goomph), which leverages Peter Kriens' [bnd](http://www.aqute.biz/Bnd/Bnd).
* Built by [gradle](http://gradle.org/).
* Tested by [junit](http://junit.org/).
* Maintained by [DiffPlug](http://www.diffplug.com/).
diff --git a/build.gradle b/build.gradle
index b79d581..24dbaa3 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,12 +1,14 @@
plugins {
// osgi
- id "org.jruyi.osgibnd" version "0.4.0"
+ id "com.diffplug.gradle.osgi.bndmanifest" version "3.4.0"
// code formatting
- id "com.diffplug.gradle.spotless" version "1.3.1"
+ id "com.diffplug.gradle.spotless" version "3.0.0"
// bintray uploading
id "com.jfrog.bintray" version "1.3.1"
// for downloading JRE6
id "de.undercouch.download" version "2.0.0"
+ // github pages
+ id "org.ajoberstar.github-pages" version "1.4.2"
}
repositories {
@@ -28,31 +30,20 @@ dependencies {
//////////
// OSGI //
//////////
-
-// delete the old manifest to ensure there's no caching or merging going on
-jar.doFirst {
- project.file('META-INF/MANIFEST.MF').delete()
-}
-
-jar.manifest {
- attributes (
- 'Export-Package': 'com.jmatio.*',
- 'Bundle-SymbolicName': "${project.group}.${project.name}",
- 'Bundle-Vendor': 'DiffPlug',
- 'Bundle-DocURL': "https://github.com/${project.org}/${project.name}",
- 'Bundle-License': "https://github.com/${project.org}/${project.name}/blob/v${project.version}/LICENSE",
- '-removeheaders': 'Bnd-LastModified,Bundle-Name,Created-By,Tool',
- '-savemanifest': project.file('META-INF/MANIFEST.MF'),
- )
-}
-
-// manifests are only generated when the java files change - not if manifest properties change
-// this task forces the manifests to regenerate
-task refreshManifest(dependsOn: jar)
-gradle.taskGraph.whenReady { taskGraph ->
- if (taskGraph.hasTask(refreshManifest)) {
- jar.outputs.upToDateWhen { false }
- }
+jar.manifest.attributes (
+ 'Export-Package': 'com.jmatio.*',
+ 'Import-Package': 'sun.misc;resolution:=optional,com.jmatio.*',
+ 'Bundle-SymbolicName': "${project.group}.${project.name}",
+ 'Bundle-Description': "${project.description}",
+ 'Bundle-Vendor': 'DiffPlug',
+ 'Bundle-DocURL': "https://github.com/${project.org}/${project.name}",
+ 'Bundle-License': "https://github.com/${project.org}/${project.name}/blob/v${project.version}/LICENSE",
+ '-removeheaders': 'Bnd-LastModified,Bundle-Name,Created-By,Tool',
+ 'Automatic-Module-Name': 'com.jmatio', // Jigsaw module name
+)
+// copy the manifest into the WC
+osgiBndManifest {
+ copyTo 'META-INF/MANIFEST.MF'
}
////////////
@@ -67,9 +58,10 @@ gradle.taskGraph.whenReady { taskGraph ->
def JDK6_URL = 'https://bitbucket.org/alexkasko/openjdk-unofficial-builds/downloads/openjdk-1.6.0-unofficial-b30-windows-i586-image.zip'
def JDK6_SHA_256 = '8a119a8c9b2ecc48e8457738f57b251e6265b2c0fb232de0ff6fddce0f127045'
// place where the JRE6 will end up
-def JDK6_DIR = "${buildDir}/jdk"
-def JDK6_DST = "${JDK6_DIR}/jdk.zip"
-def JRE6_HOME = "${buildDir}/jdk/openjdk-1.6.0-unofficial-b30-windows-i586-image/jre"
+def JDK6_ROOT_DIR = "${buildDir}/jdk"
+def JDK6_DST = "${JDK6_ROOT_DIR}/jdk.zip"
+def JDK6_DIR = "${JDK6_ROOT_DIR}/unzipped"
+def JRE6_HOME = "${JDK6_DIR}/openjdk-1.6.0-unofficial-b30-windows-i586-image/jre"
import de.undercouch.gradle.tasks.download.Download;
import de.undercouch.gradle.tasks.download.Verify;
@@ -131,21 +123,21 @@ tasks.eclipse.dependsOn(cleanEclipse)
////////////
spotless {
java {
- licenseHeaderFile 'spotless.license.java' // License header file
- importOrderFile 'spotless.importorder' // An import ordering file, exported from Eclipse
- eclipseFormatFile 'spotless.eclipseformat.xml' // XML file dumped out by the Eclipse formatter
- // Eclipse formatter puts excess whitespace after lambda blocks
- // funcThatTakesLambdas(x -> {} , y -> {} ) // what Eclipse does
- // funcThatTakesLambdas(x -> {}, y -> {}) // what I wish Eclipse did
- custom 'Lambda fix', { it.replace('} )', '})').replace('} ,', '},') }
+ licenseHeaderFile 'gradle/spotless.license.java' // License header file
+ importOrderFile 'gradle/spotless.importorder' // An import ordering file, exported from Eclipse
+ eclipseFormatFile 'gradle/spotless.eclipseformat.xml' // XML file dumped out by the Eclipse formatter
+ removeUnusedImports()
}
format 'misc', {
- target '**/.gitignore', '**/*.gradle', '**/*.md', '**/*.sh'
+ target '.gitignore', '*.gradle', '*.md', '.ci/*.sh'
indentWithTabs()
trimTrailingWhitespace()
endWithNewline()
}
- freshmark {}
+ freshmark {
+ target '*.md'
+ propertiesFile('gradle.properties')
+ }
}
//////////////
@@ -155,7 +147,7 @@ apply plugin: 'findbugs'
findbugs {
toolVersion = VER_FINDBUGS
sourceSets = [sourceSets.main] // don't check the test code
- ignoreFailures = false // bug free or it doesn't ship!
+ ignoreFailures = false // no bugs or it doesn't ship
reportsDir = file('build/findbugs')
effort = 'max' // min|default|max
reportLevel = 'medium' // low|medium|high (low = sensitive to even minor mistakes)
@@ -184,6 +176,7 @@ task sourcesJar(type: Jar) {
from sourceSets.main.allJava
}
+def verSnapshot = { it.endsWith('-SNAPSHOT') ? 'snapshot' : it }
// Where it's possible to name parameters and methods clearly enough
// that javadoc is not necessary, why make the code bigger?
//
@@ -293,6 +286,23 @@ if (!isSnapshot) {
bintrayUpload.dependsOn(['generatePomFileForMavenJavaPublication', jar, sourcesJar, javadocJar])
}
+//////////////////
+// GITHUB PAGES //
+//////////////////
+githubPages {
+ repoUri = "https://github.com/${project.org}/${project.name}"
+ deleteExistingFiles = false
+ pages {
+ from javadoc.destinationDir
+ into "javadoc/${verSnapshot(version)}"
+ }
+ credentials {
+ username = cred('gh_token')
+ password = ''
+ }
+}
+tasks.prepareGhPages.dependsOn(":javadoc")
+
// helps external scripts detect version
task printVersion << {
println version
diff --git a/doc/matfile_format.pdf b/doc/matfile_format.pdf
index 8252fa2..77be1d7 100644
Binary files a/doc/matfile_format.pdf and b/doc/matfile_format.pdf differ
diff --git a/gradle.properties b/gradle.properties
index b521196..176e626 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,5 +1,5 @@
-stable=1.3.1
-version=1.4.0-SNAPSHOT
+stable=3.1.1
+version=3.2.0-SNAPSHOT
name=matfilerw
group=com.diffplug.matsim
description=MatFileRW - Read and write .mat files
diff --git a/spotless.eclipseformat.xml b/gradle/spotless.eclipseformat.xml
similarity index 93%
rename from spotless.eclipseformat.xml
rename to gradle/spotless.eclipseformat.xml
index 613e633..8dceaed 100644
--- a/spotless.eclipseformat.xml
+++ b/gradle/spotless.eclipseformat.xml
@@ -6,19 +6,23 @@
+
+
-
+
+
+
@@ -31,6 +35,7 @@
+
@@ -52,8 +57,10 @@
+
+
@@ -72,7 +79,7 @@
-
+
@@ -82,6 +89,7 @@
+
@@ -100,6 +108,7 @@
+
@@ -115,6 +124,7 @@
+
@@ -124,7 +134,7 @@
-
+
@@ -153,14 +163,17 @@
+
+
+
@@ -183,6 +196,7 @@
+
@@ -194,8 +208,10 @@
+
+
@@ -232,7 +248,7 @@
-
+
@@ -256,6 +272,7 @@
+
@@ -271,6 +288,7 @@
+
@@ -280,7 +298,7 @@
-
+
diff --git a/spotless.importorder b/gradle/spotless.importorder
similarity index 100%
rename from spotless.importorder
rename to gradle/spotless.importorder
diff --git a/spotless.license.java b/gradle/spotless.license.java
similarity index 100%
rename from spotless.license.java
rename to gradle/spotless.license.java
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
index fd7e590..3baa851 100644
Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 437f556..0fa9b6a 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
-#Tue Oct 06 21:43:04 PDT 2015
+#Sat Nov 12 18:45:38 PST 2016
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-2.7-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-3.1-bin.zip
diff --git a/gradlew b/gradlew
index 91a7e26..27309d9 100755
--- a/gradlew
+++ b/gradlew
@@ -6,12 +6,30 @@
##
##############################################################################
-# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-DEFAULT_JVM_OPTS=""
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
@@ -30,6 +48,7 @@ die ( ) {
cygwin=false
msys=false
darwin=false
+nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
@@ -40,31 +59,11 @@ case "`uname`" in
MINGW* )
msys=true
;;
+ NONSTOP* )
+ nonstop=true
+ ;;
esac
-# For Cygwin, ensure paths are in UNIX format before anything is touched.
-if $cygwin ; then
- [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
-fi
-
-# Attempt to set APP_HOME
-# Resolve links: $0 may be a link
-PRG="$0"
-# Need this for relative symlinks.
-while [ -h "$PRG" ] ; do
- ls=`ls -ld "$PRG"`
- link=`expr "$ls" : '.*-> \(.*\)$'`
- if expr "$link" : '/.*' > /dev/null; then
- PRG="$link"
- else
- PRG=`dirname "$PRG"`"/$link"
- fi
-done
-SAVED="`pwd`"
-cd "`dirname \"$PRG\"`/" >&-
-APP_HOME="`pwd -P`"
-cd "$SAVED" >&-
-
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
@@ -90,7 +89,7 @@ location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
-if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
@@ -114,6 +113,7 @@ fi
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+ JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
diff --git a/gradlew.bat b/gradlew.bat
index 8a0b282..832fdb6 100644
--- a/gradlew.bat
+++ b/gradlew.bat
@@ -8,14 +8,14 @@
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
-@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-set DEFAULT_JVM_OPTS=
-
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
@@ -46,7 +46,7 @@ echo location of your Java installation.
goto fail
:init
-@rem Get command-line arguments, handling Windowz variants
+@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
if "%@eval[2+2]" == "4" goto 4NT_args
diff --git a/license.txt b/license.txt
deleted file mode 100644
index 753fa5c..0000000
--- a/license.txt
+++ /dev/null
@@ -1,28 +0,0 @@
-Copyright (c) 2006, Wojciech Gradkowski
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * 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.
- * Neither the name of the JMatIO 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.
diff --git a/pom.xml b/pom.xml
deleted file mode 100644
index 0c86b73..0000000
--- a/pom.xml
+++ /dev/null
@@ -1,176 +0,0 @@
-
-
- 4.0.0
-
- 2.2.1
-
- ca.mjdsystems.jmatio
- jmatio
- 1.2-SNAPSHOT
-
- Matlab's MAT-file I/O API in JAVA. Supports Matlab 5 MAT-flie format reading and writing. Written in pure JAVA.
-
- jmatio
- https://github.com/MJDSys/JMatIO
-
-
- BSD
- Free for open or commercial use, with credit line
- http://www.linfo.org/bsdlicense.html
- repo
-
-
-
- https://github.com/MJDSys/JMatIO
- scm:git:https://github.com/MJDSys/jmatio.git
- scm:git:https://github.com/MJDSys/jmatio.git
- HEAD
-
-
-
- cbwatcham
- Craig Watcham
- http://sourceforge.net/users/cbwatcham/
- Sourceforge
- http://sourceforge.net/
-
- architect
- developer
-
-
-
- ss
- Sina Samangooei
- ss@ecs.soton.ac.uk
- http://www.ecs.soton.ac.uk/people/ss
- The University of Southampton
- http://www.soton.ac.uk
-
- developer
-
- 0
-
-
- mjdsys
- Matthew Dawson
- matthew@mjdsystems.ca
-
- developer
-
-
-
-
-
- junit
- junit
- 4.11
- test
-
-
-
- 1.7
- 1.7
- UTF-8
-
-
-
-
- org.apache.maven.plugins
- maven-compiler-plugin
- 3.1
-
- true
- 1.6
- 1.6
-
-
-
- org.apache.maven.plugins
- maven-deploy-plugin
- 2.8.1
-
-
- org.apache.maven.plugins
- maven-install-plugin
- 2.5.1
-
-
- org.apache.maven.plugins
- maven-jar-plugin
- 2.4
-
-
- org.apache.maven.plugins
- maven-resources-plugin
- 2.6
-
-
- org.apache.maven.plugins
- maven-site-plugin
- 3.3
-
-
- org.apache.maven.plugins
- maven-surefire-plugin
- 2.17
-
-
- org.apache.maven.plugins
- maven-clean-plugin
- 2.5
-
-
- org.apache.maven.plugins
- maven-source-plugin
- 2.2.1
-
-
- attach-sources
- verify
-
- jar-no-fork
-
-
-
-
-
- org.apache.maven.plugins
- maven-javadoc-plugin
- 2.9.1
-
-
- verify
-
- javadoc
- jar
-
-
-
-
-
- maven-assembly-plugin
- 2.4
-
- rs.jar
-
- src/main/assembly/bundle.xml
-
-
-
-
- verify
-
- single
-
-
-
-
-
-
-
- org.sonatype.oss
- oss-parent
- 9
-
-
diff --git a/project.clj b/project.clj
deleted file mode 100644
index 166f835..0000000
--- a/project.clj
+++ /dev/null
@@ -1,9 +0,0 @@
-(defproject com.callisto/JMatIO "1.1"
-
- :description "Matlab IO"
-
- :license "Copyright (c) 2006, Wojciech Gradkowski. See license.txt"
-
- :plugins [[s3-wagon-private "1.1.2"]]
-
- :java-source-paths ["src/main/java"])
diff --git a/readme.txt b/readme.txt
deleted file mode 100644
index 25a1d35..0000000
--- a/readme.txt
+++ /dev/null
@@ -1,65 +0,0 @@
-JMatIO is a JAVA library to read/write/manipulate with Matlab binary
-MAT-files.
-
-If you would like to comment, improve, critisize the project please
-email me: wgradkowski@gmail.com
-
-or visit JMatIO project page at Sourceforge:
-http://www.sourceforge.net/projects/jmatio
-
-Subversion Access
-
-This project's SourceForge.net Subversion repository can be checked out through
-SVN with the following instruction set:
-
-svn co https://jmatio.svn.sourceforge.net/svnroot/jmatio/trunk jmatio
-
-Have fun :)
-
-Wojciech Gradkowski
-
-CHANGE LOG:
-[09.05.2013]
-+ added read/write support for input/output streams (ss, jsh)
-
-[04.12.2012]
-+ adding various fixes (thanks to: Kristofer Sandlund)
-+ adding read support for objects, java objects, other types
-+ performance enhancements
-
-[05.10.2007]
-+ Sparse matrix bugfixes by Jonas Pettersson (LU/EAB)
-+ MatFileReader performance enhancements by Eugene Rudoy
-+ new MatFileReader methods added
-
-[02.03.2007]
-+ Regression bug fixed: Double arrays created natively in Matlab are read
- incorrectly (reversed byte ordering)
-
-[22.02.2007]
-+ Added support:UInt8 array
-+ MAJOR reading performance enhancement - reading is as fast as in Matlab now
-+ Removed Log4j references
-
-TODO:
-- Other array types (serialized objects (OPAQUE) is done partially)
-- Writer performance enhancement
-- Documentation and examples
-- Organize JUnit tests
-- Refactor exceptions
-- Make structures and cell arrays more user friendly
-
-NOTE:
-Numerical arrays (MLDouble, MLUint8) are now backed by direct ByteBuffers. For
-really BIG arrays the maximum heap size for direct buffers may be modified by
--XX:MaxDirectMemorySize=
-
-
-[some.time.2006]
-Currently supproted data types are:
-+ Double array
-+ Char array
-+ Structure
-+ Cell array
-+ Sparase array
-
diff --git a/src/main/java/ca/mjdsystems/jmatio/common/MatDataTypes.java b/src/main/java/ca/mjdsystems/jmatio/common/MatDataTypes.java
deleted file mode 100755
index 9918f72..0000000
--- a/src/main/java/ca/mjdsystems/jmatio/common/MatDataTypes.java
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Code licensed under new-style BSD (see LICENSE).
- * All code up to tags/original: Copyright (c) 2006, Wojciech Gradkowski
- * All code after tags/original: Copyright (c) 2015, DiffPlug
- */
-package ca.mjdsystems.jmatio.common;
-
-/**
- * MAT-file data types
- *
- * @author Wojciech Gradkowski
- */
-public class MatDataTypes {
- /* MAT-File Data Types */
- public static final int miUNKNOWN = 0;
- public static final int miINT8 = 1;
- public static final int miUINT8 = 2;
- public static final int miINT16 = 3;
- public static final int miUINT16 = 4;
- public static final int miINT32 = 5;
- public static final int miUINT32 = 6;
- public static final int miSINGLE = 7;
- public static final int miDOUBLE = 9;
- public static final int miINT64 = 12;
- public static final int miUINT64 = 13;
- public static final int miMATRIX = 14;
- public static final int miCOMPRESSED = 15;
- public static final int miUTF8 = 16;
- public static final int miUTF16 = 17;
- public static final int miUTF32 = 18;
-
- public static final int miSIZE_INT64 = 8;
- public static final int miSIZE_INT32 = 4;
- public static final int miSIZE_INT16 = 2;
- public static final int miSIZE_INT8 = 1;
- public static final int miSIZE_UINT64 = 8;
- public static final int miSIZE_UINT32 = 4;
- public static final int miSIZE_UINT16 = 2;
- public static final int miSIZE_UINT8 = 1;
- public static final int miSIZE_DOUBLE = 8;
- public static final int miSIZE_CHAR = 1;
-
- /**
- * Return number of bytes for given type.
- *
- * @param type - MatDataTypes
- * @return
- */
- public static int sizeOf(int type) {
- switch (type) {
- case MatDataTypes.miINT8:
- return miSIZE_INT8;
- case MatDataTypes.miUINT8:
- return miSIZE_UINT8;
- case MatDataTypes.miINT16:
- return miSIZE_INT16;
- case MatDataTypes.miUINT16:
- return miSIZE_UINT16;
- case MatDataTypes.miINT32:
- return miSIZE_INT32;
- case MatDataTypes.miUINT32:
- return miSIZE_UINT32;
- case MatDataTypes.miINT64:
- return miSIZE_INT64;
- case MatDataTypes.miUINT64:
- return miSIZE_UINT64;
- case MatDataTypes.miDOUBLE:
- return miSIZE_DOUBLE;
- default:
- return 1;
- }
- }
-
- /**
- * Get String representation of a data type
- *
- * @param type - data type
- * @return - String representation
- */
- public static String typeToString(int type) {
- String s;
- switch (type) {
- case MatDataTypes.miUNKNOWN:
- s = "unknown";
- break;
- case MatDataTypes.miINT8:
- s = "int8";
- break;
- case MatDataTypes.miUINT8:
- s = "uint8";
- break;
- case MatDataTypes.miINT16:
- s = "int16";
- break;
- case MatDataTypes.miUINT16:
- s = "uint16";
- break;
- case MatDataTypes.miINT32:
- s = "int32";
- break;
- case MatDataTypes.miUINT32:
- s = "uint32";
- break;
- case MatDataTypes.miSINGLE:
- s = "single";
- break;
- case MatDataTypes.miDOUBLE:
- s = "double";
- break;
- case MatDataTypes.miINT64:
- s = "int64";
- break;
- case MatDataTypes.miUINT64:
- s = "uint64";
- break;
- case MatDataTypes.miMATRIX:
- s = "matrix";
- break;
- case MatDataTypes.miCOMPRESSED:
- s = "compressed";
- break;
- case MatDataTypes.miUTF8:
- s = "uft8";
- break;
- case MatDataTypes.miUTF16:
- s = "utf16";
- break;
- case MatDataTypes.miUTF32:
- s = "utf32";
- break;
- default:
- s = "unknown";
- }
- return s;
- }
-
-}
diff --git a/src/main/java/ca/mjdsystems/jmatio/io/ByteBufferInputStream.java b/src/main/java/ca/mjdsystems/jmatio/io/ByteBufferInputStream.java
deleted file mode 100644
index 200046d..0000000
--- a/src/main/java/ca/mjdsystems/jmatio/io/ByteBufferInputStream.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Code licensed under new-style BSD (see LICENSE).
- * All code up to tags/original: Copyright (c) 2006, Wojciech Gradkowski
- * All code after tags/original: Copyright (c) 2015, DiffPlug
- */
-package ca.mjdsystems.jmatio.io;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.ByteBuffer;
-
-class ByteBufferInputStream extends InputStream {
- private ByteBuffer buf;
-
- private int limit;
-
- public ByteBufferInputStream(final ByteBuffer buf, final int limit) {
- this.buf = buf;
- this.limit = limit;
- }
-
- @Override
- public synchronized int read() throws IOException {
- if (!(limit > 0)) {
- return -1;
- }
- limit--;
- return buf.get() & 0xFF;
- }
-
- @Override
- public synchronized int read(byte[] bytes, int off, int len)
- throws IOException {
- if (!(limit > 0)) {
- return -1;
- }
- len = Math.min(len, limit);
- // Read only what's left
- buf.get(bytes, off, len);
- limit -= len;
- return len;
- }
-}
diff --git a/src/main/java/ca/mjdsystems/jmatio/io/DataOutputStream.java b/src/main/java/ca/mjdsystems/jmatio/io/DataOutputStream.java
deleted file mode 100644
index b89584e..0000000
--- a/src/main/java/ca/mjdsystems/jmatio/io/DataOutputStream.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Code licensed under new-style BSD (see LICENSE).
- * All code up to tags/original: Copyright (c) 2006, Wojciech Gradkowski
- * All code after tags/original: Copyright (c) 2015, DiffPlug
- */
-package ca.mjdsystems.jmatio.io;
-
-import java.io.IOException;
-import java.nio.ByteBuffer;
-
-interface DataOutputStream {
- /**
- * Returns the current size of this stream.
- *
- * @return the current size of this stream.
- * @throws IOException
- */
- public abstract int size() throws IOException;
-
- /**
- * Returns the current {@link ByteBuffer} mapped on the target file.
- *
- * Note: the {@link ByteBuffer} has READ ONLY access.
- *
- * @return the {@link ByteBuffer}
- * @throws IOException
- */
- public abstract ByteBuffer getByteBuffer() throws IOException;
-
- /**
- * Writes a sequence of bytes to this stream from the given buffer.
- *
- * @param byteBuffer
- * the source {@link ByteBuffer}
- * @throws IOException
- */
- public abstract void write(ByteBuffer byteBuffer) throws IOException;
-
-}
diff --git a/src/main/java/ca/mjdsystems/jmatio/io/FileBufferedDataOutputStream.java b/src/main/java/ca/mjdsystems/jmatio/io/FileBufferedDataOutputStream.java
deleted file mode 100644
index c4783eb..0000000
--- a/src/main/java/ca/mjdsystems/jmatio/io/FileBufferedDataOutputStream.java
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Code licensed under new-style BSD (see LICENSE).
- * All code up to tags/original: Copyright (c) 2006, Wojciech Gradkowski
- * All code after tags/original: Copyright (c) 2015, DiffPlug
- */
-package ca.mjdsystems.jmatio.io;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.RandomAccessFile;
-import java.nio.ByteBuffer;
-import java.nio.channels.FileChannel;
-
-import ca.mjdsystems.jmatio.types.MLArray;
-
-/**
- * This is an {@link OutputStream} that is backed by a {@link RandomAccessFile}
- * and accessed with buffered access.
- *
- * @author Wojciech Gradkowski (wgradkowski@gmail.com)
- *
- */
-class FileBufferedDataOutputStream extends OutputStream implements DataOutputStream {
- private static final int BUFFER_SIZE = 1024;
- private ByteBuffer buf;
- private final FileChannel rwChannel;
- private final RandomAccessFile raFile;
- private final File file;
-
- public FileBufferedDataOutputStream() throws IOException {
- file = File.createTempFile("jmatio-", null);
- file.deleteOnExit();
- raFile = new RandomAccessFile(file, "rw");
- rwChannel = raFile.getChannel();
- buf = ByteBuffer.allocate(BUFFER_SIZE);
- }
-
- public FileBufferedDataOutputStream(MLArray array) throws IOException {
- file = File.createTempFile("jmatio-" + array.getName() + "-", null);
- file.deleteOnExit();
- raFile = new RandomAccessFile(file, "rw");
- rwChannel = raFile.getChannel();
- buf = ByteBuffer.allocate(BUFFER_SIZE);
- }
-
- @Override
- public void write(int b) throws IOException {
- if (buf.position() >= buf.capacity()) {
- flush();
- }
-
- buf.put((byte) (b & 0xff));
- }
-
- /* (non-Javadoc)
- * @see java.io.OutputStream#write(byte[])
- */
- @Override
- public void write(byte[] b) throws IOException {
- write(b, 0, b.length);
- }
-
- /* (non-Javadoc)
- * @see java.io.OutputStream#write(byte[], int, int)
- */
- @Override
- public void write(byte[] b, int off, int len) throws IOException {
- int wbytes = len;
- int offset = off;
-
- while (wbytes > 0) {
- if (buf.position() >= buf.capacity()) {
- flush();
- }
-
- int length = Math.min(wbytes, buf.limit() - buf.position());
-
- buf.put(b, offset, length);
-
- offset += length;
- wbytes -= length;
- }
- }
-
- /* (non-Javadoc)
- * @see java.io.OutputStream#close()
- */
- @Override
- public void close() throws IOException {
- flush();
-
- buf = null;
-
- if (rwChannel.isOpen()) {
-
- rwChannel.close();
- }
-
- raFile.close();
- }
-
- /* (non-Javadoc)
- * @see java.io.OutputStream#flush()
- */
- @Override
- public void flush() throws IOException {
- if (buf != null && buf.position() > 0) {
- buf.flip();
- rwChannel.write(buf);
- buf.clear();
- }
- }
-
- /* (non-Javadoc)
- * @see ca.mjdsystems.jmatio.io.DataOutputStream#size()
- */
- public int size() throws IOException {
- flush();
-
- return (int) file.length();
- }
-
- /* (non-Javadoc)
- * @see ca.mjdsystems.jmatio.io.DataOutputStream#getByteBuffer()
- */
- public ByteBuffer getByteBuffer() throws IOException {
- return rwChannel.map(FileChannel.MapMode.READ_ONLY, 0, file.length());
- }
-
- /* (non-Javadoc)
- * @see ca.mjdsystems.jmatio.io.DataOutputStream#write(java.nio.ByteBuffer)
- */
- public void write(ByteBuffer byteBuffer) throws IOException {
- byte[] tmp = new byte[BUFFER_SIZE];
-
- while (byteBuffer.hasRemaining()) {
- int length = Math.min(byteBuffer.remaining(), tmp.length);
- byteBuffer.get(tmp, 0, length);
- write(tmp, 0, length);
- }
- }
-
-}
diff --git a/src/main/java/ca/mjdsystems/jmatio/io/MatFileFilter.java b/src/main/java/ca/mjdsystems/jmatio/io/MatFileFilter.java
deleted file mode 100644
index afaca43..0000000
--- a/src/main/java/ca/mjdsystems/jmatio/io/MatFileFilter.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Code licensed under new-style BSD (see LICENSE).
- * All code up to tags/original: Copyright (c) 2006, Wojciech Gradkowski
- * All code after tags/original: Copyright (c) 2015, DiffPlug
- */
-package ca.mjdsystems.jmatio.io;
-
-import java.util.HashSet;
-import java.util.Set;
-
-/**
- * File filter.
- *
- * This class is used to tell MatFileReader which matrices
- * should be processed. This is useful when operating on big MAT-files,
- * when there's no need to load all arrays into memory.
- *
- * Usage:
- *
- * //create new filter instance
- * MatFileFilter filter = new MatFileFilter();
- * //add a needle
- * filter.addArrayName( "your_array_name" );
- *
- * //read array form file (haystack) looking _only_ for pecified array (needle)
- * MatFileReader mfr = new MatFileReader( fileName, filter );
- *
- *
- * @see ca.mjdsystems.jmatio.io.MatFileReader
- * @author Wojciech Gradkowski (wgradkowski@gmail.com)
- */
-public class MatFileFilter {
- private Set filter;
-
- /**
- * Creates empty filter intance.
- *
- * Note: empty filter acceps all results.
- */
- public MatFileFilter() {
- filter = new HashSet();
- }
-
- /**
- * Create filter intance and add array names.
- *
- * @param names - array of names (needles)
- */
- public MatFileFilter(String[] names) {
- this();
-
- for (String name : names) {
- addArrayName(name);
- }
- }
-
- /**
- * Add array name to the filter. This array will be processed
- * while crawling thourg the MAT-file
- *
- * @param name - array name (needle)
- */
- public void addArrayName(String name) {
- filter.add(name);
- }
-
- /**
- * Test if given name matches the filter.
- *
- * @param name - array name to be tested
- * @return - true if array (matrix) of this name should be processed
- */
- public boolean matches(String name) {
- if (filter.size() == 0) {
- return true;
- }
- return filter.contains(name);
- }
-}
diff --git a/src/main/java/ca/mjdsystems/jmatio/io/MatFileHeader.java b/src/main/java/ca/mjdsystems/jmatio/io/MatFileHeader.java
deleted file mode 100755
index 0bfcb00..0000000
--- a/src/main/java/ca/mjdsystems/jmatio/io/MatFileHeader.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Code licensed under new-style BSD (see LICENSE).
- * All code up to tags/original: Copyright (c) 2006, Wojciech Gradkowski
- * All code after tags/original: Copyright (c) 2015, DiffPlug
- */
-package ca.mjdsystems.jmatio.io;
-
-import java.nio.ByteOrder;
-import java.util.Date;
-
-/**
- * MAT-file header
- *
- * Level 5 MAT-files begin with a 128-byte header made up of a 124 byte text field
- * and two, 16-bit flag fields
- *
- * @author Wojciech Gradkowski (wgradkowski@gmail.com)
- */
-public class MatFileHeader {
- private static String DEFAULT_DESCRIPTIVE_TEXT = "MATLAB 5.0 MAT-file, Platform: "
- + System.getProperty("os.name")
- + ", CREATED on: ";
- private static int DEFAULT_VERSION = 0x0100;
- private static byte[] DEFAULT_ENDIAN_INDICATOR = new byte[]{(byte) 'M', (byte) 'I'};
- private final ByteOrder byteOrder;
-
- private int version;
- private String description;
- private byte[] endianIndicator;
-
- /**
- * New MAT-file header
- *
- * @param description - descriptive text (no longer than 116 characters)
- * @param version - by default is set to 0x0100
- * @param endianIndicator - byte array size of 2 indicating byte-swapping requirement
- */
- public MatFileHeader(String description, int version, byte[] endianIndicator, ByteOrder byteOrder) {
- this.description = description;
- this.version = version;
- this.endianIndicator = endianIndicator;
- this.byteOrder = byteOrder;
- }
-
- /**
- * Gets descriptive text
- *
- * @return
- */
- public String getDescription() {
- return description;
- }
-
- /**
- * Gets endian indicator. Bytes written as "MI" suggest that byte-swapping operation is required
- * in order to interpret data correctly. If value is set to "IM" byte-swapping is not needed.
- *
- * @return - a byte array size of 2
- */
- public byte[] getEndianIndicator() {
- return endianIndicator;
- }
-
- /**
- * When creating a MAT-file, set version to 0x0100
- *
- * @return
- */
- public int getVersion() {
- return version;
- }
-
- //@facotry
- /**
- * A factory. Creates new MatFileHeader instance with default header values:
- *
- *
MAT-file is 5.0 version
- *
version is set to 0x0100
- *
no byte-swapping ("IM")
- *
- *
- * @return - new MatFileHeader instance
- */
- public static MatFileHeader createHeader() {
- return new MatFileHeader(DEFAULT_DESCRIPTIVE_TEXT + (new Date()).toString(),
- DEFAULT_VERSION,
- DEFAULT_ENDIAN_INDICATOR,
- ByteOrder.BIG_ENDIAN);
- }
-
- /* (non-Javadoc)
- * @see java.lang.Object#toString()
- */
- public String toString() {
- StringBuffer sb = new StringBuffer();
- sb.append("[");
- sb.append("desriptive text: " + description);
- sb.append(", version: " + version);
- sb.append(", endianIndicator: " + new String(endianIndicator));
- sb.append("]");
-
- return sb.toString();
- }
-
- public ByteOrder getByteOrder() {
- assert((byteOrder != ByteOrder.LITTLE_ENDIAN || endianIndicator[0] == 'I') && (byteOrder != ByteOrder.BIG_ENDIAN || endianIndicator[0] == 'M'));
- return byteOrder;
- }
-}
diff --git a/src/main/java/ca/mjdsystems/jmatio/io/MatFileIncrementalWriter.java b/src/main/java/ca/mjdsystems/jmatio/io/MatFileIncrementalWriter.java
deleted file mode 100755
index 624b060..0000000
--- a/src/main/java/ca/mjdsystems/jmatio/io/MatFileIncrementalWriter.java
+++ /dev/null
@@ -1,472 +0,0 @@
-/*
- * Code licensed under new-style BSD (see LICENSE).
- * All code up to tags/original: Copyright (c) 2006, Wojciech Gradkowski
- * All code after tags/original: Copyright (c) 2015, DiffPlug
- */
-package ca.mjdsystems.jmatio.io;
-
-import java.io.ByteArrayOutputStream;
-import java.io.DataOutputStream;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.nio.channels.WritableByteChannel;
-import java.util.Collection;
-import java.util.Set;
-import java.util.TreeSet;
-import java.util.zip.DataFormatException;
-import java.util.zip.Deflater;
-import java.util.zip.DeflaterOutputStream;
-
-import ca.mjdsystems.jmatio.common.MatDataTypes;
-import ca.mjdsystems.jmatio.types.MLArray;
-import ca.mjdsystems.jmatio.types.MLCell;
-import ca.mjdsystems.jmatio.types.MLChar;
-import ca.mjdsystems.jmatio.types.MLNumericArray;
-import ca.mjdsystems.jmatio.types.MLSparse;
-import ca.mjdsystems.jmatio.types.MLStructure;
-
-/**
- * MAT-file Incremental writer.
- *
- * An updated writer which allows adding variables incrementally
- * for the life of the writer. This is necessary to allow large
- * variables to be written without having to hold onto then longer
- * than is necessary.
- *
- * The writer internally maintains a list of the variable names
- * it has written so far, and will throw an exception if the same
- * variable name is submitted more than once to the same reader.
- *
- * Usage:
- *
- * //1. First create example arrays
- * double[] src = new double[] { 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 };
- * MLDouble mlDouble = new MLDouble( "double_arr", src, 3 );
- * MLChar mlChar = new MLChar( "char_arr", "I am dummy" );
- *
- * //2. write arrays to file
- * MatFileIncrementalWriter writer = new MatFileIncrementalWriter( new File("mat_file.mat"));
- * writer.write(mlDouble);
- * writer.write(mlChar);
- *
- * writer.close();
- *
- *
- *
- * @author
- */
-public class MatFileIncrementalWriter {
- // private static final Logger logger = Logger.getLogger(MatFileWriter.class);
- private WritableByteChannel channel = null;
-
- private boolean headerWritten = false;
- private boolean isStillValid = false;
- private Set varNames = new TreeSet();
-
- /**
- * Creates a writer to a file given the filename.
- *
- * @param fileName - name of ouput file
- * @throws IOException
- * @throws DataFormatException
- */
- public MatFileIncrementalWriter(String fileName) throws IOException {
- this(new File(fileName));
- }
-
- /**
- * Creats a writer to a file given the File object.
- *
- * @param file - an output File
- * @throws IOException
- * @throws DataFormatException
- */
- public MatFileIncrementalWriter(File file) throws IOException {
- this((new FileOutputStream(file)).getChannel());
- }
-
- /**
- * Creates a writer for a file, given an output channel to the file..
- *
- * Writes MAT-file header and compressed data (miCOMPRESSED).
- *
- * @param chan - WritableByteChannel
- * @param data - Collection of MLArray elements
- * @throws IOException
- */
- public MatFileIncrementalWriter(WritableByteChannel chan) throws IOException {
- this.channel = chan;
- isStillValid = true;
- }
-
- public synchronized void write(MLArray data)
- throws IOException {
- String vName = data.getName();
- if (varNames.contains(vName)) {
- throw new IllegalArgumentException("Error: variable " + vName + " specified more than once for file input.");
- }
- try {
- //write the header, but only once.
- if (!headerWritten) {
- writeHeader(channel);
- }
-
- //prepare buffer for MATRIX data
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- DataOutputStream dos = new DataOutputStream(baos);
- //write MATRIX bytes into buffer
- writeMatrix(dos, data);
-
- //compress data to save storage
- Deflater compresser = new Deflater();
-
- byte[] input = baos.toByteArray();
-
- ByteArrayOutputStream compressed = new ByteArrayOutputStream();
- DataOutputStream dout = new DataOutputStream(new DeflaterOutputStream(compressed, compresser));
-
- dout.write(input);
-
- dout.close();
- compressed.close();
-
- //write COMPRESSED tag and compressed data into output channel
- byte[] compressedBytes = compressed.toByteArray();
- ByteBuffer buf = ByteBuffer.allocateDirect(2 * 4 /* Int size */ + compressedBytes.length);
- buf.putInt(MatDataTypes.miCOMPRESSED);
- buf.putInt(compressedBytes.length);
- buf.put(compressedBytes);
-
- buf.flip();
- channel.write(buf);
- } catch (IOException e) {
- throw e;
- } finally {}
- }
-
- /**
- * Writes MLArrays into WritableByteChannel.
- *
- * @param channel
- * the channel to write to
- * @param data
- * the collection of {@link MLArray} objects
- * @throws IOException
- * if writing fails
- */
- public synchronized void write(Collection data) throws IOException {
- try {
-
- //write data
- for (MLArray matrix : data) {
- write(matrix);
- }
- } catch (IllegalArgumentException iae) {
- isStillValid = false;
- throw iae;
- } catch (IOException e) {
- throw e;
- }
- }
-
- public synchronized void close() throws IOException {
- channel.close();
- }
-
- /**
- * Writes MAT-file header into OutputStream
- * @param os OutputStream
- * @throws IOException
- */
- private void writeHeader(WritableByteChannel channel) throws IOException {
- //write descriptive text
- MatFileHeader header = MatFileHeader.createHeader();
- char[] dest = new char[116];
- char[] src = header.getDescription().toCharArray();
- System.arraycopy(src, 0, dest, 0, src.length);
-
- byte[] endianIndicator = header.getEndianIndicator();
-
- ByteBuffer buf = ByteBuffer.allocateDirect(dest.length * 2 /* Char size */ + 2 + endianIndicator.length);
-
- for (int i = 0; i < dest.length; i++) {
- buf.put((byte) dest[i]);
- }
- //write subsyst data offset
- buf.position(buf.position() + 8);
-
- //write version
- int version = header.getVersion();
- buf.put((byte) (version >> 8));
- buf.put((byte) version);
-
- buf.put(endianIndicator);
-
- buf.flip();
- channel.write(buf);
-
- headerWritten = true;
- }
-
- /**
- * Writes MATRIX into OutputStream.
- *
- * @param os - OutputStream
- * @param array - a MLArray
- * @throws IOException
- */
- private void writeMatrix(DataOutputStream output, MLArray array) throws IOException {
- OSArrayTag tag;
- ByteArrayOutputStream buffer;
- DataOutputStream bufferDOS;
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- DataOutputStream dos = new DataOutputStream(baos);
-
- //flags
- writeFlags(dos, array);
-
- //dimensions
- writeDimensions(dos, array);
-
- //array name
- writeName(dos, array);
-
- switch (array.getType()) {
- case MLArray.mxCHAR_CLASS:
- //write char data
- buffer = new ByteArrayOutputStream();
- bufferDOS = new DataOutputStream(buffer);
- Character[] ac = ((MLChar) array).exportChar();
- for (int i = 0; i < ac.length; i++) {
- bufferDOS.writeByte((byte) ac[i].charValue());
- }
- tag = new OSArrayTag(MatDataTypes.miUTF8, buffer.toByteArray());
- tag.writeTo(dos);
-
- break;
- case MLArray.mxDOUBLE_CLASS:
-
- tag = new OSArrayTag(MatDataTypes.miDOUBLE,
- ((MLNumericArray>) array).getRealByteBuffer());
- tag.writeTo(dos);
-
- //write real imaginary
- if (array.isComplex()) {
- tag = new OSArrayTag(MatDataTypes.miDOUBLE,
- ((MLNumericArray>) array).getImaginaryByteBuffer());
- tag.writeTo(dos);
- }
- break;
- case MLArray.mxUINT8_CLASS:
-
- tag = new OSArrayTag(MatDataTypes.miUINT8,
- ((MLNumericArray>) array).getRealByteBuffer());
- tag.writeTo(dos);
-
- //write real imaginary
- if (array.isComplex()) {
- tag = new OSArrayTag(MatDataTypes.miUINT8,
- ((MLNumericArray>) array).getImaginaryByteBuffer());
- tag.writeTo(dos);
- }
- break;
- case MLArray.mxINT8_CLASS:
-
- tag = new OSArrayTag(MatDataTypes.miINT8,
- ((MLNumericArray>) array).getRealByteBuffer());
- tag.writeTo(dos);
-
- //write real imaginary
- if (array.isComplex()) {
- tag = new OSArrayTag(MatDataTypes.miINT8,
- ((MLNumericArray>) array).getImaginaryByteBuffer());
- tag.writeTo(dos);
- }
- break;
- case MLArray.mxINT16_CLASS:
-
- tag = new OSArrayTag(MatDataTypes.miINT16,
- ((MLNumericArray>) array).getRealByteBuffer());
- tag.writeTo(dos);
-
- //write real imaginary
- if (array.isComplex()) {
- tag = new OSArrayTag(MatDataTypes.miINT16,
- ((MLNumericArray>) array).getImaginaryByteBuffer());
- tag.writeTo(dos);
- }
- break;
- case MLArray.mxINT64_CLASS:
-
- tag = new OSArrayTag(MatDataTypes.miINT64,
- ((MLNumericArray>) array).getRealByteBuffer());
- tag.writeTo(dos);
-
- //write real imaginary
- if (array.isComplex()) {
- tag = new OSArrayTag(MatDataTypes.miINT64,
- ((MLNumericArray>) array).getImaginaryByteBuffer());
- tag.writeTo(dos);
- }
- break;
- case MLArray.mxUINT64_CLASS:
-
- tag = new OSArrayTag(MatDataTypes.miUINT64,
- ((MLNumericArray>) array).getRealByteBuffer());
- tag.writeTo(dos);
-
- //write real imaginary
- if (array.isComplex()) {
- tag = new OSArrayTag(MatDataTypes.miUINT64,
- ((MLNumericArray>) array).getImaginaryByteBuffer());
- tag.writeTo(dos);
- }
- break;
- case MLArray.mxSTRUCT_CLASS:
- //field name length
- int itag = 4 << 16 | MatDataTypes.miINT32 & 0xffff;
- dos.writeInt(itag);
- dos.writeInt(((MLStructure) array).getMaxFieldLenth());
-
- //get field names
- tag = new OSArrayTag(MatDataTypes.miINT8, ((MLStructure) array).getKeySetToByteArray());
- tag.writeTo(dos);
-
- for (MLArray a : ((MLStructure) array).getAllFields()) {
- writeMatrix(dos, a);
- }
- break;
- case MLArray.mxCELL_CLASS:
- for (MLArray a : ((MLCell) array).cells()) {
- writeMatrix(dos, a);
- }
- break;
- case MLArray.mxSPARSE_CLASS:
- int[] ai;
- //write ir
- buffer = new ByteArrayOutputStream();
- bufferDOS = new DataOutputStream(buffer);
- ai = ((MLSparse) array).getIR();
- for (int i : ai) {
- bufferDOS.writeInt(i);
- }
- tag = new OSArrayTag(MatDataTypes.miINT32, buffer.toByteArray());
- tag.writeTo(dos);
- //write jc
- buffer = new ByteArrayOutputStream();
- bufferDOS = new DataOutputStream(buffer);
- ai = ((MLSparse) array).getJC();
- for (int i : ai) {
- bufferDOS.writeInt(i);
- }
- tag = new OSArrayTag(MatDataTypes.miINT32, buffer.toByteArray());
- tag.writeTo(dos);
- //write real
- buffer = new ByteArrayOutputStream();
- bufferDOS = new DataOutputStream(buffer);
-
- Double[] ad = ((MLSparse) array).exportReal();
-
- for (int i = 0; i < ad.length; i++) {
- bufferDOS.writeDouble(ad[i].doubleValue());
- }
-
- tag = new OSArrayTag(MatDataTypes.miDOUBLE, buffer.toByteArray());
- tag.writeTo(dos);
- //write real imaginary
- if (array.isComplex()) {
- buffer = new ByteArrayOutputStream();
- bufferDOS = new DataOutputStream(buffer);
- ad = ((MLSparse) array).exportImaginary();
- for (int i = 0; i < ad.length; i++) {
- bufferDOS.writeDouble(ad[i].doubleValue());
- }
- tag = new OSArrayTag(MatDataTypes.miDOUBLE, buffer.toByteArray());
- tag.writeTo(dos);
- }
- break;
- default:
- throw new MatlabIOException("Cannot write matrix of type: " + MLArray.typeToString(array.getType()));
-
- }
-
- //write matrix
- output.writeInt(MatDataTypes.miMATRIX); //matrix tag
- output.writeInt(baos.size()); //size of matrix
- output.write(baos.toByteArray()); //matrix data
- }
-
- /**
- * Writes MATRIX flags into OutputStream.
- *
- * @param os - OutputStream
- * @param array - a MLArray
- * @throws IOException
- */
- private void writeFlags(DataOutputStream os, MLArray array) throws IOException {
- ByteArrayOutputStream buffer = new ByteArrayOutputStream();
- DataOutputStream bufferDOS = new DataOutputStream(buffer);
-
- bufferDOS.writeInt(array.getFlags());
-
- if (array.isSparse()) {
- bufferDOS.writeInt(((MLSparse) array).getMaxNZ());
- } else {
- bufferDOS.writeInt(0);
- }
- OSArrayTag tag = new OSArrayTag(MatDataTypes.miUINT32, buffer.toByteArray());
- tag.writeTo(os);
-
- }
-
- /**
- * Writes MATRIX dimensions into OutputStream.
- *
- * @param os - OutputStream
- * @param array - a MLArray
- * @throws IOException
- */
- private void writeDimensions(DataOutputStream os, MLArray array) throws IOException {
- ByteArrayOutputStream buffer = new ByteArrayOutputStream();
- DataOutputStream bufferDOS = new DataOutputStream(buffer);
-
- int[] dims = array.getDimensions();
- for (int i = 0; i < dims.length; i++) {
- bufferDOS.writeInt(dims[i]);
- }
- OSArrayTag tag = new OSArrayTag(MatDataTypes.miINT32, buffer.toByteArray());
- tag.writeTo(os);
-
- }
-
- /**
- * Writes MATRIX name into OutputStream.
- *
- * @param os - OutputStream
- * @param array - a MLArray
- * @throws IOException
- */
- private void writeName(DataOutputStream os, MLArray array) throws IOException {
- ByteArrayOutputStream buffer = new ByteArrayOutputStream();
- DataOutputStream bufferDOS = new DataOutputStream(buffer);
-
- byte[] nameByteArray = array.getNameToByteArray();
- buffer = new ByteArrayOutputStream();
- bufferDOS = new DataOutputStream(buffer);
- bufferDOS.write(nameByteArray);
- OSArrayTag tag = new OSArrayTag(MatDataTypes.miINT8, buffer.toByteArray());
- tag.writeTo(os);
- }
-
-}
diff --git a/src/main/java/ca/mjdsystems/jmatio/io/MatFileInputStream.java b/src/main/java/ca/mjdsystems/jmatio/io/MatFileInputStream.java
deleted file mode 100644
index a591ef4..0000000
--- a/src/main/java/ca/mjdsystems/jmatio/io/MatFileInputStream.java
+++ /dev/null
@@ -1,285 +0,0 @@
-/*
- * Code licensed under new-style BSD (see LICENSE).
- * All code up to tags/original: Copyright (c) 2006, Wojciech Gradkowski
- * All code after tags/original: Copyright (c) 2015, DiffPlug
- */
-package ca.mjdsystems.jmatio.io;
-
-import java.io.IOException;
-import java.nio.ByteBuffer;
-
-import ca.mjdsystems.jmatio.common.MatDataTypes;
-import ca.mjdsystems.jmatio.types.ByteStorageSupport;
-
-/**
- * MAT-file input stream class.
- *
- * @author Wojciech Gradkowski
- */
-class MatFileInputStream {
- private final int type;
- private final ByteBuffer buf;
-
- /**
- * Attach MAT-file input stream to InputStream
- *
- * @param is - input stream
- * @param type - type of data in the stream
- * @see ca.mjdsystems.jmatio.common.MatDataTypes
- */
- public MatFileInputStream(ByteBuffer buf, int type) {
- this.type = type;
- this.buf = buf;
- }
-
- /**
- * Reads data (number of bytes red is determined by data type)
- * from the stream to int.
- *
- * @return
- * @throws IOException
- */
- public int readInt() throws IOException {
- switch (type) {
- case MatDataTypes.miUINT8:
- return (int) (buf.get() & 0xFF);
- case MatDataTypes.miINT8:
- return (int) buf.get();
- case MatDataTypes.miUINT16:
- return (int) (buf.getShort() & 0xFFFF);
- case MatDataTypes.miINT16:
- return (int) buf.getShort();
- case MatDataTypes.miUINT32:
- return (int) (buf.getInt() & 0xFFFFFFFF);
- case MatDataTypes.miINT32:
- return (int) buf.getInt();
- case MatDataTypes.miUINT64:
- return (int) buf.getLong();
- case MatDataTypes.miINT64:
- return (int) buf.getLong();
- case MatDataTypes.miDOUBLE:
- return (int) buf.getDouble();
- default:
- throw new IllegalArgumentException("Unknown data type: " + type);
- }
- }
-
- /**
- * Reads data (number of bytes red is determined by data type)
- * from the stream to char.
- *
- * @return - char
- * @throws IOException
- */
- public char readChar() throws IOException {
- switch (type) {
- case MatDataTypes.miUINT8:
- return (char) (buf.get() & 0xFF);
- case MatDataTypes.miINT8:
- return (char) buf.get();
- case MatDataTypes.miUINT16:
- return (char) (buf.getShort() & 0xFFFF);
- case MatDataTypes.miINT16:
- return (char) buf.getShort();
- case MatDataTypes.miUINT32:
- return (char) (buf.getInt() & 0xFFFFFFFF);
- case MatDataTypes.miINT32:
- return (char) buf.getInt();
- case MatDataTypes.miDOUBLE:
- return (char) buf.getDouble();
- case MatDataTypes.miUTF8:
- return (char) buf.get();
- default:
- throw new IllegalArgumentException("Unknown data type: " + type);
- }
- }
-
- /**
- * Reads data (number of bytes red is determined by data type)
- * from the stream to double.
- *
- * @return - double
- * @throws IOException
- */
- public double readDouble() throws IOException {
- switch (type) {
- case MatDataTypes.miUINT8:
- return (double) (buf.get() & 0xFF);
- case MatDataTypes.miINT8:
- return (double) buf.get();
- case MatDataTypes.miUINT16:
- return (double) (buf.getShort() & 0xFFFF);
- case MatDataTypes.miINT16:
- return (double) buf.getShort();
- case MatDataTypes.miUINT32:
- return (double) (buf.getInt() & 0xFFFFFFFF);
- case MatDataTypes.miINT32:
- return (double) buf.getInt();
- case MatDataTypes.miDOUBLE:
- return (double) buf.getDouble();
- default:
- throw new IllegalArgumentException("Unknown data type: " + type);
- }
- }
-
- public byte readByte() {
- switch (type) {
- case MatDataTypes.miUINT8:
- return (byte) (buf.get() & 0xFF);
- case MatDataTypes.miINT8:
- return (byte) buf.get();
- case MatDataTypes.miUINT16:
- return (byte) (buf.getShort() & 0xFFFF);
- case MatDataTypes.miINT16:
- return (byte) buf.getShort();
- case MatDataTypes.miUINT32:
- return (byte) (buf.getInt() & 0xFFFFFFFF);
- case MatDataTypes.miINT32:
- return (byte) buf.getInt();
- case MatDataTypes.miDOUBLE:
- return (byte) buf.getDouble();
- case MatDataTypes.miUTF8:
- return (byte) buf.get();
- default:
- throw new IllegalArgumentException("Unknown data type: " + type);
- }
- }
-
- /**
- * Reads the data into a {@link ByteBuffer}. This method is
- * only supported for arrays with backing ByteBuffer ({@link ByteStorageSupport}).
- *
- * @param dest
- * the destination {@link ByteBuffer}
- * @param elements
- * the number of elements to read into a buffer
- * @param storage
- * the backing {@link ByteStorageSupport} that
- * gives information how data should be interpreted
- * @return reference to the destination {@link ByteBuffer}
- * @throws IOException
- * if buffer is under-fed, or another IO problem occurs
- */
- public ByteBuffer readToByteBuffer(ByteBuffer dest, int elements,
- ByteStorageSupport> storage) throws IOException {
-
- int bytesAllocated = storage.getBytesAllocated();
- int size = elements * storage.getBytesAllocated();
-
- //direct buffer copy
- if (MatDataTypes.sizeOf(type) == bytesAllocated && buf.order().equals(dest.order())) {
- int bufMaxSize = 1024;
- int bufSize = Math.min(buf.remaining(), bufMaxSize);
- int bufPos = buf.position();
-
- byte[] tmp = new byte[bufSize];
-
- while (dest.remaining() > 0) {
- int length = Math.min(dest.remaining(), tmp.length);
- buf.get(tmp, 0, length);
- dest.put(tmp, 0, length);
- }
- buf.position(bufPos + size);
- } else {
- //because Matlab writes data not respectively to the declared
- //matrix type, the reading is not straight forward (as above)
- Class> clazz = storage.getStorageClazz();
- while (dest.remaining() > 0) {
- if (clazz.equals(Double.class)) {
- dest.putDouble(readDouble());
- } else if (clazz.equals(Byte.class)) {
- dest.put(readByte());
- } else if (clazz.equals(Integer.class)) {
- dest.putInt(readInt());
- } else if (clazz.equals(Long.class)) {
- dest.putLong(readLong());
- } else if (clazz.equals(Float.class)) {
- dest.putFloat(readFloat());
- } else if (clazz.equals(Short.class)) {
- dest.putShort(readShort());
- } else {
- throw new RuntimeException("Not supported buffer reader for " + clazz);
- }
- }
- }
- dest.rewind();
- return dest;
- }
-
- private float readFloat() {
- switch (type) {
- case MatDataTypes.miUINT8:
- return (float) (buf.get() & 0xFF);
- case MatDataTypes.miINT8:
- return (float) buf.get();
- case MatDataTypes.miUINT16:
- return (float) (buf.getShort() & 0xFFFF);
- case MatDataTypes.miINT16:
- return (float) buf.getShort();
- case MatDataTypes.miUINT32:
- return (float) (buf.getInt() & 0xFFFFFFFF);
- case MatDataTypes.miINT32:
- return (float) buf.getInt();
- case MatDataTypes.miSINGLE:
- return (float) buf.getFloat();
- case MatDataTypes.miDOUBLE:
- return (float) buf.getDouble();
- default:
- throw new IllegalArgumentException("Unknown data type: " + type);
- }
- }
-
- private short readShort() {
- switch (type) {
- case MatDataTypes.miUINT8:
- return (short) (buf.get() & 0xFF);
- case MatDataTypes.miINT8:
- return (short) buf.get();
- case MatDataTypes.miUINT16:
- return (short) (buf.getShort() & 0xFFFF);
- case MatDataTypes.miINT16:
- return (short) buf.getShort();
- case MatDataTypes.miUINT32:
- return (short) (buf.getInt() & 0xFFFFFFFF);
- case MatDataTypes.miINT32:
- return (short) buf.getInt();
- case MatDataTypes.miUINT64:
- return (short) buf.getLong();
- case MatDataTypes.miINT64:
- return (short) buf.getLong();
- case MatDataTypes.miDOUBLE:
- return (short) buf.getDouble();
- default:
- throw new IllegalArgumentException("Unknown data type: " + type);
- }
- }
-
- private long readLong() {
- switch (type) {
- case MatDataTypes.miUINT8:
- return (long) (buf.get() & 0xFF);
- case MatDataTypes.miINT8:
- return (long) buf.get();
- case MatDataTypes.miUINT16:
- return (long) (buf.getShort() & 0xFFFF);
- case MatDataTypes.miINT16:
- return (long) buf.getShort();
- case MatDataTypes.miUINT32:
- return (long) (buf.getInt() & 0xFFFFFFFF);
- case MatDataTypes.miINT32:
- return (long) buf.getInt();
- case MatDataTypes.miUINT64:
- return (long) buf.getLong();
- case MatDataTypes.miINT64:
- return (long) buf.getLong();
- case MatDataTypes.miDOUBLE:
- return (long) buf.getDouble();
- default:
- throw new IllegalArgumentException("Unknown data type: " + type);
- }
- }
-
- public void skip(int padding) {
- buf.position(buf.position() + padding);
- }
-}
diff --git a/src/main/java/ca/mjdsystems/jmatio/io/MatFileReader.java b/src/main/java/ca/mjdsystems/jmatio/io/MatFileReader.java
deleted file mode 100755
index 935dcf9..0000000
--- a/src/main/java/ca/mjdsystems/jmatio/io/MatFileReader.java
+++ /dev/null
@@ -1,1441 +0,0 @@
-/*
- * Code licensed under new-style BSD (see LICENSE).
- * All code up to tags/original: Copyright (c) 2006, Wojciech Gradkowski
- * All code after tags/original: Copyright (c) 2015, DiffPlug
- */
-package ca.mjdsystems.jmatio.io;
-
-import java.io.EOFException;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.ObjectInputStream;
-import java.io.RandomAccessFile;
-import java.lang.ref.WeakReference;
-import java.lang.reflect.Method;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.nio.MappedByteBuffer;
-import java.nio.channels.FileChannel;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.util.*;
-import java.util.zip.InflaterInputStream;
-
-import ca.mjdsystems.jmatio.common.MatDataTypes;
-import ca.mjdsystems.jmatio.io.MatFileWriter.ByteArrayOutputStream2;
-import ca.mjdsystems.jmatio.types.ByteStorageSupport;
-import ca.mjdsystems.jmatio.types.MLArray;
-import ca.mjdsystems.jmatio.types.MLCell;
-import ca.mjdsystems.jmatio.types.MLChar;
-import ca.mjdsystems.jmatio.types.MLDouble;
-import ca.mjdsystems.jmatio.types.MLEmptyArray;
-import ca.mjdsystems.jmatio.types.MLInt16;
-import ca.mjdsystems.jmatio.types.MLInt32;
-import ca.mjdsystems.jmatio.types.MLInt64;
-import ca.mjdsystems.jmatio.types.MLInt8;
-import ca.mjdsystems.jmatio.types.MLJavaObject;
-import ca.mjdsystems.jmatio.types.MLNumericArray;
-import ca.mjdsystems.jmatio.types.MLObject;
-import ca.mjdsystems.jmatio.types.MLSingle;
-import ca.mjdsystems.jmatio.types.MLSparse;
-import ca.mjdsystems.jmatio.types.MLStructure;
-import ca.mjdsystems.jmatio.types.MLUInt32;
-import ca.mjdsystems.jmatio.types.MLUInt64;
-import ca.mjdsystems.jmatio.types.MLUInt8;
-
-/**
- * MAT-file reader. Reads MAT-file into MLArray objects.
- *
- * Usage:
- *
- * //read in the file
- * MatFileReader mfr = new MatFileReader( "mat_file.mat" );
- *
- * //get array of a name "my_array" from file
- * MLArray mlArrayRetrived = mfr.getMLArray( "my_array" );
- *
- * //or get the collection of all arrays that were stored in the file
- * Map content = mfr.getContent();
- *
- *
- * @see ca.mjdsystems.jmatio.io.MatFileFilter
- * @author Wojciech Gradkowski (wgradkowski@gmail.com)
- */
-/**
- * @author Wojciech Gradkowski (wgradkowski@gmail.com)
- *
- */
-public class MatFileReader {
- public static final int MEMORY_MAPPED_FILE = 1;
- public static final int DIRECT_BYTE_BUFFER = 2;
- public static final int HEAP_BYTE_BUFFER = 4;
-
- /**
- * Type of matlab mat file.
- */
- private final MatFileType matType;
- /**
- * MAT-file header
- */
- private MatFileHeader matFileHeader;
- /**
- * Container for red MLArrays
- */
- private Map data;
- /**
- * Tells how bytes are organized in the buffer.
- */
- private ByteOrder byteOrder;
- /**
- * Array name filter
- */
- private MatFileFilter filter;
- /**
- * Whether or not we have found an MCOS type variable. Needed to know if further processing is needed.
- */
- private boolean haveMCOS = false;
- /**
- * Holds the likely candidate for the MCOS extra data at the end of a MAT file.
- */
- private MLUInt8 mcosData;
-
- /**
- * Creates instance of MatFileReader and reads MAT-file
- * from location given as fileName.
- *
- * This method reads MAT-file without filtering.
- *
- * @param fileName the MAT-file path String
- * @throws IOException when error occurred while processing the file.
- */
- public MatFileReader(String fileName) throws FileNotFoundException, IOException {
- this(new File(fileName), new MatFileFilter(), MatFileType.Regular);
- }
-
- /**
- * Creates instance of MatFileReader and reads MAT-file
- * from location given as fileName.
- *
- * Results are filtered by MatFileFilter. Arrays that do not meet
- * filter match condition will not be available in results.
- *
- * @param fileName the MAT-file path String
- * @param MatFileFilter array name filter.
- * @throws IOException when error occurred while processing the file.
- */
- public MatFileReader(String fileName, MatFileFilter filter) throws IOException {
- this(new File(fileName), filter, MatFileType.Regular);
- }
-
- /**
- * Creates instance of MatFileReader and reads MAT-file
- * from file.
- *
- * This method reads MAT-file without filtering.
- *
- * @param file the MAT-file
- * @throws IOException when error occurred while processing the file.
- */
- public MatFileReader(File file) throws IOException {
- this(file, new MatFileFilter(), MatFileType.Regular);
-
- }
-
- /**
- * Creates instance of MatFileReader and reads MAT-file from
- * file.
- *
- * Results are filtered by MatFileFilter. Arrays that do not
- * meet filter match condition will not be available in results.
- *
- * Note: this method reads file using the memory mapped file policy, see
- * notes to {@link #read(File, MatFileFilter, ca.mjdsystems.jmatio.io.MatFileReader.MallocPolicy)}
- *
- * @param file
- * the MAT-file
- * @param MatFileFilter
- * array name filter.
- * @throws IOException
- * when error occurred while processing the file.
- */
- public MatFileReader(File file, MatFileFilter filter, MatFileType matType) throws IOException {
- this(matType);
-
- read(file, filter, MEMORY_MAPPED_FILE);
- }
-
- public MatFileReader(MatFileType matType) {
- this.matType = matType;
- filter = new MatFileFilter();
- data = new LinkedHashMap();
- }
-
- /**
- * Creates instance of MatFileReader and reads MAT-file from
- * file.
- *
- * This method reads MAT-file without filtering.
- *
- * @param stream
- * the MAT-file stream
- * @throws IOException
- * when error occurred while processing the file.
- */
- public MatFileReader(InputStream stream, MatFileType type) throws IOException {
- this(stream, new MatFileFilter(), type);
- }
-
- /**
- * Creates instance of MatFileReader and reads MAT-file from
- * file.
- *
- * Results are filtered by MatFileFilter. Arrays that do not
- * meet filter match condition will not be available in results.
- *
- * Note: this method reads file using the memory mapped file policy, see
- * notes to
- * {@link #read(File, MatFileFilter, ca.mjdsystems.jmatio.io.MatFileReader.MallocPolicy)}
- *
- *
- * @param stream
- * the MAT-file stream
- * @param MatFileFilter
- * array name filter.
- * @throws IOException
- * when error occurred while processing the file.
- */
- public MatFileReader(InputStream stream, MatFileFilter filter, MatFileType type) throws IOException {
- this(type);
-
- read(stream, filter);
- }
-
- /**
- * Reads the content of a MAT-file and returns the mapped content.
- *
- * This method calls
- * read(file, new MatFileFilter(), MallocPolicy.MEMORY_MAPPED_FILE).
- *
- * @param file
- * a valid MAT-file file to be read
- * @return the same as {@link #getContent()}
- * @throws IOException
- * if error occurs during file processing
- */
- public synchronized Map read(File file) throws IOException {
- return read(file, new MatFileFilter(), MEMORY_MAPPED_FILE);
- }
-
- /**
- * Reads the content of a MAT-file and returns the mapped content.
- *
- * This method calls read(stream, new MatFileFilter()).
- *
- * @param stream
- * a valid MAT-file stream to be read
- * @return the same as {@link #getContent()}
- * @throws IOException
- * if error occurs during file processing
- */
- public synchronized Map read(InputStream stream) throws IOException {
- return read(stream, new MatFileFilter());
- }
-
- /**
- * Reads the content of a MAT-file and returns the mapped content.
- *
- * This method calls
- * read(file, new MatFileFilter(), policy).
- *
- * @param file
- * a valid MAT-file file to be read
- * @param policy
- * the file memory allocation policy
- * @return the same as {@link #getContent()}
- * @throws IOException
- * if error occurs during file processing
- */
- public synchronized Map read(File file, int policy) throws IOException {
- return read(file, new MatFileFilter(), policy);
- }
-
- /**
- * Reads the content of a MAT-file and returns the mapped content.
- *
- * Because of java bug #4724038
- * which disables releasing the memory mapped resource, additional different
- * allocation modes are available.
- *
- *
{@link #MEMORY_MAPPED_FILE} - a memory mapped file
- *
{@link #DIRECT_BYTE_BUFFER} - a uses
- * {@link ByteBuffer#allocateDirect(int)} method to read in
- * the file contents
- *
{@link #HEAP_BYTE_BUFFER} - a uses
- * {@link ByteBuffer#allocate(int)} method to read in the
- * file contents
- *
- * Note: memory mapped file will try to invoke a nasty code to relase
- * it's resources
- *
- * @param file
- * a valid MAT-file file to be read
- * @param filter
- * the array filter applied during reading
- * @param policy
- * the file memory allocation policy
- * @return the same as {@link #getContent()}
- * @see MatFileFilter
- * @throws IOException
- * if error occurs during file processing
- */
- private static final int DIRECT_BUFFER_LIMIT = 1 << 25;
-
- public synchronized Map read(File file, MatFileFilter filter,
- int policy) throws IOException {
- this.filter = filter;
-
- //clear the results
- for (String key : data.keySet()) {
- data.remove(key);
- }
-
- FileChannel roChannel = null;
- RandomAccessFile raFile = null;
- ByteBuffer buf = null;
- WeakReference bufferWeakRef = null;
- try {
- //Create a read-only memory-mapped file
- raFile = new RandomAccessFile(file, "r");
- roChannel = raFile.getChannel();
- // until java bug #4715154 is fixed I am not using memory mapped files
- // The bug disables re-opening the memory mapped files for writing
- // or deleting until the VM stops working. In real life I need to open
- // and update files
- switch (policy) {
- case DIRECT_BYTE_BUFFER:
- buf = ByteBuffer.allocateDirect((int) roChannel.size());
- roChannel.read(buf, 0);
- buf.rewind();
- break;
- case HEAP_BYTE_BUFFER:
- int filesize = (int) roChannel.size();
- System.gc();
- buf = ByteBuffer.allocate(filesize);
-
- // The following two methods couldn't be used (at least under MS Windows)
- // since they are implemented in a suboptimal way. Each of them
- // allocates its own _direct_ buffer of exactly the same size,
- // the buffer passed as parameter has, reads data into it and
- // only afterwards moves data into the buffer passed as parameter.
- // roChannel.read(buf, 0); // ends up in outOfMemory
- // raFile.readFully(buf.array()); // ends up in outOfMemory
- int numberOfBlocks = filesize / DIRECT_BUFFER_LIMIT + ((filesize % DIRECT_BUFFER_LIMIT) > 0 ? 1 : 0);
- if (numberOfBlocks > 1) {
- ByteBuffer tempByteBuffer = ByteBuffer.allocateDirect(DIRECT_BUFFER_LIMIT);
- for (int block = 0; block < numberOfBlocks; block++) {
- tempByteBuffer.clear();
- roChannel.read(tempByteBuffer, block * DIRECT_BUFFER_LIMIT);
- tempByteBuffer.flip();
- buf.put(tempByteBuffer);
- }
- tempByteBuffer = null;
- } else
- roChannel.read(buf, 0);
-
- buf.rewind();
- break;
- case MEMORY_MAPPED_FILE:
- buf = roChannel.map(FileChannel.MapMode.READ_ONLY, 0, (int) roChannel.size());
- bufferWeakRef = new WeakReference((MappedByteBuffer) buf);
- break;
- default:
- throw new IllegalArgumentException("Unknown file allocation policy");
- }
- // Do the actual work.
- parseData(buf);
-
- return getContent();
- } catch (IOException e) {
- throw e;
- } finally {
- if (roChannel != null) {
- roChannel.close();
- }
- if (raFile != null) {
- raFile.close();
- }
- if (buf != null && bufferWeakRef != null && policy == MEMORY_MAPPED_FILE) {
- try {
- clean(buf);
- } catch (Exception e) {
- int GC_TIMEOUT_MS = 1000;
- buf = null;
- long start = System.currentTimeMillis();
- while (bufferWeakRef.get() != null) {
- if (System.currentTimeMillis() - start > GC_TIMEOUT_MS) {
- break; //a hell cannot be unmapped - hopefully GC will
- //do it's job later
- }
- System.gc();
- Thread.yield();
- }
- }
- }
- }
-
- }
-
- private void parseData(ByteBuffer buf) throws IOException {
- //read in file header
- readHeader(buf);
-
- while (buf.remaining() > 0) {
- readData(buf);
- }
- if (haveMCOS) {
- parseMCOS(mcosData);
- if (data.get("@") == mcosData) {
- data.remove("@");
- }
- for (Map.Entry it : data.entrySet()) {
- if (it.getValue() == mcosData) {
- data.remove(it.getKey());
- break;
- }
- }
- }
- mcosData = null;
- }
-
- private void parseMCOS(MLUInt8 mcosData) throws IOException {
- // First, parse back out the mcosData.
- ByteBuffer buffer = mcosData.getRealByteBuffer();
- ByteBufferInputStream dataStream = new ByteBufferInputStream(buffer, buffer.limit());
-
- Map mcosContent;
-
- MatFileReader matFile = new MatFileReader(dataStream, MatFileType.ReducedHeader);
- mcosContent = matFile.getContent();
- MLCell mcosInfo = (MLCell) ((MLStructure) mcosContent.get("@0")).getField("MCOS");
- ByteBuffer mcosDataBuf = ((MLUInt8) mcosInfo.get(0)).getRealByteBuffer();
- // This bytebuffer needs to be read in the byte order of the MAT file order. Thus fix.
- mcosDataBuf.order(matFile.getMatFileHeader().getByteOrder());
-
- // Parse out the data buffer. First get version information. Should always equal 2.
- int version = mcosDataBuf.getInt();
- if (version != 2) {
- throw new IllegalStateException("MAT file's MCOS data has a different version(?). Got: " + version + ", wanted 2.");
- }
-
- // Get the string count + define the string array.
- int strCount = mcosDataBuf.getInt();
- String[] strs = new String[strCount];
-
- // Get the segment indexes.
- int segmentIndexes[] = new int[6];
- for (int i = 0; i < segmentIndexes.length; ++i) {
- segmentIndexes[i] = mcosDataBuf.getInt();
- }
-
- // There should now be 8 0 bytes. Make sure this is true to avoid object format changes.
- if (mcosDataBuf.getLong() != 0) {
- throw new IllegalStateException("MAT file's MCOS data has different byte values for unknown fields! Aborting!");
- }
-
- // Finally, read in each string. Java doesn't provide an easy way to do this in bulk, so just use a stupid formula for now.
- for (int i = 0; i < strCount; ++i) {
- StringBuilder sb = new StringBuilder();
- for (char next = (char) mcosDataBuf.get(); next != '\0'; next = (char) mcosDataBuf.get()) {
- sb.append(next);
- }
- strs[i] = sb.toString();
- }
-
- // Sanity check, next 8 byte aligned position in the buffer should equal the start of the first segment!
- if (((mcosDataBuf.position() + 0x07) & ~0x07) != segmentIndexes[0]) {
- throw new IllegalStateException("Data from the strings section was not all read!");
- }
-
- // First segment, class information. Really just need the class names.
- List classNamesList = new ArrayList();
- mcosDataBuf.position(segmentIndexes[0]);
- // There are 16 unknown bytes. Ensure they are 0.
- if (mcosDataBuf.getLong() != 0 || mcosDataBuf.getLong() != 0) {
- throw new IllegalStateException("MAT file's MCOS data has different byte values for unknown fields! Aborting!");
- }
- while (mcosDataBuf.position() < segmentIndexes[1]) {
- int packageNameIndex = mcosDataBuf.getInt(); // Unused for now.
- int classNameIndex = mcosDataBuf.getInt(); // Unused for now.
- String className = strs[classNameIndex - 1];
- classNamesList.add(className);
- if (mcosDataBuf.getLong() != 0) {
- throw new IllegalStateException("MAT file's MCOS data has different byte values for unknown fields! Aborting!");
- }
- }
-
- // Sanity check, position in the buffer should equal the start of the second segment!
- if (mcosDataBuf.position() != segmentIndexes[1]) {
- throw new IllegalStateException("Data from the class section was not all read!");
- }
-
- // @todo: Second segment, Object properties containing other properties. Not used yet, thus ignored.
- mcosDataBuf.position(segmentIndexes[2]);
-
- // Third segment. Contains all the useful per-object information.
- Map objectInfoList = new HashMap();
- // There are 24 unknown bytes. Ensure they are 0.
- if (mcosDataBuf.getLong() != 0 || mcosDataBuf.getLong() != 0 || mcosDataBuf.getLong() != 0) {
- throw new IllegalStateException("MAT file's MCOS data has different byte values for unknown fields! Aborting!");
- }
- int objectCount = 1;
- while (mcosDataBuf.position() < segmentIndexes[3]) {
- // First fetch the data.
- int classIndex = mcosDataBuf.getInt();
- if (mcosDataBuf.getLong() != 0) {
- throw new IllegalStateException("MAT file's MCOS data has different byte values for unknown fields! Aborting!");
- }
- int segment2Index = mcosDataBuf.getInt();
- int segment4Index = mcosDataBuf.getInt();
- mcosDataBuf.getInt(); // This value is random. But we need to move the buffer forward, so read it without a check.
- int objectId = objectCount++; // It would appear that the "objectId" is in fact some other MATLAB value. Thus ignore,
- // and use the index into this segment as the id instead.
-
- // Then parse it into the form needed for the object.
- objectInfoList.put(objectId - 1, new MatMCOSObjectInformation(classNamesList.get(classIndex - 1), classIndex, objectId, segment2Index, segment4Index));
- }
-
- // Sanity check, position in the buffer should equal the start of the fourth segment!
- if (mcosDataBuf.position() != segmentIndexes[3]) {
- throw new IllegalStateException("Data from the object section was not all read! At: " + mcosDataBuf.position() + ", wanted: " + segmentIndexes[3]);
- }
-
- // Fourth segment. Contains the regular properties for objects.
- // There are 8 unknown bytes. Ensure they are 0.
- if (mcosDataBuf.getLong() != 0) {
- throw new IllegalStateException("MAT file's MCOS data has different byte values for unknown fields! Aborting!");
- }
- List