1 2 /* ==================================================================== 3 * The Apache Software License, Version 1.1 4 * 5 * Copyright (c) 2002 The Apache Software Foundation. All rights 6 * reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in 17 * the documentation and/or other materials provided with the 18 * distribution. 19 * 20 * 3. The end-user documentation included with the redistribution, 21 * if any, must include the following acknowledgment: 22 * "This product includes software developed by the 23 * Apache Software Foundation (http://www.apache.org/)." 24 * Alternately, this acknowledgment may appear in the software itself, 25 * if and wherever such third-party acknowledgments normally appear. 26 * 27 * 4. The names "Apache" and "Apache Software Foundation" and 28 * "Apache POI" must not be used to endorse or promote products 29 * derived from this software without prior written permission. For 30 * written permission, please contact apache@apache.org. 31 * 32 * 5. Products derived from this software may not be called "Apache", 33 * "Apache POI", nor may "Apache" appear in their name, without 34 * prior written permission of the Apache Software Foundation. 35 * 36 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED 37 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 38 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 39 * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR 40 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 41 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 42 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 43 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 44 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 45 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 46 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 47 * SUCH DAMAGE. 48 * ==================================================================== 49 * 50 * This software consists of voluntary contributions made by many 51 * individuals on behalf of the Apache Software Foundation. For more 52 * information on the Apache Software Foundation, please see 53 * <http://www.apache.org/>. 54 */ 55 56 package org.apache.poi.hssf.record; 57 58 import org.apache.poi.util.LittleEndian; 59 import org.apache.poi.util.StringUtil; 60 61 /** 62 * Title: Format Record<P> 63 * Description: describes a number format -- those goofy strings like $(#,###)<P> 64 * 65 * REFERENCE: PG 317 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<P> 66 * @author Andrew C. Oliver (acoliver at apache dot org) 67 * @author Shawn M. Laubach (slaubach at apache dot org) 68 * @version 2.0-pre 69 */ 70 71 public class FormatRecord 72 extends Record 73 { 74 public final static short sid = 0x41e; 75 private short field_1_index_code; 76 private short field_2_formatstring_len; 77 private short field_3_unicode_len; // unicode string length 78 private boolean field_3_unicode_flag; // it is not undocumented - it is unicode flag 79 private String field_4_formatstring; 80 81 public FormatRecord() 82 { 83 } 84 85 /** 86 * Constructs a Format record and sets its fields appropriately. 87 * 88 * @param id id must be 0x41e or an exception will be throw upon validation 89 * @param size the size of the data area of the record 90 * @param data data of the record (should not contain sid/len) 91 */ 92 93 public FormatRecord(short id, short size, byte [] data) 94 { 95 super(id, size, data); 96 } 97 98 /** 99 * Constructs a Format record and sets its fields appropriately. 100 * 101 * @param id id must be 0x41e or an exception will be throw upon validation 102 * @param size the size of the data area of the record 103 * @param data data of the record (should not contain sid/len) 104 * @param offset of the record's data 105 */ 106 107 public FormatRecord(short id, short size, byte [] data, int offset) 108 { 109 super(id, size, data, offset); 110 } 111 112 protected void validateSid(short id) 113 { 114 if (id != sid) 115 { 116 throw new RecordFormatException("NOT A FORMAT RECORD"); 117 } 118 } 119 120 protected void fillFields(byte [] data, short size, int offset) 121 { 122 field_1_index_code = LittleEndian.getShort(data, 0 + offset); 123 // field_2_formatstring_len = data[ 2 + offset ]; 124 field_3_unicode_len = LittleEndian.getShort( data, 2 + offset ); 125 field_2_formatstring_len = field_3_unicode_len; 126 field_3_unicode_flag = ( data[ 4 + offset ] & (byte)0x01 ) != 0; 127 128 129 if ( field_3_unicode_flag ) { 130 // unicode 131 field_4_formatstring = StringUtil.getFromUnicodeHigh( data, 5 + offset, field_3_unicode_len ); 132 } 133 else { 134 // not unicode 135 field_4_formatstring = new String(data, 5 + offset, field_3_unicode_len ); 136 } 137 } 138 139 /** 140 * set the format index code (for built in formats) 141 * 142 * @param index the format index code 143 * @see org.apache.poi.hssf.model.Workbook 144 */ 145 146 public void setIndexCode(short index) 147 { 148 field_1_index_code = index; 149 } 150 151 /** 152 * set the format string length 153 * 154 * @param len the length of the format string 155 * @see #setFormatString(String) 156 */ 157 158 public void setFormatStringLength(byte len) 159 { 160 field_2_formatstring_len = len; 161 field_3_unicode_len = len; 162 } 163 164 /** 165 * set whether the string is unicode 166 * 167 * @param unicode flag for whether string is unicode 168 */ 169 170 public void setUnicodeFlag(boolean unicode) { 171 field_3_unicode_flag = unicode; 172 } 173 174 /** 175 * set the format string 176 * 177 * @param fs the format string 178 * @see #setFormatStringLength(byte) 179 */ 180 181 public void setFormatString(String fs) 182 { 183 field_4_formatstring = fs; 184 } 185 186 /** 187 * get the format index code (for built in formats) 188 * 189 * @return the format index code 190 * @see org.apache.poi.hssf.model.Workbook 191 */ 192 193 public short getIndexCode() 194 { 195 return field_1_index_code; 196 } 197 198 /** 199 * get the format string length 200 * 201 * @return the length of the format string 202 * @see #getFormatString() 203 */ 204 205 public short getFormatStringLength() 206 { 207 return field_3_unicode_flag ? field_3_unicode_len : field_2_formatstring_len; 208 } 209 210 /** 211 * get whether the string is unicode 212 * 213 * @return flag for whether string is unicode 214 */ 215 216 public boolean getUnicodeFlag() { 217 return field_3_unicode_flag; 218 } 219 220 /** 221 * get the format string 222 * 223 * @return the format string 224 * @see #getFormatStringLength() 225 */ 226 227 public String getFormatString() 228 { 229 return field_4_formatstring; 230 } 231 232 public String toString() 233 { 234 StringBuffer buffer = new StringBuffer(); 235 236 buffer.append("[FORMAT]\n"); 237 buffer.append(" .indexcode = ") 238 .append(Integer.toHexString(getIndexCode())).append("\n"); 239 /* 240 buffer.append(" .formatstringlen = ") 241 .append(Integer.toHexString(getFormatStringLength())) 242 .append("\n"); 243 */ 244 buffer.append(" .unicode length = ") 245 .append(Integer.toHexString(field_3_unicode_len)).append("\n"); 246 buffer.append(" .isUnicode = ") 247 .append( field_3_unicode_flag ).append("\n"); 248 buffer.append(" .formatstring = ").append(getFormatString()) 249 .append("\n"); 250 buffer.append("[/FORMAT]\n"); 251 return buffer.toString(); 252 } 253 254 public int serialize(int offset, byte [] data) 255 { 256 LittleEndian.putShort(data, 0 + offset, sid); 257 LittleEndian.putShort(data, 2 + offset, (short)( 2 + 2 + 1 + ( (field_3_unicode_flag) 258 ? 2 * field_3_unicode_len 259 : field_3_unicode_len ) ) ); 260 // index + len + flag + format string length 261 LittleEndian.putShort(data, 4 + offset, getIndexCode()); 262 LittleEndian.putShort(data, 6 + offset, field_3_unicode_len); 263 data[ 8 + offset ] = (byte)( (field_3_unicode_flag) ? 0x01 : 0x00 ); 264 265 if ( field_3_unicode_flag ) { 266 // unicode 267 StringUtil.putUncompressedUnicode( getFormatString(), data, 9 + offset ); 268 } 269 else { 270 // not unicode 271 StringUtil.putCompressedUnicode( getFormatString(), data, 9 + offset ); 272 } 273 274 return getRecordSize(); 275 } 276 277 public int getRecordSize() 278 { 279 return 9 + ( ( field_3_unicode_flag ) ? 2 * field_3_unicode_len : field_3_unicode_len ); 280 } 281 282 public short getSid() 283 { 284 return this.sid; 285 } 286 } 287