From 683d490074d93baa8a47db7ec43b7bd31145a12a Mon Sep 17 00:00:00 2001 From: Mark Donszelmann Date: Thu, 5 Nov 2009 23:00:15 +0100 Subject: Tar file expanded and committed --- .../cpptasks/platforms/WindowsPlatform.java | 364 +++++++++++++++++++++ 1 file changed, 364 insertions(+) create mode 100644 src/main/java/net/sf/antcontrib/cpptasks/platforms/WindowsPlatform.java (limited to 'src/main/java/net/sf/antcontrib/cpptasks/platforms/WindowsPlatform.java') diff --git a/src/main/java/net/sf/antcontrib/cpptasks/platforms/WindowsPlatform.java b/src/main/java/net/sf/antcontrib/cpptasks/platforms/WindowsPlatform.java new file mode 100644 index 0000000..f16f94e --- /dev/null +++ b/src/main/java/net/sf/antcontrib/cpptasks/platforms/WindowsPlatform.java @@ -0,0 +1,364 @@ +/* + * + * Copyright 2004 The Ant-Contrib project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.sf.antcontrib.cpptasks.platforms; + +import java.io.BufferedWriter; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStreamWriter; +import java.io.Writer; + +import net.sf.antcontrib.cpptasks.CUtil; +import net.sf.antcontrib.cpptasks.TargetMatcher; +import net.sf.antcontrib.cpptasks.VersionInfo; +import net.sf.antcontrib.cpptasks.compiler.LinkType; + + +/** + * Platform specific behavior for Microsoft Windows. + * + * @author Curt Arnold + */ +public final class WindowsPlatform { + + /** + * Constructor. + */ + private WindowsPlatform() { + } + /** + * Adds source or object files to the bidded fileset to + * support version information. + * + * @param versionInfo version information + * @param linkType link type + * @param isDebug true if debug build + * @param outputFile name of generated executable + * @param objDir directory for generated files + * @param matcher bidded fileset + * @throws IOException if unable to write version resource + */ + public static void addVersionFiles(final VersionInfo versionInfo, + final LinkType linkType, + final File outputFile, + final boolean isDebug, + final File objDir, + final TargetMatcher matcher) + throws IOException { + if (versionInfo == null) { + throw new NullPointerException("versionInfo"); + } + if (linkType == null) { + throw new NullPointerException("linkType"); + } + if (outputFile == null) { + throw new NullPointerException("outputFile"); + } + if (objDir == null) { + throw new NullPointerException("objDir"); + } + + /** + * Fully resolve version info + */ + VersionInfo mergedInfo = versionInfo.merge(); + + File versionResource = new File(objDir, "versioninfo.rc"); + + boolean notChanged = false; + // + // if the resource exists + // + if (versionResource.exists()) { + ByteArrayOutputStream memStream = new ByteArrayOutputStream(); + Writer writer = new BufferedWriter(new OutputStreamWriter(memStream)); + writeResource(writer, mergedInfo, outputFile, isDebug, linkType); + writer.close(); + ByteArrayInputStream proposedResource = new ByteArrayInputStream( + memStream.toByteArray()); + + InputStream existingResource = new FileInputStream(versionResource); + // + // + // + notChanged = hasSameContent(proposedResource, existingResource); + existingResource.close(); + } + + // + // if the resource file did not exist or will be changed then + // write the file + // + if (!notChanged) { + Writer writer = new BufferedWriter( + new OutputStreamWriter( + new FileOutputStream(versionResource))); + writeResource(writer, mergedInfo, outputFile, isDebug, linkType); + writer.close(); + } + if (matcher != null) { + matcher.visit(new File(versionResource.getParent()), + versionResource.getName()); + } + + } + + /** + * Compare two input streams for duplicate content + * + * Naive implementation, but should not be performance issue. + * @param stream1 stream + * @param stream2 stream + * @return true if streams are identical in content + * @throws IOException if error reading streams + */ + private static boolean hasSameContent(final InputStream stream1, + final InputStream stream2) + throws IOException { + int byte1 = -1; + int byte2 = -1; + do { + byte1 = stream1.read(); + byte2 = stream2.read(); + + } + while (byte1 == byte2 && byte1 != -1); + return (byte1 == byte2); + } + + + /** + * Parse version string into array of four short values. + * @param version String version + * @return short[] four element array + */ + public static short[] parseVersion(final String version) { + short[] values = new short[] { + 0, 0, 0, 0}; + if (version != null) { + StringBuffer buf = new StringBuffer(version); + int start = 0; + for (int i = 0; i < 4; i++) { + int end = version.indexOf('.', start); + if (end <= 0) { + end = version.length(); + for (int j = end; j > start; j--) { + String part = buf.substring(start, end); + try { + values[i] = Short.parseShort(part); + break; + } catch (NumberFormatException ex) { + values[i] = 0; + } + } + break; + } else { + String part = buf.substring(start, end); + try { + values[i] = Short.parseShort(part); + start = end + 1; + } catch (NumberFormatException ex) { + break; + } + } + } + } + return values; + } + + /** + * Converts parsed version information into a string representation. + * + * @param buf StringBuffer string buffer to receive version number + * @param version short[] four-element array + */ + private static void encodeVersion(final StringBuffer buf, + final short[] version) { + for (int i = 0; i < 3; i++) { + buf.append(Short.toString(version[i])); + buf.append(','); + } + buf.append(Short.toString(version[3])); + } + + /** + * Writes windows resource. + * @param writer writer, may not be nul + * @param versionInfo version information + * @param outputFile executable file + * @param isDebug true if debug + * @param linkType link type + * @throws IOException if error writing resource file + */ + public static void writeResource(final Writer writer, + final VersionInfo versionInfo, + final File outputFile, + final boolean isDebug, + final LinkType linkType) throws IOException { + + //writer.write("#include \"windows.h\"\n"); + + writer.write("VS_VERSION_INFO VERSIONINFO\n"); + StringBuffer buf = new StringBuffer("FILEVERSION "); + encodeVersion(buf, parseVersion(versionInfo.getFileversion())); + buf.append("\nPRODUCTVERSION "); + encodeVersion(buf, parseVersion(versionInfo.getProductversion())); + buf.append("\n"); + writer.write(buf.toString()); + buf.setLength(0); + buf.append("FILEFLAGSMASK 0x1L /* VS_FF_DEBUG */"); + Boolean patched = versionInfo.getPatched(); + Boolean prerelease = versionInfo.getPrerelease(); + if (patched != null) { + buf.append(" | 0x4L /* VS_FF_PATCHED */"); + } + if (prerelease != null) { + buf.append(" | 0x2L /* VS_FF_PRERELEASE */"); + } + if (versionInfo.getPrivatebuild() != null) { + buf.append(" | 0x8L /* VS_FF_PRIVATEBUILD */"); + } + if (versionInfo.getSpecialbuild() != null) { + buf.append(" | 0x20L /* VS_FF_SPECIALBUILD */"); + } + buf.append('\n'); + writer.write(buf.toString()); + buf.setLength(0); + buf.append("FILEFLAGS "); + + if (isDebug) { + buf.append("0x1L /* VS_FF_DEBUG */ | "); + } + if (Boolean.TRUE.equals(patched)) { + buf.append("0x4L /* VS_FF_PATCHED */ | "); + } + if (Boolean.TRUE.equals(prerelease)) { + buf.append("0x2L /* VS_FF_PRERELEASE */ | "); + } + if (Boolean.TRUE.equals(versionInfo.getPrivatebuild())) { + buf.append("0x8L /* VS_FF_PRIVATEBUILD */ | "); + } + if (Boolean.TRUE.equals(versionInfo.getSpecialbuild())) { + buf.append("0x20L /* VS_FF_SPECIALBUILD */ | "); + } + if (buf.length() > 10) { + buf.setLength(buf.length() - 3); + buf.append('\n'); + } else { + buf.append("0\n"); + } + writer.write(buf.toString()); + buf.setLength(0); + + writer.write("FILEOS 0x40004 /* VOS_NT_WINDOWS32 */\nFILETYPE "); + if (linkType.isExecutable()) { + writer.write("0x1L /* VFT_APP */\n"); + } else { + if (linkType.isSharedLibrary()) { + writer.write("0x2L /* VFT_DLL */\n"); + } else if (linkType.isStaticLibrary()) { + writer.write("0x7L /* VFT_STATIC_LIB */\n"); + } else { + writer.write("0x0L /* VFT_UNKNOWN */\n"); + } + } + writer.write("FILESUBTYPE 0x0L\n"); + writer.write("BEGIN\n"); + writer.write("BLOCK \"StringFileInfo\"\n"); + writer.write(" BEGIN\n#ifdef UNICODE\nBLOCK \"040904B0\"\n"); + writer.write("#else\nBLOCK \"040904E4\"\n#endif\n"); + writer.write("BEGIN\n"); + if (versionInfo.getFilecomments() != null) { + writer.write("VALUE \"Comments\", \""); + writer.write(versionInfo.getFilecomments()); + writer.write("\\0\"\n"); + } + if (versionInfo.getCompanyname() != null) { + writer.write("VALUE \"CompanyName\", \""); + writer.write(versionInfo.getCompanyname()); + writer.write("\\0\"\n"); + } + if (versionInfo.getFiledescription() != null) { + writer.write("VALUE \"FileDescription\", \""); + writer.write(versionInfo.getFiledescription()); + writer.write("\\0\"\n"); + } + if (versionInfo.getFileversion() != null) { + writer.write("VALUE \"FileVersion\", \""); + writer.write(versionInfo.getFileversion()); + writer.write("\\0\"\n"); + } + String baseName = CUtil.getBasename(outputFile); + String internalName = versionInfo.getInternalname(); + if (internalName == null) { + internalName = baseName; + } + writer.write("VALUE \"InternalName\", \""); + writer.write(internalName); + writer.write("\\0\"\n"); + if (versionInfo.getLegalcopyright() != null) { + writer.write("VALUE \"LegalCopyright\", \""); + writer.write(versionInfo.getLegalcopyright()); + writer.write("\\0\"\n"); + } + if (versionInfo.getLegaltrademarks() != null) { + writer.write("VALUE \"LegalTrademarks\", \""); + writer.write(versionInfo.getLegaltrademarks()); + writer.write("\\0\"\n"); + } + writer.write("VALUE \"OriginalFilename\", \""); + writer.write(baseName); + writer.write("\\0\"\n"); + if (versionInfo.getPrivatebuild() != null) { + writer.write("VALUE \"PrivateBuild\", \""); + writer.write(versionInfo.getPrivatebuild()); + writer.write("\\0\"\n"); + } + if (versionInfo.getProductname() != null) { + writer.write("VALUE \"ProductName\", \""); + writer.write(versionInfo.getProductname()); + writer.write("\\0\"\n"); + } + if (versionInfo.getProductversion() != null) { + writer.write("VALUE \"ProductVersion\", \""); + writer.write(versionInfo.getProductversion()); + writer.write("\\0\"\n"); + } + if (versionInfo.getSpecialbuild() != null) { + writer.write("VALUE \"SpecialBuild\", \""); + writer.write(versionInfo.getSpecialbuild()); + writer.write("\\0\"\n"); + } + writer.write("END\n"); + writer.write("END\n"); + + writer.write("BLOCK \"VarFileInfo\"\n"); + writer.write("BEGIN\n#ifdef UNICODE\n"); + writer.write("VALUE \"Translation\", 0x409, 1200\n"); + writer.write("#else\n"); + writer.write("VALUE \"Translation\", 0x409, 1252\n"); + writer.write("#endif\n"); + writer.write("END\n"); + writer.write("END\n"); + } + +} -- cgit v1.2.3