PageRenderTime 47ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 1ms

/components/forks/poi/src/loci/poi/hssf/record/RKRecord.java

http://github.com/openmicroscopy/bioformats
Java | 320 lines | 176 code | 38 blank | 106 comment | 22 complexity | 48209ea57cc94560d63635e7f68af007 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1, Apache-2.0, BSD-2-Clause, MPL-2.0-no-copyleft-exception
  1. /*
  2. * #%L
  3. * Fork of Apache Jakarta POI.
  4. * %%
  5. * Copyright (C) 2008 - 2013 Open Microscopy Environment:
  6. * - Board of Regents of the University of Wisconsin-Madison
  7. * - Glencoe Software, Inc.
  8. * - University of Dundee
  9. * %%
  10. * Licensed under the Apache License, Version 2.0 (the "License");
  11. * you may not use this file except in compliance with the License.
  12. * You may obtain a copy of the License at
  13. *
  14. * http://www.apache.org/licenses/LICENSE-2.0
  15. *
  16. * Unless required by applicable law or agreed to in writing, software
  17. * distributed under the License is distributed on an "AS IS" BASIS,
  18. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  19. * See the License for the specific language governing permissions and
  20. * limitations under the License.
  21. * #L%
  22. */
  23. /* ====================================================================
  24. Licensed to the Apache Software Foundation (ASF) under one or more
  25. contributor license agreements. See the NOTICE file distributed with
  26. this work for additional information regarding copyright ownership.
  27. The ASF licenses this file to You under the Apache License, Version 2.0
  28. (the "License"); you may not use this file except in compliance with
  29. the License. You may obtain a copy of the License at
  30. http://www.apache.org/licenses/LICENSE-2.0
  31. Unless required by applicable law or agreed to in writing, software
  32. distributed under the License is distributed on an "AS IS" BASIS,
  33. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  34. See the License for the specific language governing permissions and
  35. limitations under the License.
  36. ==================================================================== */
  37. package loci.poi.hssf.record;
  38. import loci.poi.hssf.util.RKUtil;
  39. /**
  40. * Title: RK Record
  41. * Description: An internal 32 bit number with the two most significant bits
  42. * storing the type. This is part of a bizarre scheme to save disk
  43. * space and memory (gee look at all the other whole records that
  44. * are in the file just "cause"..,far better to waste processor
  45. * cycles on this then leave on of those "valuable" records out).<P>
  46. * We support this in READ-ONLY mode. HSSF converts these to NUMBER records<P>
  47. *
  48. *
  49. *
  50. * REFERENCE: PG 376 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<P>
  51. * @author Andrew C. Oliver (acoliver at apache dot org)
  52. * @author Jason Height (jheight at chariot dot net dot au)
  53. * @version 2.0-pre
  54. * @see loci.poi.hssf.record.NumberRecord
  55. */
  56. public class RKRecord
  57. extends Record
  58. implements CellValueRecordInterface
  59. {
  60. public final static short sid = 0x27e;
  61. public final static short RK_IEEE_NUMBER = 0;
  62. public final static short RK_IEEE_NUMBER_TIMES_100 = 1;
  63. public final static short RK_INTEGER = 2;
  64. public final static short RK_INTEGER_TIMES_100 = 3;
  65. //private short field_1_row;
  66. private int field_1_row;
  67. private short field_2_col;
  68. private short field_3_xf_index;
  69. private int field_4_rk_number;
  70. public RKRecord()
  71. {
  72. }
  73. /**
  74. * Constructs a RK record and sets its fields appropriately.
  75. * @param in the RecordInputstream to read the record from
  76. */
  77. public RKRecord(RecordInputStream in)
  78. {
  79. super(in);
  80. }
  81. protected void validateSid(short id)
  82. {
  83. if (id != sid)
  84. {
  85. throw new RecordFormatException("NOT A valid RK RECORD");
  86. }
  87. }
  88. protected void fillFields(RecordInputStream in)
  89. {
  90. //field_1_row = LittleEndian.getShort(data, 0 + offset);
  91. field_1_row = in.readUShort();
  92. field_2_col = in.readShort();
  93. field_3_xf_index = in.readShort();
  94. field_4_rk_number = in.readInt();
  95. }
  96. //public short getRow()
  97. public int getRow()
  98. {
  99. return field_1_row;
  100. }
  101. public short getColumn()
  102. {
  103. return field_2_col;
  104. }
  105. public short getXFIndex()
  106. {
  107. return field_3_xf_index;
  108. }
  109. public int getRKField()
  110. {
  111. return field_4_rk_number;
  112. }
  113. /**
  114. * Get the type of the number
  115. *
  116. * @return one of these values:
  117. * <OL START="0">
  118. * <LI>RK_IEEE_NUMBER</LI>
  119. * <LI>RK_IEEE_NUMBER_TIMES_100</LI>
  120. * <LI>RK_INTEGER</LI>
  121. * <LI>RK_INTEGER_TIMES_100</LI>
  122. * </OL>
  123. */
  124. public short getRKType()
  125. {
  126. return ( short ) (field_4_rk_number & 3);
  127. }
  128. /**
  129. * Extract the value of the number
  130. * <P>
  131. * The mechanism for determining the value is dependent on the two
  132. * low order bits of the raw number. If bit 1 is set, the number
  133. * is an integer and can be cast directly as a double, otherwise,
  134. * it's apparently the exponent and mantissa of a double (and the
  135. * remaining low-order bits of the double's mantissa are 0's).
  136. * <P>
  137. * If bit 0 is set, the result of the conversion to a double is
  138. * divided by 100; otherwise, the value is left alone.
  139. * <P>
  140. * [insert picture of Screwy Squirrel in full Napoleonic regalia]
  141. *
  142. * @return the value as a proper double (hey, it <B>could</B>
  143. * happen)
  144. */
  145. public double getRKNumber()
  146. {
  147. return RKUtil.decodeNumber(field_4_rk_number);
  148. }
  149. public String toString()
  150. {
  151. StringBuffer buffer = new StringBuffer();
  152. buffer.append("[RK]\n");
  153. buffer.append(" .row = ")
  154. .append(Integer.toHexString(getRow())).append("\n");
  155. buffer.append(" .col = ")
  156. .append(Integer.toHexString(getColumn())).append("\n");
  157. buffer.append(" .xfindex = ")
  158. .append(Integer.toHexString(getXFIndex())).append("\n");
  159. buffer.append(" .rknumber = ")
  160. .append(Integer.toHexString(getRKField())).append("\n");
  161. buffer.append(" .rktype = ")
  162. .append(Integer.toHexString(getRKType())).append("\n");
  163. buffer.append(" .rknumber = ").append(getRKNumber())
  164. .append("\n");
  165. buffer.append("[/RK]\n");
  166. return buffer.toString();
  167. }
  168. //temporarily just constructs a new number record and returns its value
  169. public int serialize(int offset, byte [] data)
  170. {
  171. NumberRecord rec = new NumberRecord();
  172. rec.setColumn(getColumn());
  173. rec.setRow(getRow());
  174. rec.setValue(getRKNumber());
  175. rec.setXFIndex(getXFIndex());
  176. return rec.serialize(offset, data);
  177. }
  178. /**
  179. * Debugging main()
  180. * <P>
  181. * Normally I'd do this in a junit test, but let's face it -- once
  182. * this algorithm has been tested and it works, we are never ever
  183. * going to change it. This is driven by the Faceless Enemy's
  184. * minions, who dare not change the algorithm out from under us.
  185. *
  186. * @param ignored_args command line arguments, which we blithely
  187. * ignore
  188. */
  189. public static void main(String ignored_args[])
  190. {
  191. int[] values =
  192. {
  193. 0x3FF00000, 0x405EC001, 0x02F1853A, 0x02F1853B, 0xFCDD699A
  194. };
  195. double[] rvalues =
  196. {
  197. 1, 1.23, 12345678, 123456.78, -13149594
  198. };
  199. for (int j = 0; j < values.length; j++)
  200. {
  201. System.out.println("input = " + Integer.toHexString(values[ j ])
  202. + " -> " + rvalues[ j ] + ": "
  203. + RKUtil.decodeNumber(values[ j ]));
  204. }
  205. }
  206. public short getSid()
  207. {
  208. return sid;
  209. }
  210. public boolean isBefore(CellValueRecordInterface i)
  211. {
  212. if (this.getRow() > i.getRow())
  213. {
  214. return false;
  215. }
  216. if ((this.getRow() == i.getRow())
  217. && (this.getColumn() > i.getColumn()))
  218. {
  219. return false;
  220. }
  221. if ((this.getRow() == i.getRow())
  222. && (this.getColumn() == i.getColumn()))
  223. {
  224. return false;
  225. }
  226. return true;
  227. }
  228. public boolean isAfter(CellValueRecordInterface i)
  229. {
  230. if (this.getRow() < i.getRow())
  231. {
  232. return false;
  233. }
  234. if ((this.getRow() == i.getRow())
  235. && (this.getColumn() < i.getColumn()))
  236. {
  237. return false;
  238. }
  239. if ((this.getRow() == i.getRow())
  240. && (this.getColumn() == i.getColumn()))
  241. {
  242. return false;
  243. }
  244. return true;
  245. }
  246. public boolean isEqual(CellValueRecordInterface i)
  247. {
  248. return ((this.getRow() == i.getRow())
  249. && (this.getColumn() == i.getColumn()));
  250. }
  251. public boolean isInValueSection()
  252. {
  253. return true;
  254. }
  255. public boolean isValue()
  256. {
  257. return true;
  258. }
  259. public void setColumn(short col)
  260. {
  261. }
  262. //public void setRow(short row)
  263. public void setRow(int row)
  264. {
  265. }
  266. /**
  267. * NO OP!
  268. */
  269. public void setXFIndex(short xf)
  270. {
  271. }
  272. public Object clone() {
  273. RKRecord rec = new RKRecord();
  274. rec.field_1_row = field_1_row;
  275. rec.field_2_col = field_2_col;
  276. rec.field_3_xf_index = field_3_xf_index;
  277. rec.field_4_rk_number = field_4_rk_number;
  278. return rec;
  279. }
  280. }