001package jmri.jmrit.symbolicprog; 002 003import java.io.File; 004import java.io.FileInputStream; 005import java.io.IOException; 006import java.util.Enumeration; 007import java.util.Properties; 008import jmri.JmriException; 009import org.slf4j.Logger; 010import org.slf4j.LoggerFactory; 011 012/** 013 * Import CV values from a "PR1" file written by PR1DOS or PR1WIN. 014 * 015 * 016 * <hr> 017 * This file is part of JMRI. 018 * <p> 019 * JMRI is free software; you can redistribute it and/or modify it under the 020 * terms of version 2 of the GNU General Public License as published by the Free 021 * Software Foundation. See the "COPYING" file for a copy of this license. 022 * <p> 023 * JMRI is distributed in the hope that it will be useful, but WITHOUT ANY 024 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 025 * A PARTICULAR PURPOSE. See the GNU General Public License for more details. 026 * 027 * @author Alex Shepherd Copyright (C) 2003 028 */ 029public class Pr1Importer { 030 031 private final static Logger log = LoggerFactory.getLogger(Pr1Importer.class); 032 private static final String VERSION_KEY = "Version"; 033 private static final String CV_PREFIX = "CV"; 034 private static final int CV_INDEX_OFFSET = 2; 035 036 Properties m_CVs; 037 boolean m_packedValues = false; 038 039 public Pr1Importer(File file) throws IOException { 040 m_CVs = new Properties(); 041 FileInputStream fileStream = new FileInputStream(file); 042 try { 043 m_CVs.load(fileStream); 044 } finally { 045 fileStream.close(); 046 } 047 048 // First check to see if the file contains a Version=x entry and if it 049 // does assume it is a PR1WIN file that has packed values 050 if (m_CVs.containsKey(VERSION_KEY)) { 051 if (m_CVs.get(VERSION_KEY).equals("0")) { 052 m_packedValues = true; 053 } else { 054 throw new IOException("Unsupported PR1 File Version"); 055 } 056 } // Have a look at the values and see if there are any entries with values 057 // greater out of the range 0..255. If they are found then also assume PR1WIN 058 else { 059 Enumeration<Object> cvKeys = m_CVs.keys(); 060 061 while (cvKeys.hasMoreElements()) { 062 String cvKey = (String) cvKeys.nextElement(); 063 if (cvKey.startsWith(CV_PREFIX)) { 064 String cvValue = (String) m_CVs.get(cvKey); 065 int cvIntValue = Integer.parseInt(cvValue); 066 if ((cvIntValue < 0) || (cvIntValue > 255)) { 067 m_packedValues = true; 068 return; 069 } 070 } 071 } 072 } 073 } 074 075 public void setCvTable(CvTableModel pCvTable) { 076 Enumeration<Object> keyIterator = m_CVs.keys(); 077 while (keyIterator.hasMoreElements()) { 078 String key = (String) keyIterator.nextElement(); 079 if (key.startsWith(CV_PREFIX)) { 080 int Index = Integer.parseInt(key.substring(CV_INDEX_OFFSET)); 081 082 int lowCV; 083 int highCV; 084 085 if (m_packedValues) { 086 lowCV = Index * 4 - 3; 087 highCV = Index * 4; 088 } else { 089 lowCV = Index; 090 highCV = Index; 091 } 092 093 for (int cvNum = lowCV; cvNum <= highCV; cvNum++) { 094 if (cvNum <= CvTableModel.MAXCVNUM) { // MAXCVNUM is the highest number, so is included 095 try { 096 CvValue cv = pCvTable.allCvMap().get("" + cvNum); 097 if (cv != null) { 098 cv.setValue(getCV(cvNum)); 099 } 100 } catch (JmriException ex) { 101 log.error("failed to getCV() {}", cvNum); 102 } catch (ArrayIndexOutOfBoundsException ex) { 103 log.error("failed to getCvByNumber() {}", cvNum); 104 } 105 } 106 } 107 } 108 } 109 } 110 111 public int getCV(int cvNumber) throws JmriException { 112 int result; 113 114 if (m_packedValues) { 115 String cvKey = CV_PREFIX + ((cvNumber / 4) + 1); 116 String cvValueStr = m_CVs.getProperty(cvKey); 117 if (cvValueStr == null) { 118 throw new JmriException("CV not found"); 119 } 120 121 int shiftBits = ((cvNumber - 1) % 4) << 3; 122 123 long cvValue = Long.parseLong(cvValueStr); 124 125 if (cvValue < 0) { 126 result = (int) (((cvValue + 0x7FFFFFFF) >> shiftBits) % 256); 127 if (shiftBits > 16) { 128 result += 127; 129 } 130 } else { 131 result = (int) ((cvValue >> shiftBits) % 256); 132 } 133 } else { 134 String cvKey = CV_PREFIX + cvNumber; 135 String cvValueStr = m_CVs.getProperty(cvKey); 136 if (cvValueStr == null) { 137 throw new JmriException("CV not found"); 138 } 139 140 result = Integer.parseInt(cvValueStr); 141 } 142 143 return result; 144 } 145 146}