You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

TypedPropertyValue.java 8.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. /*
  2. * ====================================================================
  3. * Licensed to the Apache Software Foundation (ASF) under one or more
  4. * contributor license agreements. See the NOTICE file distributed with
  5. * this work for additional information regarding copyright ownership.
  6. * The ASF licenses this file to You under the Apache License, Version 2.0
  7. * (the "License"); you may not use this file except in compliance with
  8. * the License. You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. * ====================================================================
  18. */
  19. package org.apache.poi.hpsf;
  20. import java.math.BigInteger;
  21. import org.apache.logging.log4j.LogManager;
  22. import org.apache.logging.log4j.Logger;
  23. import org.apache.poi.util.Internal;
  24. import org.apache.poi.util.LittleEndianByteArrayInputStream;
  25. import org.apache.poi.util.LittleEndianConsts;
  26. import static org.apache.logging.log4j.util.Unbox.box;
  27. @Internal
  28. public class TypedPropertyValue {
  29. private static final Logger LOG = LogManager.getLogger(TypedPropertyValue.class);
  30. private int _type;
  31. private Object _value;
  32. public TypedPropertyValue( int type, Object value ) {
  33. _type = type;
  34. _value = value;
  35. }
  36. public Object getValue() {
  37. return _value;
  38. }
  39. public void read( LittleEndianByteArrayInputStream lei ) {
  40. _type = lei.readShort();
  41. short padding = lei.readShort();
  42. if ( padding != 0 ) {
  43. LOG.atWarn().log("TypedPropertyValue padding at offset {} MUST be 0, but it's value is {}", box(lei.getReadIndex()),box(padding));
  44. }
  45. readValue( lei );
  46. }
  47. public void readValue( LittleEndianByteArrayInputStream lei ) {
  48. switch ( _type ) {
  49. case Variant.VT_EMPTY:
  50. case Variant.VT_NULL:
  51. _value = null;
  52. break;
  53. case Variant.VT_I1:
  54. _value = lei.readByte();
  55. break;
  56. case Variant.VT_UI1:
  57. _value = lei.readUByte();
  58. break;
  59. case Variant.VT_I2:
  60. _value = lei.readShort();
  61. break;
  62. case Variant.VT_UI2:
  63. _value = lei.readUShort();
  64. break;
  65. case Variant.VT_INT:
  66. case Variant.VT_I4:
  67. _value = lei.readInt();
  68. break;
  69. case Variant.VT_UINT:
  70. case Variant.VT_UI4:
  71. case Variant.VT_ERROR:
  72. _value = lei.readUInt();
  73. break;
  74. case Variant.VT_I8:
  75. _value = lei.readLong();
  76. break;
  77. case Variant.VT_UI8: {
  78. byte[] biBytesLE = new byte[LittleEndianConsts.LONG_SIZE];
  79. lei.readFully(biBytesLE);
  80. // first byte needs to be 0 for unsigned BigInteger
  81. byte[] biBytesBE = new byte[9];
  82. int i=biBytesLE.length;
  83. for (byte b : biBytesLE) {
  84. if (i<=8) {
  85. biBytesBE[i] = b;
  86. }
  87. i--;
  88. }
  89. _value = new BigInteger(biBytesBE);
  90. break;
  91. }
  92. case Variant.VT_R4:
  93. _value = Float.intBitsToFloat(lei.readInt());
  94. break;
  95. case Variant.VT_R8:
  96. _value = lei.readDouble();
  97. break;
  98. case Variant.VT_CY:
  99. Currency cur = new Currency();
  100. cur.read(lei);
  101. _value = cur;
  102. break;
  103. case Variant.VT_DATE:
  104. Date date = new Date();
  105. date.read(lei);
  106. _value = date;
  107. break;
  108. case Variant.VT_BSTR:
  109. case Variant.VT_LPSTR:
  110. CodePageString cps = new CodePageString();
  111. cps.read(lei);
  112. _value = cps;
  113. break;
  114. case Variant.VT_BOOL:
  115. VariantBool vb = new VariantBool();
  116. vb.read(lei);
  117. _value = vb;
  118. break;
  119. case Variant.VT_DECIMAL:
  120. Decimal dec = new Decimal();
  121. dec.read(lei);
  122. _value = dec;
  123. break;
  124. case Variant.VT_LPWSTR:
  125. UnicodeString us = new UnicodeString();
  126. us.read(lei);
  127. _value = us;
  128. break;
  129. case Variant.VT_FILETIME:
  130. Filetime ft = new Filetime();
  131. ft.read(lei);
  132. _value = ft;
  133. break;
  134. case Variant.VT_BLOB:
  135. case Variant.VT_BLOB_OBJECT:
  136. Blob blob = new Blob();
  137. blob.read(lei);
  138. _value = blob;
  139. break;
  140. case Variant.VT_STREAM:
  141. case Variant.VT_STORAGE:
  142. case Variant.VT_STREAMED_OBJECT:
  143. case Variant.VT_STORED_OBJECT:
  144. IndirectPropertyName ipn = new IndirectPropertyName();
  145. ipn.read(lei);
  146. _value = ipn;
  147. break;
  148. case Variant.VT_CF:
  149. ClipboardData cd = new ClipboardData();
  150. cd.read(lei);
  151. _value = cd;
  152. break;
  153. case Variant.VT_CLSID:
  154. GUID guid = new GUID();
  155. guid.read(lei);
  156. _value = lei;
  157. break;
  158. case Variant.VT_VERSIONED_STREAM:
  159. VersionedStream vs = new VersionedStream();
  160. vs.read(lei);
  161. _value = vs;
  162. break;
  163. case Variant.VT_VECTOR | Variant.VT_I2:
  164. case Variant.VT_VECTOR | Variant.VT_I4:
  165. case Variant.VT_VECTOR | Variant.VT_R4:
  166. case Variant.VT_VECTOR | Variant.VT_R8:
  167. case Variant.VT_VECTOR | Variant.VT_CY:
  168. case Variant.VT_VECTOR | Variant.VT_DATE:
  169. case Variant.VT_VECTOR | Variant.VT_BSTR:
  170. case Variant.VT_VECTOR | Variant.VT_ERROR:
  171. case Variant.VT_VECTOR | Variant.VT_BOOL:
  172. case Variant.VT_VECTOR | Variant.VT_VARIANT:
  173. case Variant.VT_VECTOR | Variant.VT_I1:
  174. case Variant.VT_VECTOR | Variant.VT_UI1:
  175. case Variant.VT_VECTOR | Variant.VT_UI2:
  176. case Variant.VT_VECTOR | Variant.VT_UI4:
  177. case Variant.VT_VECTOR | Variant.VT_I8:
  178. case Variant.VT_VECTOR | Variant.VT_UI8:
  179. case Variant.VT_VECTOR | Variant.VT_LPSTR:
  180. case Variant.VT_VECTOR | Variant.VT_LPWSTR:
  181. case Variant.VT_VECTOR | Variant.VT_FILETIME:
  182. case Variant.VT_VECTOR | Variant.VT_CF:
  183. case Variant.VT_VECTOR | Variant.VT_CLSID:
  184. Vector vec = new Vector( (short) ( _type & 0x0FFF ) );
  185. vec.read(lei);
  186. _value = vec;
  187. break;
  188. case Variant.VT_ARRAY | Variant.VT_I2:
  189. case Variant.VT_ARRAY | Variant.VT_I4:
  190. case Variant.VT_ARRAY | Variant.VT_R4:
  191. case Variant.VT_ARRAY | Variant.VT_R8:
  192. case Variant.VT_ARRAY | Variant.VT_CY:
  193. case Variant.VT_ARRAY | Variant.VT_DATE:
  194. case Variant.VT_ARRAY | Variant.VT_BSTR:
  195. case Variant.VT_ARRAY | Variant.VT_ERROR:
  196. case Variant.VT_ARRAY | Variant.VT_BOOL:
  197. case Variant.VT_ARRAY | Variant.VT_VARIANT:
  198. case Variant.VT_ARRAY | Variant.VT_DECIMAL:
  199. case Variant.VT_ARRAY | Variant.VT_I1:
  200. case Variant.VT_ARRAY | Variant.VT_UI1:
  201. case Variant.VT_ARRAY | Variant.VT_UI2:
  202. case Variant.VT_ARRAY | Variant.VT_UI4:
  203. case Variant.VT_ARRAY | Variant.VT_INT:
  204. case Variant.VT_ARRAY | Variant.VT_UINT:
  205. Array arr = new Array();
  206. arr.read(lei);
  207. _value = arr;
  208. break;
  209. default:
  210. String msg = "Unknown (possibly, incorrect) TypedPropertyValue type: " + _type;
  211. throw new UnsupportedOperationException(msg);
  212. }
  213. }
  214. static void skipPadding( LittleEndianByteArrayInputStream lei ) {
  215. final int offset = lei.getReadIndex();
  216. int skipBytes = (4 - (offset & 3)) & 3;
  217. for (int i=0; i<skipBytes; i++) {
  218. lei.mark(1);
  219. int b = lei.read();
  220. if (b == -1 || b != 0) {
  221. lei.reset();
  222. break;
  223. }
  224. }
  225. }
  226. }