You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@poi.apache.org by fa...@apache.org on 2021/05/22 20:56:49 UTC
svn commit: r1890120 [7/43] - in /poi/trunk/poi/src:
main/java/org/apache/poi/ main/java/org/apache/poi/ddf/
main/java/org/apache/poi/extractor/ main/java/org/apache/poi/hpsf/
main/java/org/apache/poi/hssf/ main/java/org/apache/poi/hssf/dev/
main/java/...
Modified: poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/NameRecord.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/NameRecord.java?rev=1890120&r1=1890119&r2=1890120&view=diff
==============================================================================
--- poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/NameRecord.java (original)
+++ poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/NameRecord.java Sat May 22 20:56:44 2021
@@ -38,427 +38,427 @@ import org.apache.poi.util.StringUtil;
@SuppressWarnings("unused")
public final class NameRecord extends ContinuableRecord {
public static final short sid = 0x0018;
- /**Included for completeness sake, not implemented */
- public static final byte BUILTIN_CONSOLIDATE_AREA = 1;
- /**Included for completeness sake, not implemented */
- public static final byte BUILTIN_AUTO_OPEN = 2;
- /**Included for completeness sake, not implemented */
- public static final byte BUILTIN_AUTO_CLOSE = 3;
- /**Included for completeness sake, not implemented */
- public static final byte BUILTIN_DATABASE = 4;
- /**Included for completeness sake, not implemented */
- public static final byte BUILTIN_CRITERIA = 5;
-
- public static final byte BUILTIN_PRINT_AREA = 6;
- public static final byte BUILTIN_PRINT_TITLE = 7;
-
- /**Included for completeness sake, not implemented */
- public static final byte BUILTIN_RECORDER = 8;
- /**Included for completeness sake, not implemented */
- public static final byte BUILTIN_DATA_FORM = 9;
- /**Included for completeness sake, not implemented */
- public static final byte BUILTIN_AUTO_ACTIVATE = 10;
- /**Included for completeness sake, not implemented */
- public static final byte BUILTIN_AUTO_DEACTIVATE = 11;
- /**Included for completeness sake, not implemented */
- public static final byte BUILTIN_SHEET_TITLE = 12;
-
- public static final byte BUILTIN_FILTER_DB = 13;
-
- private static final class Option {
- public static final int OPT_HIDDEN_NAME = 0x0001;
- public static final int OPT_FUNCTION_NAME = 0x0002;
- public static final int OPT_COMMAND_NAME = 0x0004;
- public static final int OPT_MACRO = 0x0008;
- public static final int OPT_COMPLEX = 0x0010;
- public static final int OPT_BUILTIN = 0x0020;
- public static final int OPT_BINDATA = 0x1000;
- public static boolean isFormula(int optValue) {
- return (optValue & 0x0F) == 0;
- }
- }
-
- private short field_1_option_flag;
- private byte field_2_keyboard_shortcut;
- /** One-based extern index of sheet (resolved via LinkTable). Zero if this is a global name */
- private short field_5_externSheetIndex_plus1;
- /** the one based sheet number. */
- private int field_6_sheetNumber;
- private boolean field_11_nameIsMultibyte;
- private byte field_12_built_in_code;
- private String field_12_name_text;
- private Formula field_13_name_definition;
- private String field_14_custom_menu_text;
- private String field_15_description_text;
- private String field_16_help_topic_text;
- private String field_17_status_bar_text;
-
-
- /** Creates new NameRecord */
- public NameRecord() {
- field_13_name_definition = Formula.create(Ptg.EMPTY_PTG_ARRAY);
-
- field_12_name_text = "";
- field_14_custom_menu_text = "";
- field_15_description_text = "";
- field_16_help_topic_text = "";
- field_17_status_bar_text = "";
- }
-
- public NameRecord(NameRecord other) {
- super(other);
- field_1_option_flag = other.field_1_option_flag;
- field_2_keyboard_shortcut = other.field_2_keyboard_shortcut;
- field_5_externSheetIndex_plus1 = other.field_5_externSheetIndex_plus1;
- field_6_sheetNumber = other.field_6_sheetNumber;
- field_11_nameIsMultibyte = other.field_11_nameIsMultibyte;
- field_12_built_in_code = other.field_12_built_in_code;
- field_12_name_text = other.field_12_name_text;
- field_13_name_definition = other.field_13_name_definition;
- field_14_custom_menu_text = other.field_14_custom_menu_text;
- field_15_description_text = other.field_15_description_text;
- field_16_help_topic_text = other.field_16_help_topic_text;
- field_17_status_bar_text = other.field_17_status_bar_text;
- }
-
- /**
- * Constructor to create a built-in named region
- * @param builtin Built-in byte representation for the name record, use the public constants
- * @param sheetNumber the sheet which the name applies to
- */
- public NameRecord(byte builtin, int sheetNumber)
- {
- this();
- field_12_built_in_code = builtin;
- setOptionFlag((short)(field_1_option_flag | Option.OPT_BUILTIN));
- // the extern sheets are set through references
- field_6_sheetNumber = sheetNumber;
- }
-
- /** sets the option flag for the named range
- * @param flag option flag
- */
- public void setOptionFlag(short flag){
- field_1_option_flag = flag;
- }
-
-
- /** sets the keyboard shortcut
- * @param shortcut keyboard shortcut
- */
- public void setKeyboardShortcut(byte shortcut){
- field_2_keyboard_shortcut = shortcut;
- }
-
- /**
- * For named ranges, and built-in names
- * @return the 1-based sheet number.
- */
- public int getSheetNumber()
- {
- return field_6_sheetNumber;
- }
-
- /**
- * @return function group
- * @see FnGroupCountRecord
- */
- public byte getFnGroup() {
- int masked = field_1_option_flag & 0x0fc0;
- return (byte) (masked >> 4);
- }
-
-
- public void setSheetNumber(int value)
- {
- field_6_sheetNumber = value;
- }
-
-
- /** sets the name of the named range
- * @param name named range name
- */
- public void setNameText(String name){
- field_12_name_text = name;
- field_11_nameIsMultibyte = StringUtil.hasMultibyte(name);
- }
-
- /** sets the custom menu text
- * @param text custom menu text
- */
- public void setCustomMenuText(String text){
- field_14_custom_menu_text = text;
- }
-
- /** sets the description text
- * @param text the description text
- */
- public void setDescriptionText(String text){
- field_15_description_text = text;
- }
-
- /** sets the help topic text
- * @param text help topix text
- */
- public void setHelpTopicText(String text){
- field_16_help_topic_text = text;
- }
-
- /** sets the status bar text
- * @param text status bar text
- */
- public void setStatusBarText(String text){
- field_17_status_bar_text = text;
- }
-
- /** gets the option flag
- * @return option flag
- */
- public short getOptionFlag(){
- return field_1_option_flag;
- }
-
- /** returns the keyboard shortcut
- * @return keyboard shortcut
- */
- public byte getKeyboardShortcut(){
- return field_2_keyboard_shortcut ;
- }
-
- /**
- * gets the name length, in characters
- * @return name length
- */
- private int getNameTextLength(){
- if (isBuiltInName()) {
- return 1;
- }
- return field_12_name_text.length();
- }
-
-
- /**
- * @return true if name is hidden
- */
- public boolean isHiddenName() {
- return (field_1_option_flag & Option.OPT_HIDDEN_NAME) != 0;
- }
-
- public void setHidden(boolean b) {
- if (b) {
- field_1_option_flag |= Option.OPT_HIDDEN_NAME;
- } else {
- field_1_option_flag &= (~Option.OPT_HIDDEN_NAME);
- }
- }
- /**
- * @return <code>true</code> if name is a function
- */
- public boolean isFunctionName() {
- return (field_1_option_flag & Option.OPT_FUNCTION_NAME) != 0;
- }
-
- /**
- * Indicates that the defined name refers to a user-defined function.
- * This attribute is used when there is an add-in or other code project associated with the file.
- *
- * @param function <code>true</code> indicates the name refers to a function.
- */
- public void setFunction(boolean function){
- if (function) {
- field_1_option_flag |= Option.OPT_FUNCTION_NAME;
- } else {
- field_1_option_flag &= (~Option.OPT_FUNCTION_NAME);
- }
- }
-
- /**
- * @return <code>true</code> if name has a formula (named range or defined value)
- */
- public boolean hasFormula() {
- return Option.isFormula(field_1_option_flag) && field_13_name_definition.getEncodedTokenSize() > 0;
- }
-
- /**
- * @return true if name is a command
- */
- public boolean isCommandName() {
- return (field_1_option_flag & Option.OPT_COMMAND_NAME) != 0;
- }
- /**
- * @return true if function macro or command macro
- */
- public boolean isMacro() {
- return (field_1_option_flag & Option.OPT_MACRO) != 0;
- }
- /**
- * @return true if array formula or user defined
- */
- public boolean isComplexFunction() {
- return (field_1_option_flag & Option.OPT_COMPLEX) != 0;
- }
-
- /**
- * Convenience Function to determine if the name is a built-in name
- *
- * @return true, if the name is a built-in name
- */
- public boolean isBuiltInName()
- {
- return ((field_1_option_flag & Option.OPT_BUILTIN) != 0);
- }
-
-
- /** gets the name
- * @return name
- */
- public String getNameText(){
-
- return isBuiltInName() ? translateBuiltInName(getBuiltInName()) : field_12_name_text;
- }
-
- /** Gets the Built In Name
- * @return the built in Name
- */
- public byte getBuiltInName()
- {
- return field_12_built_in_code;
- }
-
-
- /** gets the definition, reference (Formula)
- * @return the name formula. never <code>null</code>
- */
- public Ptg[] getNameDefinition() {
- return field_13_name_definition.getTokens();
- }
-
- public void setNameDefinition(Ptg[] ptgs) {
- field_13_name_definition = Formula.create(ptgs);
- }
-
- /** get the custom menu text
- * @return custom menu text
- */
- public String getCustomMenuText(){
- return field_14_custom_menu_text;
- }
-
- /** gets the description text
- * @return description text
- */
- public String getDescriptionText(){
- return field_15_description_text;
- }
-
- /** get the help topic text
- * @return gelp topic text
- */
- public String getHelpTopicText(){
- return field_16_help_topic_text;
- }
-
- /** gets the status bar text
- * @return status bar text
- */
- public String getStatusBarText(){
- return field_17_status_bar_text;
- }
+ /**Included for completeness sake, not implemented */
+ public static final byte BUILTIN_CONSOLIDATE_AREA = 1;
+ /**Included for completeness sake, not implemented */
+ public static final byte BUILTIN_AUTO_OPEN = 2;
+ /**Included for completeness sake, not implemented */
+ public static final byte BUILTIN_AUTO_CLOSE = 3;
+ /**Included for completeness sake, not implemented */
+ public static final byte BUILTIN_DATABASE = 4;
+ /**Included for completeness sake, not implemented */
+ public static final byte BUILTIN_CRITERIA = 5;
+
+ public static final byte BUILTIN_PRINT_AREA = 6;
+ public static final byte BUILTIN_PRINT_TITLE = 7;
+
+ /**Included for completeness sake, not implemented */
+ public static final byte BUILTIN_RECORDER = 8;
+ /**Included for completeness sake, not implemented */
+ public static final byte BUILTIN_DATA_FORM = 9;
+ /**Included for completeness sake, not implemented */
+ public static final byte BUILTIN_AUTO_ACTIVATE = 10;
+ /**Included for completeness sake, not implemented */
+ public static final byte BUILTIN_AUTO_DEACTIVATE = 11;
+ /**Included for completeness sake, not implemented */
+ public static final byte BUILTIN_SHEET_TITLE = 12;
+
+ public static final byte BUILTIN_FILTER_DB = 13;
+
+ private static final class Option {
+ public static final int OPT_HIDDEN_NAME = 0x0001;
+ public static final int OPT_FUNCTION_NAME = 0x0002;
+ public static final int OPT_COMMAND_NAME = 0x0004;
+ public static final int OPT_MACRO = 0x0008;
+ public static final int OPT_COMPLEX = 0x0010;
+ public static final int OPT_BUILTIN = 0x0020;
+ public static final int OPT_BINDATA = 0x1000;
+ public static boolean isFormula(int optValue) {
+ return (optValue & 0x0F) == 0;
+ }
+ }
+
+ private short field_1_option_flag;
+ private byte field_2_keyboard_shortcut;
+ /** One-based extern index of sheet (resolved via LinkTable). Zero if this is a global name */
+ private short field_5_externSheetIndex_plus1;
+ /** the one based sheet number. */
+ private int field_6_sheetNumber;
+ private boolean field_11_nameIsMultibyte;
+ private byte field_12_built_in_code;
+ private String field_12_name_text;
+ private Formula field_13_name_definition;
+ private String field_14_custom_menu_text;
+ private String field_15_description_text;
+ private String field_16_help_topic_text;
+ private String field_17_status_bar_text;
+
+
+ /** Creates new NameRecord */
+ public NameRecord() {
+ field_13_name_definition = Formula.create(Ptg.EMPTY_PTG_ARRAY);
+
+ field_12_name_text = "";
+ field_14_custom_menu_text = "";
+ field_15_description_text = "";
+ field_16_help_topic_text = "";
+ field_17_status_bar_text = "";
+ }
+
+ public NameRecord(NameRecord other) {
+ super(other);
+ field_1_option_flag = other.field_1_option_flag;
+ field_2_keyboard_shortcut = other.field_2_keyboard_shortcut;
+ field_5_externSheetIndex_plus1 = other.field_5_externSheetIndex_plus1;
+ field_6_sheetNumber = other.field_6_sheetNumber;
+ field_11_nameIsMultibyte = other.field_11_nameIsMultibyte;
+ field_12_built_in_code = other.field_12_built_in_code;
+ field_12_name_text = other.field_12_name_text;
+ field_13_name_definition = other.field_13_name_definition;
+ field_14_custom_menu_text = other.field_14_custom_menu_text;
+ field_15_description_text = other.field_15_description_text;
+ field_16_help_topic_text = other.field_16_help_topic_text;
+ field_17_status_bar_text = other.field_17_status_bar_text;
+ }
+
+ /**
+ * Constructor to create a built-in named region
+ * @param builtin Built-in byte representation for the name record, use the public constants
+ * @param sheetNumber the sheet which the name applies to
+ */
+ public NameRecord(byte builtin, int sheetNumber)
+ {
+ this();
+ field_12_built_in_code = builtin;
+ setOptionFlag((short)(field_1_option_flag | Option.OPT_BUILTIN));
+ // the extern sheets are set through references
+ field_6_sheetNumber = sheetNumber;
+ }
+
+ /** sets the option flag for the named range
+ * @param flag option flag
+ */
+ public void setOptionFlag(short flag){
+ field_1_option_flag = flag;
+ }
+
+
+ /** sets the keyboard shortcut
+ * @param shortcut keyboard shortcut
+ */
+ public void setKeyboardShortcut(byte shortcut){
+ field_2_keyboard_shortcut = shortcut;
+ }
+
+ /**
+ * For named ranges, and built-in names
+ * @return the 1-based sheet number.
+ */
+ public int getSheetNumber()
+ {
+ return field_6_sheetNumber;
+ }
+
+ /**
+ * @return function group
+ * @see FnGroupCountRecord
+ */
+ public byte getFnGroup() {
+ int masked = field_1_option_flag & 0x0fc0;
+ return (byte) (masked >> 4);
+ }
+
+
+ public void setSheetNumber(int value)
+ {
+ field_6_sheetNumber = value;
+ }
+
+
+ /** sets the name of the named range
+ * @param name named range name
+ */
+ public void setNameText(String name){
+ field_12_name_text = name;
+ field_11_nameIsMultibyte = StringUtil.hasMultibyte(name);
+ }
+
+ /** sets the custom menu text
+ * @param text custom menu text
+ */
+ public void setCustomMenuText(String text){
+ field_14_custom_menu_text = text;
+ }
+
+ /** sets the description text
+ * @param text the description text
+ */
+ public void setDescriptionText(String text){
+ field_15_description_text = text;
+ }
+
+ /** sets the help topic text
+ * @param text help topix text
+ */
+ public void setHelpTopicText(String text){
+ field_16_help_topic_text = text;
+ }
+
+ /** sets the status bar text
+ * @param text status bar text
+ */
+ public void setStatusBarText(String text){
+ field_17_status_bar_text = text;
+ }
+
+ /** gets the option flag
+ * @return option flag
+ */
+ public short getOptionFlag(){
+ return field_1_option_flag;
+ }
+
+ /** returns the keyboard shortcut
+ * @return keyboard shortcut
+ */
+ public byte getKeyboardShortcut(){
+ return field_2_keyboard_shortcut ;
+ }
+
+ /**
+ * gets the name length, in characters
+ * @return name length
+ */
+ private int getNameTextLength(){
+ if (isBuiltInName()) {
+ return 1;
+ }
+ return field_12_name_text.length();
+ }
+
+
+ /**
+ * @return true if name is hidden
+ */
+ public boolean isHiddenName() {
+ return (field_1_option_flag & Option.OPT_HIDDEN_NAME) != 0;
+ }
+
+ public void setHidden(boolean b) {
+ if (b) {
+ field_1_option_flag |= Option.OPT_HIDDEN_NAME;
+ } else {
+ field_1_option_flag &= (~Option.OPT_HIDDEN_NAME);
+ }
+ }
+ /**
+ * @return <code>true</code> if name is a function
+ */
+ public boolean isFunctionName() {
+ return (field_1_option_flag & Option.OPT_FUNCTION_NAME) != 0;
+ }
+
+ /**
+ * Indicates that the defined name refers to a user-defined function.
+ * This attribute is used when there is an add-in or other code project associated with the file.
+ *
+ * @param function <code>true</code> indicates the name refers to a function.
+ */
+ public void setFunction(boolean function){
+ if (function) {
+ field_1_option_flag |= Option.OPT_FUNCTION_NAME;
+ } else {
+ field_1_option_flag &= (~Option.OPT_FUNCTION_NAME);
+ }
+ }
+
+ /**
+ * @return <code>true</code> if name has a formula (named range or defined value)
+ */
+ public boolean hasFormula() {
+ return Option.isFormula(field_1_option_flag) && field_13_name_definition.getEncodedTokenSize() > 0;
+ }
+
+ /**
+ * @return true if name is a command
+ */
+ public boolean isCommandName() {
+ return (field_1_option_flag & Option.OPT_COMMAND_NAME) != 0;
+ }
+ /**
+ * @return true if function macro or command macro
+ */
+ public boolean isMacro() {
+ return (field_1_option_flag & Option.OPT_MACRO) != 0;
+ }
+ /**
+ * @return true if array formula or user defined
+ */
+ public boolean isComplexFunction() {
+ return (field_1_option_flag & Option.OPT_COMPLEX) != 0;
+ }
+
+ /**
+ * Convenience Function to determine if the name is a built-in name
+ *
+ * @return true, if the name is a built-in name
+ */
+ public boolean isBuiltInName()
+ {
+ return ((field_1_option_flag & Option.OPT_BUILTIN) != 0);
+ }
+
+
+ /** gets the name
+ * @return name
+ */
+ public String getNameText(){
+
+ return isBuiltInName() ? translateBuiltInName(getBuiltInName()) : field_12_name_text;
+ }
+
+ /** Gets the Built In Name
+ * @return the built in Name
+ */
+ public byte getBuiltInName()
+ {
+ return field_12_built_in_code;
+ }
+
+
+ /** gets the definition, reference (Formula)
+ * @return the name formula. never <code>null</code>
+ */
+ public Ptg[] getNameDefinition() {
+ return field_13_name_definition.getTokens();
+ }
+
+ public void setNameDefinition(Ptg[] ptgs) {
+ field_13_name_definition = Formula.create(ptgs);
+ }
+
+ /** get the custom menu text
+ * @return custom menu text
+ */
+ public String getCustomMenuText(){
+ return field_14_custom_menu_text;
+ }
+
+ /** gets the description text
+ * @return description text
+ */
+ public String getDescriptionText(){
+ return field_15_description_text;
+ }
+
+ /** get the help topic text
+ * @return gelp topic text
+ */
+ public String getHelpTopicText(){
+ return field_16_help_topic_text;
+ }
+
+ /** gets the status bar text
+ * @return status bar text
+ */
+ public String getStatusBarText(){
+ return field_17_status_bar_text;
+ }
/**
* NameRecord can span into
*
* @param out a data output stream
*/
- @Override
+ @Override
public void serialize(ContinuableRecordOutput out) {
- int field_7_length_custom_menu = field_14_custom_menu_text.length();
- int field_8_length_description_text = field_15_description_text.length();
- int field_9_length_help_topic_text = field_16_help_topic_text.length();
- int field_10_length_status_bar_text = field_17_status_bar_text.length();
-
- // size defined below
- out.writeShort(getOptionFlag());
- out.writeByte(getKeyboardShortcut());
- out.writeByte(getNameTextLength());
- // Note - formula size is not immediately before encoded formula, and does not include any array constant data
- out.writeShort(field_13_name_definition.getEncodedTokenSize());
- out.writeShort(field_5_externSheetIndex_plus1);
- out.writeShort(field_6_sheetNumber);
- out.writeByte(field_7_length_custom_menu);
- out.writeByte(field_8_length_description_text);
- out.writeByte(field_9_length_help_topic_text);
- out.writeByte(field_10_length_status_bar_text);
- out.writeByte(field_11_nameIsMultibyte ? 1 : 0);
-
- if (isBuiltInName()) {
- //can send the builtin name directly in
- out.writeByte(field_12_built_in_code);
- } else {
- String nameText = field_12_name_text;
- if (field_11_nameIsMultibyte) {
- StringUtil.putUnicodeLE(nameText, out);
- } else {
- StringUtil.putCompressedUnicode(nameText, out);
- }
- }
- field_13_name_definition.serializeTokens(out);
- field_13_name_definition.serializeArrayConstantData(out);
-
- StringUtil.putCompressedUnicode( getCustomMenuText(), out);
- StringUtil.putCompressedUnicode( getDescriptionText(), out);
- StringUtil.putCompressedUnicode( getHelpTopicText(), out);
- StringUtil.putCompressedUnicode( getStatusBarText(), out);
- }
- private int getNameRawSize() {
- if (isBuiltInName()) {
- return 1;
- }
- int nChars = field_12_name_text.length();
- if(field_11_nameIsMultibyte) {
- return 2 * nChars;
- }
- return nChars;
- }
-
- int getDataSize() {
- return 13 // 3 shorts + 7 bytes
- + getNameRawSize()
- + field_14_custom_menu_text.length()
- + field_15_description_text.length()
- + field_16_help_topic_text.length()
- + field_17_status_bar_text.length()
- + field_13_name_definition.getEncodedSize();
- }
-
- /** gets the extern sheet number
- * @return extern sheet index
- */
- public int getExternSheetNumber(){
- Ptg[] tokens = field_13_name_definition.getTokens();
- if (tokens.length == 0) {
- return 0;
- }
-
- Ptg ptg = tokens[0];
- if (ptg.getClass() == Area3DPtg.class){
- return ((Area3DPtg) ptg).getExternSheetIndex();
-
- }
- if (ptg.getClass() == Ref3DPtg.class){
- return ((Ref3DPtg) ptg).getExternSheetIndex();
- }
- return 0;
- }
-
- /**
- * called by the constructor, should set class level fields. Should throw
- * runtime exception for bad/icomplete data.
- *
- * @param ris the RecordInputstream to read the record from
- */
- public NameRecord(RecordInputStream ris) {
+ int field_7_length_custom_menu = field_14_custom_menu_text.length();
+ int field_8_length_description_text = field_15_description_text.length();
+ int field_9_length_help_topic_text = field_16_help_topic_text.length();
+ int field_10_length_status_bar_text = field_17_status_bar_text.length();
+
+ // size defined below
+ out.writeShort(getOptionFlag());
+ out.writeByte(getKeyboardShortcut());
+ out.writeByte(getNameTextLength());
+ // Note - formula size is not immediately before encoded formula, and does not include any array constant data
+ out.writeShort(field_13_name_definition.getEncodedTokenSize());
+ out.writeShort(field_5_externSheetIndex_plus1);
+ out.writeShort(field_6_sheetNumber);
+ out.writeByte(field_7_length_custom_menu);
+ out.writeByte(field_8_length_description_text);
+ out.writeByte(field_9_length_help_topic_text);
+ out.writeByte(field_10_length_status_bar_text);
+ out.writeByte(field_11_nameIsMultibyte ? 1 : 0);
+
+ if (isBuiltInName()) {
+ //can send the builtin name directly in
+ out.writeByte(field_12_built_in_code);
+ } else {
+ String nameText = field_12_name_text;
+ if (field_11_nameIsMultibyte) {
+ StringUtil.putUnicodeLE(nameText, out);
+ } else {
+ StringUtil.putCompressedUnicode(nameText, out);
+ }
+ }
+ field_13_name_definition.serializeTokens(out);
+ field_13_name_definition.serializeArrayConstantData(out);
+
+ StringUtil.putCompressedUnicode( getCustomMenuText(), out);
+ StringUtil.putCompressedUnicode( getDescriptionText(), out);
+ StringUtil.putCompressedUnicode( getHelpTopicText(), out);
+ StringUtil.putCompressedUnicode( getStatusBarText(), out);
+ }
+ private int getNameRawSize() {
+ if (isBuiltInName()) {
+ return 1;
+ }
+ int nChars = field_12_name_text.length();
+ if(field_11_nameIsMultibyte) {
+ return 2 * nChars;
+ }
+ return nChars;
+ }
+
+ int getDataSize() {
+ return 13 // 3 shorts + 7 bytes
+ + getNameRawSize()
+ + field_14_custom_menu_text.length()
+ + field_15_description_text.length()
+ + field_16_help_topic_text.length()
+ + field_17_status_bar_text.length()
+ + field_13_name_definition.getEncodedSize();
+ }
+
+ /** gets the extern sheet number
+ * @return extern sheet index
+ */
+ public int getExternSheetNumber(){
+ Ptg[] tokens = field_13_name_definition.getTokens();
+ if (tokens.length == 0) {
+ return 0;
+ }
+
+ Ptg ptg = tokens[0];
+ if (ptg.getClass() == Area3DPtg.class){
+ return ((Area3DPtg) ptg).getExternSheetIndex();
+
+ }
+ if (ptg.getClass() == Ref3DPtg.class){
+ return ((Ref3DPtg) ptg).getExternSheetIndex();
+ }
+ return 0;
+ }
+
+ /**
+ * called by the constructor, should set class level fields. Should throw
+ * runtime exception for bad/icomplete data.
+ *
+ * @param ris the RecordInputstream to read the record from
+ */
+ public NameRecord(RecordInputStream ris) {
// YK: Formula data can span into continue records, for example,
// when containing a large array of strings. See Bugzilla 50244
@@ -466,151 +466,151 @@ public final class NameRecord extends Co
byte[] remainder = ris.readAllContinuedRemainder();
LittleEndianInput in = new LittleEndianByteArrayInputStream(remainder);
- field_1_option_flag = in.readShort();
- field_2_keyboard_shortcut = in.readByte();
- int field_3_length_name_text = in.readUByte();
- int field_4_length_name_definition = in.readShort();
- field_5_externSheetIndex_plus1 = in.readShort();
- field_6_sheetNumber = in.readUShort();
- int f7_customMenuLen = in.readUByte();
- int f8_descriptionTextLen = in.readUByte();
- int f9_helpTopicTextLen = in.readUByte();
- int f10_statusBarTextLen = in.readUByte();
-
- //store the name in byte form if it's a built-in name
- field_11_nameIsMultibyte = (in.readByte() != 0);
- if (isBuiltInName()) {
- field_12_built_in_code = in.readByte();
- } else {
- if (field_11_nameIsMultibyte) {
- field_12_name_text = StringUtil.readUnicodeLE(in, field_3_length_name_text);
- } else {
- field_12_name_text = StringUtil.readCompressedUnicode(in, field_3_length_name_text);
- }
- }
-
- int nBytesAvailable = in.available() - (f7_customMenuLen
- + f8_descriptionTextLen + f9_helpTopicTextLen + f10_statusBarTextLen);
- field_13_name_definition = Formula.read(field_4_length_name_definition, in, nBytesAvailable);
-
- //Who says that this can only ever be compressed unicode???
- field_14_custom_menu_text = StringUtil.readCompressedUnicode(in, f7_customMenuLen);
- field_15_description_text = StringUtil.readCompressedUnicode(in, f8_descriptionTextLen);
- field_16_help_topic_text = StringUtil.readCompressedUnicode(in, f9_helpTopicTextLen);
- field_17_status_bar_text = StringUtil.readCompressedUnicode(in, f10_statusBarTextLen);
- }
-
- /**
- * return the non static version of the id for this record.
- */
- @Override
+ field_1_option_flag = in.readShort();
+ field_2_keyboard_shortcut = in.readByte();
+ int field_3_length_name_text = in.readUByte();
+ int field_4_length_name_definition = in.readShort();
+ field_5_externSheetIndex_plus1 = in.readShort();
+ field_6_sheetNumber = in.readUShort();
+ int f7_customMenuLen = in.readUByte();
+ int f8_descriptionTextLen = in.readUByte();
+ int f9_helpTopicTextLen = in.readUByte();
+ int f10_statusBarTextLen = in.readUByte();
+
+ //store the name in byte form if it's a built-in name
+ field_11_nameIsMultibyte = (in.readByte() != 0);
+ if (isBuiltInName()) {
+ field_12_built_in_code = in.readByte();
+ } else {
+ if (field_11_nameIsMultibyte) {
+ field_12_name_text = StringUtil.readUnicodeLE(in, field_3_length_name_text);
+ } else {
+ field_12_name_text = StringUtil.readCompressedUnicode(in, field_3_length_name_text);
+ }
+ }
+
+ int nBytesAvailable = in.available() - (f7_customMenuLen
+ + f8_descriptionTextLen + f9_helpTopicTextLen + f10_statusBarTextLen);
+ field_13_name_definition = Formula.read(field_4_length_name_definition, in, nBytesAvailable);
+
+ //Who says that this can only ever be compressed unicode???
+ field_14_custom_menu_text = StringUtil.readCompressedUnicode(in, f7_customMenuLen);
+ field_15_description_text = StringUtil.readCompressedUnicode(in, f8_descriptionTextLen);
+ field_16_help_topic_text = StringUtil.readCompressedUnicode(in, f9_helpTopicTextLen);
+ field_17_status_bar_text = StringUtil.readCompressedUnicode(in, f10_statusBarTextLen);
+ }
+
+ /**
+ * return the non static version of the id for this record.
+ */
+ @Override
public short getSid() {
- return sid;
- }
- /*
- 20 00
- 00
- 01
- 1A 00 // sz = 0x1A = 26
- 00 00
- 01 00
- 00
- 00
- 00
- 00
- 00 // unicode flag
- 07 // name
-
- 29 17 00 3B 00 00 00 00 FF FF 00 00 02 00 3B 00 //{ 26
- 00 07 00 07 00 00 00 FF 00 10 // }
+ return sid;
+ }
+ /*
+ 20 00
+ 00
+ 01
+ 1A 00 // sz = 0x1A = 26
+ 00 00
+ 01 00
+ 00
+ 00
+ 00
+ 00
+ 00 // unicode flag
+ 07 // name
+
+ 29 17 00 3B 00 00 00 00 FF FF 00 00 02 00 3B 00 //{ 26
+ 00 07 00 07 00 00 00 FF 00 10 // }
- 20 00
- 00
- 01
- 0B 00 // sz = 0xB = 11
- 00 00
- 01 00
- 00
- 00
- 00
- 00
- 00 // unicode flag
- 07 // name
+ 20 00
+ 00
+ 01
+ 0B 00 // sz = 0xB = 11
+ 00 00
+ 01 00
+ 00
+ 00
+ 00
+ 00
+ 00 // unicode flag
+ 07 // name
- 3B 00 00 07 00 07 00 00 00 FF 00 // { 11 }
+ 3B 00 00 07 00 07 00 00 00 FF 00 // { 11 }
*/
- /*
- 18, 00,
- 1B, 00,
-
- 20, 00,
- 00,
- 01,
- 0B, 00,
- 00,
- 00,
- 00,
- 00,
- 00,
- 07,
- 3B 00 00 07 00 07 00 00 00 FF 00 ]
- */
-
- /**Creates a human readable name for built in types
- * @return Unknown if the built-in name cannot be translated
- */
- private static String translateBuiltInName(byte name)
- {
- switch (name)
- {
- case NameRecord.BUILTIN_AUTO_ACTIVATE : return "Auto_Activate";
- case NameRecord.BUILTIN_AUTO_CLOSE : return "Auto_Close";
- case NameRecord.BUILTIN_AUTO_DEACTIVATE : return "Auto_Deactivate";
- case NameRecord.BUILTIN_AUTO_OPEN : return "Auto_Open";
- case NameRecord.BUILTIN_CONSOLIDATE_AREA : return "Consolidate_Area";
- case NameRecord.BUILTIN_CRITERIA : return "Criteria";
- case NameRecord.BUILTIN_DATABASE : return "Database";
- case NameRecord.BUILTIN_DATA_FORM : return "Data_Form";
- case NameRecord.BUILTIN_PRINT_AREA : return "Print_Area";
- case NameRecord.BUILTIN_PRINT_TITLE : return "Print_Titles";
- case NameRecord.BUILTIN_RECORDER : return "Recorder";
- case NameRecord.BUILTIN_SHEET_TITLE : return "Sheet_Title";
- case NameRecord.BUILTIN_FILTER_DB : return "_FilterDatabase";
-
- }
-
- return "Unknown";
- }
-
- @Override
- public NameRecord copy() {
- return new NameRecord(this);
- }
-
- @Override
- public HSSFRecordTypes getGenericRecordType() {
- return HSSFRecordTypes.NAME;
- }
-
- @Override
- public Map<String, Supplier<?>> getGenericProperties() {
- final Map<String,Supplier<?>> m = new LinkedHashMap<>();
- m.put("dataSize", this::getDataSize);
- m.put("optionFlag", this::getOptionFlag);
- m.put("keyboardShortcut", this::getKeyboardShortcut);
- m.put("externSheetIndex", () -> field_5_externSheetIndex_plus1);
- m.put("sheetNumber", this::getSheetNumber);
- m.put("nameIsMultibyte", () -> field_11_nameIsMultibyte);
- m.put("builtInName", this::getBuiltInName);
- m.put("nameLength", this::getNameTextLength);
- m.put("nameText", this::getNameText);
- m.put("formula", this::getNameDefinition);
- m.put("customMenuText", this::getCustomMenuText);
- m.put("descriptionText", this::getDescriptionText);
- m.put("helpTopicText", this::getHelpTopicText);
- m.put("statusBarText", this::getStatusBarText);
- return Collections.unmodifiableMap(m);
- }
+ /*
+ 18, 00,
+ 1B, 00,
+
+ 20, 00,
+ 00,
+ 01,
+ 0B, 00,
+ 00,
+ 00,
+ 00,
+ 00,
+ 00,
+ 07,
+ 3B 00 00 07 00 07 00 00 00 FF 00 ]
+ */
+
+ /**Creates a human readable name for built in types
+ * @return Unknown if the built-in name cannot be translated
+ */
+ private static String translateBuiltInName(byte name)
+ {
+ switch (name)
+ {
+ case NameRecord.BUILTIN_AUTO_ACTIVATE : return "Auto_Activate";
+ case NameRecord.BUILTIN_AUTO_CLOSE : return "Auto_Close";
+ case NameRecord.BUILTIN_AUTO_DEACTIVATE : return "Auto_Deactivate";
+ case NameRecord.BUILTIN_AUTO_OPEN : return "Auto_Open";
+ case NameRecord.BUILTIN_CONSOLIDATE_AREA : return "Consolidate_Area";
+ case NameRecord.BUILTIN_CRITERIA : return "Criteria";
+ case NameRecord.BUILTIN_DATABASE : return "Database";
+ case NameRecord.BUILTIN_DATA_FORM : return "Data_Form";
+ case NameRecord.BUILTIN_PRINT_AREA : return "Print_Area";
+ case NameRecord.BUILTIN_PRINT_TITLE : return "Print_Titles";
+ case NameRecord.BUILTIN_RECORDER : return "Recorder";
+ case NameRecord.BUILTIN_SHEET_TITLE : return "Sheet_Title";
+ case NameRecord.BUILTIN_FILTER_DB : return "_FilterDatabase";
+
+ }
+
+ return "Unknown";
+ }
+
+ @Override
+ public NameRecord copy() {
+ return new NameRecord(this);
+ }
+
+ @Override
+ public HSSFRecordTypes getGenericRecordType() {
+ return HSSFRecordTypes.NAME;
+ }
+
+ @Override
+ public Map<String, Supplier<?>> getGenericProperties() {
+ final Map<String,Supplier<?>> m = new LinkedHashMap<>();
+ m.put("dataSize", this::getDataSize);
+ m.put("optionFlag", this::getOptionFlag);
+ m.put("keyboardShortcut", this::getKeyboardShortcut);
+ m.put("externSheetIndex", () -> field_5_externSheetIndex_plus1);
+ m.put("sheetNumber", this::getSheetNumber);
+ m.put("nameIsMultibyte", () -> field_11_nameIsMultibyte);
+ m.put("builtInName", this::getBuiltInName);
+ m.put("nameLength", this::getNameTextLength);
+ m.put("nameText", this::getNameText);
+ m.put("formula", this::getNameDefinition);
+ m.put("customMenuText", this::getCustomMenuText);
+ m.put("descriptionText", this::getDescriptionText);
+ m.put("helpTopicText", this::getHelpTopicText);
+ m.put("statusBarText", this::getStatusBarText);
+ return Collections.unmodifiableMap(m);
+ }
}
Modified: poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/NoteRecord.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/NoteRecord.java?rev=1890120&r1=1890119&r2=1890120&view=diff
==============================================================================
--- poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/NoteRecord.java (original)
+++ poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/NoteRecord.java Sat May 22 20:56:44 2021
@@ -28,237 +28,237 @@ import org.apache.poi.util.StringUtil;
* NOTE: Comment Associated with a Cell (0x001C)
*/
public final class NoteRecord extends StandardRecord {
- public static final short sid = 0x001C;
+ public static final short sid = 0x001C;
- public static final NoteRecord[] EMPTY_ARRAY = { };
+ public static final NoteRecord[] EMPTY_ARRAY = { };
- /**
- * Flag indicating that the comment is hidden (default)
- */
- public static final short NOTE_HIDDEN = 0x0;
-
- /**
- * Flag indicating that the comment is visible
- */
- public static final short NOTE_VISIBLE = 0x2;
-
- private static final Byte DEFAULT_PADDING = (byte) 0;
-
- private int field_1_row;
- private int field_2_col;
- private short field_3_flags;
- private int field_4_shapeid;
- private boolean field_5_hasMultibyte;
- private String field_6_author;
-
- /**
- * Saves padding byte value to reduce delta during round-trip serialization.<br>
- *
- * The documentation is not clear about how padding should work. In any case
- * Excel(2007) does something different.
- */
- private Byte field_7_padding;
-
- /**
- * Construct a new <code>NoteRecord</code> and
- * fill its data with the default values
- */
- public NoteRecord() {
- field_6_author = "";
- field_3_flags = 0;
- field_7_padding = DEFAULT_PADDING; // seems to be always present regardless of author text
- }
-
- public NoteRecord(NoteRecord other) {
- super(other);
- field_1_row = other.field_1_row;
- field_2_col = other.field_2_col;
- field_3_flags = other.field_3_flags;
- field_4_shapeid = other.field_4_shapeid;
- field_5_hasMultibyte = other.field_5_hasMultibyte;
- field_6_author = other.field_6_author;
- field_7_padding = other.field_7_padding;
- }
-
- /**
- * @return id of this record.
- */
- public short getSid() {
- return sid;
- }
-
- /**
- * Read the record data from the supplied <code>RecordInputStream</code>
- *
- * @param in the RecordInputStream to read from
- */
- public NoteRecord(RecordInputStream in) {
- field_1_row = in.readUShort();
- field_2_col = in.readShort();
- field_3_flags = in.readShort();
- field_4_shapeid = in.readUShort();
- int length = in.readShort();
- field_5_hasMultibyte = in.readByte() != 0x00;
- if (field_5_hasMultibyte) {
- field_6_author = StringUtil.readUnicodeLE(in, length);
- } else {
- field_6_author = StringUtil.readCompressedUnicode(in, length);
- }
- if (in.available() == 1) {
- field_7_padding = in.readByte();
- } else if (in.available() == 2 && length == 0) {
- // If there's no author, may be double padded
+ /**
+ * Flag indicating that the comment is hidden (default)
+ */
+ public static final short NOTE_HIDDEN = 0x0;
+
+ /**
+ * Flag indicating that the comment is visible
+ */
+ public static final short NOTE_VISIBLE = 0x2;
+
+ private static final Byte DEFAULT_PADDING = (byte) 0;
+
+ private int field_1_row;
+ private int field_2_col;
+ private short field_3_flags;
+ private int field_4_shapeid;
+ private boolean field_5_hasMultibyte;
+ private String field_6_author;
+
+ /**
+ * Saves padding byte value to reduce delta during round-trip serialization.<br>
+ *
+ * The documentation is not clear about how padding should work. In any case
+ * Excel(2007) does something different.
+ */
+ private Byte field_7_padding;
+
+ /**
+ * Construct a new <code>NoteRecord</code> and
+ * fill its data with the default values
+ */
+ public NoteRecord() {
+ field_6_author = "";
+ field_3_flags = 0;
+ field_7_padding = DEFAULT_PADDING; // seems to be always present regardless of author text
+ }
+
+ public NoteRecord(NoteRecord other) {
+ super(other);
+ field_1_row = other.field_1_row;
+ field_2_col = other.field_2_col;
+ field_3_flags = other.field_3_flags;
+ field_4_shapeid = other.field_4_shapeid;
+ field_5_hasMultibyte = other.field_5_hasMultibyte;
+ field_6_author = other.field_6_author;
+ field_7_padding = other.field_7_padding;
+ }
+
+ /**
+ * @return id of this record.
+ */
+ public short getSid() {
+ return sid;
+ }
+
+ /**
+ * Read the record data from the supplied <code>RecordInputStream</code>
+ *
+ * @param in the RecordInputStream to read from
+ */
+ public NoteRecord(RecordInputStream in) {
+ field_1_row = in.readUShort();
+ field_2_col = in.readShort();
+ field_3_flags = in.readShort();
+ field_4_shapeid = in.readUShort();
+ int length = in.readShort();
+ field_5_hasMultibyte = in.readByte() != 0x00;
+ if (field_5_hasMultibyte) {
+ field_6_author = StringUtil.readUnicodeLE(in, length);
+ } else {
+ field_6_author = StringUtil.readCompressedUnicode(in, length);
+ }
+ if (in.available() == 1) {
+ field_7_padding = in.readByte();
+ } else if (in.available() == 2 && length == 0) {
+ // If there's no author, may be double padded
field_7_padding = in.readByte();
in.readByte();
- }
- }
+ }
+ }
- public void serialize(LittleEndianOutput out) {
- out.writeShort(field_1_row);
- out.writeShort(field_2_col);
- out.writeShort(field_3_flags);
- out.writeShort(field_4_shapeid);
- out.writeShort(field_6_author.length());
- out.writeByte(field_5_hasMultibyte ? 0x01 : 0x00);
- if (field_5_hasMultibyte) {
- StringUtil.putUnicodeLE(field_6_author, out);
- } else {
- StringUtil.putCompressedUnicode(field_6_author, out);
- }
- if (field_7_padding != null) {
- out.writeByte(field_7_padding.intValue());
- }
- }
-
- protected int getDataSize() {
- return 11 // 5 shorts + 1 byte
- + field_6_author.length() * (field_5_hasMultibyte ? 2 : 1)
- + (field_7_padding == null ? 0 : 1);
- }
-
- /**
- * Return the row that contains the comment
- *
- * @return the row that contains the comment
- */
- public int getRow() {
- return field_1_row;
- }
-
- /**
- * Specify the row that contains the comment
- *
- * @param row the row that contains the comment
- */
- public void setRow(int row) {
- field_1_row = row;
- }
-
- /**
- * Return the column that contains the comment
- *
- * @return the column that contains the comment
- */
- public int getColumn() {
- return field_2_col;
- }
-
- /**
- * Specify the column that contains the comment
- *
- * @param col the column that contains the comment
- */
- public void setColumn(int col) {
- field_2_col = col;
- }
-
- /**
- * Options flags.
- *
- * @return the options flag
- * @see #NOTE_VISIBLE
- * @see #NOTE_HIDDEN
- */
- public short getFlags() {
- return field_3_flags;
- }
-
- /**
- * Options flag
- *
- * @param flags the options flag
- * @see #NOTE_VISIBLE
- * @see #NOTE_HIDDEN
- */
- public void setFlags(short flags) {
- field_3_flags = flags;
- }
-
- /**
- * For unit testing only!
- *
- * @return true, if author element uses multi byte
- */
- boolean authorIsMultibyte() {
- return field_5_hasMultibyte;
- }
-
- /**
- * Object id for OBJ record that contains the comment
- *
- * @return the Object id for OBJ record that contains the comment
- */
- public int getShapeId() {
- return field_4_shapeid;
- }
-
- /**
- * Object id for OBJ record that contains the comment
- *
- * @param id the Object id for OBJ record that contains the comment
- */
- public void setShapeId(int id) {
- field_4_shapeid = id;
- }
-
- /**
- * Name of the original comment author
- *
- * @return the name of the original author of the comment
- */
- public String getAuthor() {
- return field_6_author;
- }
-
- /**
- * Name of the original comment author
- *
- * @param author the name of the original author of the comment
- */
- public void setAuthor(String author) {
- field_6_author = author;
- field_5_hasMultibyte = StringUtil.hasMultibyte(author);
- }
-
-
- @Override
- public NoteRecord copy() {
- return new NoteRecord(this);
- }
-
- @Override
- public HSSFRecordTypes getGenericRecordType() {
- return HSSFRecordTypes.NOTE;
- }
-
- @Override
- public Map<String, Supplier<?>> getGenericProperties() {
- return GenericRecordUtil.getGenericProperties(
- "row", this::getRow,
- "column", this::getColumn,
- "flags", this::getFlags,
- "shapeId", this::getShapeId,
- "author", this::getAuthor
- );
- }
+ public void serialize(LittleEndianOutput out) {
+ out.writeShort(field_1_row);
+ out.writeShort(field_2_col);
+ out.writeShort(field_3_flags);
+ out.writeShort(field_4_shapeid);
+ out.writeShort(field_6_author.length());
+ out.writeByte(field_5_hasMultibyte ? 0x01 : 0x00);
+ if (field_5_hasMultibyte) {
+ StringUtil.putUnicodeLE(field_6_author, out);
+ } else {
+ StringUtil.putCompressedUnicode(field_6_author, out);
+ }
+ if (field_7_padding != null) {
+ out.writeByte(field_7_padding.intValue());
+ }
+ }
+
+ protected int getDataSize() {
+ return 11 // 5 shorts + 1 byte
+ + field_6_author.length() * (field_5_hasMultibyte ? 2 : 1)
+ + (field_7_padding == null ? 0 : 1);
+ }
+
+ /**
+ * Return the row that contains the comment
+ *
+ * @return the row that contains the comment
+ */
+ public int getRow() {
+ return field_1_row;
+ }
+
+ /**
+ * Specify the row that contains the comment
+ *
+ * @param row the row that contains the comment
+ */
+ public void setRow(int row) {
+ field_1_row = row;
+ }
+
+ /**
+ * Return the column that contains the comment
+ *
+ * @return the column that contains the comment
+ */
+ public int getColumn() {
+ return field_2_col;
+ }
+
+ /**
+ * Specify the column that contains the comment
+ *
+ * @param col the column that contains the comment
+ */
+ public void setColumn(int col) {
+ field_2_col = col;
+ }
+
+ /**
+ * Options flags.
+ *
+ * @return the options flag
+ * @see #NOTE_VISIBLE
+ * @see #NOTE_HIDDEN
+ */
+ public short getFlags() {
+ return field_3_flags;
+ }
+
+ /**
+ * Options flag
+ *
+ * @param flags the options flag
+ * @see #NOTE_VISIBLE
+ * @see #NOTE_HIDDEN
+ */
+ public void setFlags(short flags) {
+ field_3_flags = flags;
+ }
+
+ /**
+ * For unit testing only!
+ *
+ * @return true, if author element uses multi byte
+ */
+ boolean authorIsMultibyte() {
+ return field_5_hasMultibyte;
+ }
+
+ /**
+ * Object id for OBJ record that contains the comment
+ *
+ * @return the Object id for OBJ record that contains the comment
+ */
+ public int getShapeId() {
+ return field_4_shapeid;
+ }
+
+ /**
+ * Object id for OBJ record that contains the comment
+ *
+ * @param id the Object id for OBJ record that contains the comment
+ */
+ public void setShapeId(int id) {
+ field_4_shapeid = id;
+ }
+
+ /**
+ * Name of the original comment author
+ *
+ * @return the name of the original author of the comment
+ */
+ public String getAuthor() {
+ return field_6_author;
+ }
+
+ /**
+ * Name of the original comment author
+ *
+ * @param author the name of the original author of the comment
+ */
+ public void setAuthor(String author) {
+ field_6_author = author;
+ field_5_hasMultibyte = StringUtil.hasMultibyte(author);
+ }
+
+
+ @Override
+ public NoteRecord copy() {
+ return new NoteRecord(this);
+ }
+
+ @Override
+ public HSSFRecordTypes getGenericRecordType() {
+ return HSSFRecordTypes.NOTE;
+ }
+
+ @Override
+ public Map<String, Supplier<?>> getGenericProperties() {
+ return GenericRecordUtil.getGenericProperties(
+ "row", this::getRow,
+ "column", this::getColumn,
+ "flags", this::getFlags,
+ "shapeId", this::getShapeId,
+ "author", this::getAuthor
+ );
+ }
}
Modified: poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/NoteStructureSubRecord.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/NoteStructureSubRecord.java?rev=1890120&r1=1890119&r2=1890120&view=diff
==============================================================================
--- poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/NoteStructureSubRecord.java (original)
+++ poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/NoteStructureSubRecord.java Sat May 22 20:56:44 2021
@@ -85,7 +85,7 @@ public final class NoteStructureSubRecor
out.write(reserved);
}
- @Override
+ @Override
protected int getDataSize() {
return reserved.length;
}
Modified: poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/PageBreakRecord.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/PageBreakRecord.java?rev=1890120&r1=1890119&r2=1890120&view=diff
==============================================================================
--- poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/PageBreakRecord.java (original)
+++ poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/PageBreakRecord.java Sat May 22 20:56:44 2021
@@ -124,7 +124,7 @@ public abstract class PageBreakRecord ex
}
public boolean isEmpty() {
- return _breaks.isEmpty();
+ return _breaks.isEmpty();
}
protected int getDataSize() {
return 2 + _breaks.size() * Break.ENCODED_SIZE;
Modified: poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/RKRecord.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/RKRecord.java?rev=1890120&r1=1890119&r2=1890120&view=diff
==============================================================================
--- poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/RKRecord.java (original)
+++ poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/RKRecord.java Sat May 22 20:56:44 2021
@@ -75,17 +75,17 @@ public final class RKRecord extends Cell
@Override
protected String getRecordName() {
- return "RK";
+ return "RK";
}
@Override
protected void serializeValue(LittleEndianOutput out) {
- out.writeInt(field_4_rk_number);
+ out.writeInt(field_4_rk_number);
}
@Override
protected int getValueDataSize() {
- return 4;
+ return 4;
}
@Override
Modified: poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/RecalcIdRecord.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/RecalcIdRecord.java?rev=1890120&r1=1890119&r2=1890120&view=diff
==============================================================================
--- poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/RecalcIdRecord.java (original)
+++ poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/RecalcIdRecord.java Sat May 22 20:56:44 2021
@@ -56,9 +56,9 @@ public final class RecalcIdRecord extend
}
public RecalcIdRecord(RecordInputStream in) {
- in.readUShort(); // field 'rt' should have value 0x01C1, but Excel doesn't care during reading
- _reserved0 = in.readUShort();
- _engineId = in.readInt();
+ in.readUShort(); // field 'rt' should have value 0x01C1, but Excel doesn't care during reading
+ _reserved0 = in.readUShort();
+ _engineId = in.readInt();
}
public boolean isNeeded() {
Modified: poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/RecordBase.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/RecordBase.java?rev=1890120&r1=1890119&r2=1890120&view=diff
==============================================================================
--- poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/RecordBase.java (original)
+++ poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/RecordBase.java Sat May 22 20:56:44 2021
@@ -21,22 +21,22 @@ package org.apache.poi.hssf.record;
* Common base class of {@link Record} and {@link org.apache.poi.hssf.record.aggregates.RecordAggregate}
*/
public abstract class RecordBase {
- /**
- * called by the class that is responsible for writing this sucker.
- * Subclasses should implement this so that their data is passed back in a
- * byte array.
- *
- * @param offset to begin writing at
- * @param data byte array containing instance data
- * @return number of bytes written
- */
- public abstract int serialize(int offset, byte[] data);
+ /**
+ * called by the class that is responsible for writing this sucker.
+ * Subclasses should implement this so that their data is passed back in a
+ * byte array.
+ *
+ * @param offset to begin writing at
+ * @param data byte array containing instance data
+ * @return number of bytes written
+ */
+ public abstract int serialize(int offset, byte[] data);
- /**
- * gives the current serialized size of the record. Should include the sid
- * and reclength (4 bytes).
- *
- * @return the record size
- */
- public abstract int getRecordSize();
+ /**
+ * gives the current serialized size of the record. Should include the sid
+ * and reclength (4 bytes).
+ *
+ * @return the record size
+ */
+ public abstract int getRecordSize();
}
Modified: poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/RecordFactoryInputStream.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/RecordFactoryInputStream.java?rev=1890120&r1=1890119&r2=1890120&view=diff
==============================================================================
--- poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/RecordFactoryInputStream.java (original)
+++ poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/RecordFactoryInputStream.java Sat May 22 20:56:44 2021
@@ -41,75 +41,75 @@ import org.apache.poi.util.RecordFormatE
*/
public final class RecordFactoryInputStream {
- /**
- * Keeps track of the sizes of the initial records up to and including {@link FilePassRecord}
- * Needed for protected files because each byte is encrypted with respect to its absolute
- * position from the start of the stream.
- */
- private static final class StreamEncryptionInfo {
- private final int _initialRecordsSize;
- private final FilePassRecord _filePassRec;
- private final Record _lastRecord;
- private final boolean _hasBOFRecord;
-
- public StreamEncryptionInfo(RecordInputStream rs, List<org.apache.poi.hssf.record.Record> outputRecs) {
- Record rec;
- rs.nextRecord();
- int recSize = 4 + rs.remaining();
- rec = RecordFactory.createSingleRecord(rs);
- outputRecs.add(rec);
- FilePassRecord fpr = null;
- if (rec instanceof BOFRecord) {
- _hasBOFRecord = true;
-
- // Fetch the next record, and see if it indicates whether
- // the document is encrypted or not
- if (rs.hasNextRecord()) {
- rs.nextRecord();
- rec = RecordFactory.createSingleRecord(rs);
- recSize += rec.getRecordSize();
- outputRecs.add(rec);
-
- // Encrypted is normally BOF then FILEPASS
- // May sometimes be BOF, WRITEPROTECT, FILEPASS
- if (rec instanceof WriteProtectRecord && rs.hasNextRecord()) {
- rs.nextRecord();
- rec = RecordFactory.createSingleRecord(rs);
- recSize += rec.getRecordSize();
- outputRecs.add(rec);
- }
-
- // If it's a FILEPASS, track it specifically
- if (rec instanceof FilePassRecord) {
- fpr = (FilePassRecord) rec;
- }
-
- // workbook not encrypted (typical case)
- if (rec instanceof EOFRecord) {
- // A workbook stream is never empty, so crash instead
- // of trying to keep track of nesting level
- throw new IllegalStateException("Nothing between BOF and EOF");
- }
- }
- } else {
- // Invalid in a normal workbook stream.
- // However, some test cases work on sub-sections of
- // the workbook stream that do not begin with BOF
- _hasBOFRecord = false;
- }
- _initialRecordsSize = recSize;
- _filePassRec = fpr;
- _lastRecord = rec;
- }
+ /**
+ * Keeps track of the sizes of the initial records up to and including {@link FilePassRecord}
+ * Needed for protected files because each byte is encrypted with respect to its absolute
+ * position from the start of the stream.
+ */
+ private static final class StreamEncryptionInfo {
+ private final int _initialRecordsSize;
+ private final FilePassRecord _filePassRec;
+ private final Record _lastRecord;
+ private final boolean _hasBOFRecord;
+
+ public StreamEncryptionInfo(RecordInputStream rs, List<org.apache.poi.hssf.record.Record> outputRecs) {
+ Record rec;
+ rs.nextRecord();
+ int recSize = 4 + rs.remaining();
+ rec = RecordFactory.createSingleRecord(rs);
+ outputRecs.add(rec);
+ FilePassRecord fpr = null;
+ if (rec instanceof BOFRecord) {
+ _hasBOFRecord = true;
+
+ // Fetch the next record, and see if it indicates whether
+ // the document is encrypted or not
+ if (rs.hasNextRecord()) {
+ rs.nextRecord();
+ rec = RecordFactory.createSingleRecord(rs);
+ recSize += rec.getRecordSize();
+ outputRecs.add(rec);
+
+ // Encrypted is normally BOF then FILEPASS
+ // May sometimes be BOF, WRITEPROTECT, FILEPASS
+ if (rec instanceof WriteProtectRecord && rs.hasNextRecord()) {
+ rs.nextRecord();
+ rec = RecordFactory.createSingleRecord(rs);
+ recSize += rec.getRecordSize();
+ outputRecs.add(rec);
+ }
+
+ // If it's a FILEPASS, track it specifically
+ if (rec instanceof FilePassRecord) {
+ fpr = (FilePassRecord) rec;
+ }
+
+ // workbook not encrypted (typical case)
+ if (rec instanceof EOFRecord) {
+ // A workbook stream is never empty, so crash instead
+ // of trying to keep track of nesting level
+ throw new IllegalStateException("Nothing between BOF and EOF");
+ }
+ }
+ } else {
+ // Invalid in a normal workbook stream.
+ // However, some test cases work on sub-sections of
+ // the workbook stream that do not begin with BOF
+ _hasBOFRecord = false;
+ }
+ _initialRecordsSize = recSize;
+ _filePassRec = fpr;
+ _lastRecord = rec;
+ }
- @SuppressWarnings({"squid:S2068"})
- public RecordInputStream createDecryptingStream(InputStream original) {
+ @SuppressWarnings({"squid:S2068"})
+ public RecordInputStream createDecryptingStream(InputStream original) {
String userPassword = Biff8EncryptionKey.getCurrentUserPassword();
- if (userPassword == null) {
- userPassword = Decryptor.DEFAULT_PASSWORD;
- }
+ if (userPassword == null) {
+ userPassword = Decryptor.DEFAULT_PASSWORD;
+ }
- EncryptionInfo info = _filePassRec.getEncryptionInfo();
+ EncryptionInfo info = _filePassRec.getEncryptionInfo();
try {
if (!info.getDecryptor().verifyPassword(userPassword)) {
throw new EncryptedDocumentException(
@@ -120,250 +120,250 @@ public final class RecordFactoryInputStr
throw new EncryptedDocumentException(e);
}
- return new RecordInputStream(original, info, _initialRecordsSize);
- }
+ return new RecordInputStream(original, info, _initialRecordsSize);
+ }
- public boolean hasEncryption() {
- return _filePassRec != null;
- }
-
- /**
- * @return last record scanned while looking for encryption info.
- * This will typically be the first or second record read. Possibly <code>null</code>
- * if stream was empty
- */
- public Record getLastRecord() {
- return _lastRecord;
- }
-
- /**
- * <code>false</code> in some test cases
- */
- public boolean hasBOFRecord() {
- return _hasBOFRecord;
- }
- }
-
-
- private final RecordInputStream _recStream;
- private final boolean _shouldIncludeContinueRecords;
-
- /**
- * Temporarily stores a group of {@link Record}s, for future return by {@link #nextRecord()}.
- * This is used at the start of the workbook stream, and also when the most recently read
- * underlying record is a {@link MulRKRecord}
- */
- private Record[] _unreadRecordBuffer;
-
- /**
- * used to help iterating over the unread records
- */
- private int _unreadRecordIndex = -1;
-
- /**
- * The most recent record that we gave to the user
- */
- private Record _lastRecord;
- /**
- * The most recent DrawingRecord seen
- */
- private DrawingRecord _lastDrawingRecord = new DrawingRecord();
-
- private int _bofDepth;
-
- private boolean _lastRecordWasEOFLevelZero;
-
-
- /**
- * @param in the InputStream to read from
- *
- * @param shouldIncludeContinueRecords caller can pass <code>false</code> if loose
- * {@link ContinueRecord}s should be skipped (this is sometimes useful in event based
- * processing).
- */
- public RecordFactoryInputStream(InputStream in, boolean shouldIncludeContinueRecords) {
- RecordInputStream rs = new RecordInputStream(in);
- List<org.apache.poi.hssf.record.Record> records = new ArrayList<>();
- StreamEncryptionInfo sei = new StreamEncryptionInfo(rs, records);
- if (sei.hasEncryption()) {
- rs = sei.createDecryptingStream(in);
- } else {
- // typical case - non-encrypted stream
- }
-
- if (!records.isEmpty()) {
- _unreadRecordBuffer = new Record[records.size()];
- records.toArray(_unreadRecordBuffer);
- _unreadRecordIndex =0;
- }
- _recStream = rs;
- _shouldIncludeContinueRecords = shouldIncludeContinueRecords;
- _lastRecord = sei.getLastRecord();
-
- /*
- * How to recognise end of stream?
- * In the best case, the underlying input stream (in) ends just after the last EOF record
- * Usually however, the stream is padded with an arbitrary byte count. Excel and most apps
- * reliably use zeros for padding and if this were always the case, this code could just
- * skip all the (zero sized) records with sid==0. However, bug 46987 shows a file with
- * non-zero padding that is read OK by Excel (Excel also fixes the padding).
- *
- * So to properly detect the workbook end of stream, this code has to identify the last
- * EOF record. This is not so easy because the worbook bof+eof pair do not bracket the
- * whole stream. The worksheets follow the workbook, but it is not easy to tell how many
- * sheet sub-streams should be present. Hence we are looking for an EOF record that is not
- * immediately followed by a BOF record. One extra complication is that bof+eof sub-
- * streams can be nested within worksheet streams and it's not clear in these cases what
- * record might follow any EOF record. So we also need to keep track of the bof/eof
- * nesting level.
- */
- _bofDepth = sei.hasBOFRecord() ? 1 : 0;
- _lastRecordWasEOFLevelZero = false;
- }
-
- /**
- * @return the next (complete) record from the stream, or null if there are no more.
- */
- public Record nextRecord() {
- Record r;
- r = getNextUnreadRecord();
- if (r != null) {
- // found an unread record
- return r;
- }
- while (true) {
- if (!_recStream.hasNextRecord()) {
- // recStream is exhausted;
- return null;
- }
-
- if (_lastRecordWasEOFLevelZero) {
- // Potential place for ending the workbook stream
- // Check that the next record is not BOFRecord(0x0809)
- // Normally the input stream contains only zero padding after the last EOFRecord,
- // but bug 46987 and 48068 suggests that the padding may be garbage.
- // This code relies on the padding bytes not starting with BOFRecord.sid
- if (_recStream.getNextSid() != BOFRecord.sid) {
- return null;
- }
- // else - another sheet substream starting here
- }
+ public boolean hasEncryption() {
+ return _filePassRec != null;
+ }
+
+ /**
+ * @return last record scanned while looking for encryption info.
+ * This will typically be the first or second record read. Possibly <code>null</code>
+ * if stream was empty
+ */
+ public Record getLastRecord() {
+ return _lastRecord;
+ }
+
+ /**
+ * <code>false</code> in some test cases
+ */
+ public boolean hasBOFRecord() {
+ return _hasBOFRecord;
+ }
+ }
+
+
+ private final RecordInputStream _recStream;
+ private final boolean _shouldIncludeContinueRecords;
+
+ /**
+ * Temporarily stores a group of {@link Record}s, for future return by {@link #nextRecord()}.
+ * This is used at the start of the workbook stream, and also when the most recently read
+ * underlying record is a {@link MulRKRecord}
+ */
+ private Record[] _unreadRecordBuffer;
+
+ /**
+ * used to help iterating over the unread records
+ */
+ private int _unreadRecordIndex = -1;
+
+ /**
+ * The most recent record that we gave to the user
+ */
+ private Record _lastRecord;
+ /**
+ * The most recent DrawingRecord seen
+ */
+ private DrawingRecord _lastDrawingRecord = new DrawingRecord();
+
+ private int _bofDepth;
+
+ private boolean _lastRecordWasEOFLevelZero;
+
+
+ /**
+ * @param in the InputStream to read from
+ *
+ * @param shouldIncludeContinueRecords caller can pass <code>false</code> if loose
+ * {@link ContinueRecord}s should be skipped (this is sometimes useful in event based
+ * processing).
+ */
+ public RecordFactoryInputStream(InputStream in, boolean shouldIncludeContinueRecords) {
+ RecordInputStream rs = new RecordInputStream(in);
+ List<org.apache.poi.hssf.record.Record> records = new ArrayList<>();
+ StreamEncryptionInfo sei = new StreamEncryptionInfo(rs, records);
+ if (sei.hasEncryption()) {
+ rs = sei.createDecryptingStream(in);
+ } else {
+ // typical case - non-encrypted stream
+ }
+
+ if (!records.isEmpty()) {
+ _unreadRecordBuffer = new Record[records.size()];
+ records.toArray(_unreadRecordBuffer);
+ _unreadRecordIndex =0;
+ }
+ _recStream = rs;
+ _shouldIncludeContinueRecords = shouldIncludeContinueRecords;
+ _lastRecord = sei.getLastRecord();
+
+ /*
+ * How to recognise end of stream?
+ * In the best case, the underlying input stream (in) ends just after the last EOF record
+ * Usually however, the stream is padded with an arbitrary byte count. Excel and most apps
+ * reliably use zeros for padding and if this were always the case, this code could just
+ * skip all the (zero sized) records with sid==0. However, bug 46987 shows a file with
+ * non-zero padding that is read OK by Excel (Excel also fixes the padding).
+ *
+ * So to properly detect the workbook end of stream, this code has to identify the last
+ * EOF record. This is not so easy because the worbook bof+eof pair do not bracket the
+ * whole stream. The worksheets follow the workbook, but it is not easy to tell how many
+ * sheet sub-streams should be present. Hence we are looking for an EOF record that is not
+ * immediately followed by a BOF record. One extra complication is that bof+eof sub-
+ * streams can be nested within worksheet streams and it's not clear in these cases what
+ * record might follow any EOF record. So we also need to keep track of the bof/eof
+ * nesting level.
+ */
+ _bofDepth = sei.hasBOFRecord() ? 1 : 0;
+ _lastRecordWasEOFLevelZero = false;
+ }
+
+ /**
+ * @return the next (complete) record from the stream, or null if there are no more.
+ */
+ public Record nextRecord() {
+ Record r;
+ r = getNextUnreadRecord();
+ if (r != null) {
+ // found an unread record
+ return r;
+ }
+ while (true) {
+ if (!_recStream.hasNextRecord()) {
+ // recStream is exhausted;
+ return null;
+ }
+
+ if (_lastRecordWasEOFLevelZero) {
+ // Potential place for ending the workbook stream
+ // Check that the next record is not BOFRecord(0x0809)
+ // Normally the input stream contains only zero padding after the last EOFRecord,
+ // but bug 46987 and 48068 suggests that the padding may be garbage.
+ // This code relies on the padding bytes not starting with BOFRecord.sid
+ if (_recStream.getNextSid() != BOFRecord.sid) {
+ return null;
+ }
+ // else - another sheet substream starting here
+ }
// step underlying RecordInputStream to the next record
_recStream.nextRecord();
- r = readNextRecord();
- if (r == null) {
- // some record types may get skipped (e.g. DBCellRecord and ContinueRecord)
- continue;
- }
- return r;
- }
- }
-
- /**
- * @return the next {@link Record} from the multiple record group as expanded from
- * a recently read {@link MulRKRecord}. <code>null</code> if not present.
- */
- private Record getNextUnreadRecord() {
- if (_unreadRecordBuffer != null) {
- int ix = _unreadRecordIndex;
- if (ix < _unreadRecordBuffer.length) {
- Record result = _unreadRecordBuffer[ix];
- _unreadRecordIndex = ix + 1;
- return result;
- }
- _unreadRecordIndex = -1;
- _unreadRecordBuffer = null;
- }
- return null;
- }
-
- /**
- * @return the next available record, or <code>null</code> if
- * this pass didn't return a record that's
- * suitable for returning (eg was a continue record).
- */
- private Record readNextRecord() {
-
- Record record = RecordFactory.createSingleRecord(_recStream);
- _lastRecordWasEOFLevelZero = false;
-
- if (record instanceof BOFRecord) {
- _bofDepth++;
- return record;
- }
-
- if (record instanceof EOFRecord) {
- _bofDepth--;
- if (_bofDepth < 1) {
- _lastRecordWasEOFLevelZero = true;
- }
-
- return record;
- }
-
- if (record instanceof DBCellRecord) {
- // Not needed by POI. Regenerated from scratch by POI when spreadsheet is written
- return null;
- }
-
- if (record instanceof RKRecord) {
- return RecordFactory.convertToNumberRecord((RKRecord) record);
- }
-
- if (record instanceof MulRKRecord) {
- Record[] records = RecordFactory.convertRKRecords((MulRKRecord) record);
-
- _unreadRecordBuffer = records;
- _unreadRecordIndex = 1;
- return records[0];
- }
-
- if (record.getSid() == DrawingGroupRecord.sid
- && _lastRecord instanceof DrawingGroupRecord) {
- DrawingGroupRecord lastDGRecord = (DrawingGroupRecord) _lastRecord;
- lastDGRecord.join((AbstractEscherHolderRecord) record);
- return null;
- }
- if (record.getSid() == ContinueRecord.sid) {
- ContinueRecord contRec = (ContinueRecord) record;
-
- if (_lastRecord instanceof ObjRecord || _lastRecord instanceof TextObjectRecord) {
- // Drawing records have a very strange continue behaviour.
- //There can actually be OBJ records mixed between the continues.
- _lastDrawingRecord.processContinueRecord(contRec.getData());
- //we must remember the position of the continue record.
- //in the serialization procedure the original structure of records must be preserved
- if (_shouldIncludeContinueRecords) {
- return record;
- }
- return null;
- }
- if (_lastRecord instanceof DrawingGroupRecord) {
- ((DrawingGroupRecord) _lastRecord).processContinueRecord(contRec.getData());
- return null;
- }
- if (_lastRecord instanceof DrawingRecord) {
-// ((DrawingRecord) _lastRecord).appendContinueRecord(contRec.getData());
- return contRec;
- }
- if (_lastRecord instanceof UnknownRecord) {
- //Gracefully handle records that we don't know about,
- //that happen to be continued
- return record;
- }
- if (_lastRecord instanceof EOFRecord) {
- // This is really odd, but excel still sometimes
- // outputs a file like this all the same
- return record;
- }
- throw new RecordFormatException("Unhandled Continue Record followining " + _lastRecord.getClass());
- }
- _lastRecord = record;
- if (record instanceof DrawingRecord) {
- _lastDrawingRecord = (DrawingRecord) record;
- }
- return record;
- }
+ r = readNextRecord();
+ if (r == null) {
+ // some record types may get skipped (e.g. DBCellRecord and ContinueRecord)
+ continue;
+ }
+ return r;
+ }
+ }
+
+ /**
+ * @return the next {@link Record} from the multiple record group as expanded from
+ * a recently read {@link MulRKRecord}. <code>null</code> if not present.
+ */
+ private Record getNextUnreadRecord() {
+ if (_unreadRecordBuffer != null) {
+ int ix = _unreadRecordIndex;
+ if (ix < _unreadRecordBuffer.length) {
+ Record result = _unreadRecordBuffer[ix];
+ _unreadRecordIndex = ix + 1;
+ return result;
+ }
+ _unreadRecordIndex = -1;
+ _unreadRecordBuffer = null;
+ }
+ return null;
+ }
+
+ /**
+ * @return the next available record, or <code>null</code> if
+ * this pass didn't return a record that's
+ * suitable for returning (eg was a continue record).
+ */
+ private Record readNextRecord() {
+
+ Record record = RecordFactory.createSingleRecord(_recStream);
+ _lastRecordWasEOFLevelZero = false;
+
+ if (record instanceof BOFRecord) {
+ _bofDepth++;
+ return record;
+ }
+
+ if (record instanceof EOFRecord) {
+ _bofDepth--;
+ if (_bofDepth < 1) {
+ _lastRecordWasEOFLevelZero = true;
+ }
+
+ return record;
+ }
+
+ if (record instanceof DBCellRecord) {
+ // Not needed by POI. Regenerated from scratch by POI when spreadsheet is written
+ return null;
+ }
+
+ if (record instanceof RKRecord) {
+ return RecordFactory.convertToNumberRecord((RKRecord) record);
+ }
+
+ if (record instanceof MulRKRecord) {
+ Record[] records = RecordFactory.convertRKRecords((MulRKRecord) record);
+
+ _unreadRecordBuffer = records;
+ _unreadRecordIndex = 1;
+ return records[0];
+ }
+
+ if (record.getSid() == DrawingGroupRecord.sid
+ && _lastRecord instanceof DrawingGroupRecord) {
+ DrawingGroupRecord lastDGRecord = (DrawingGroupRecord) _lastRecord;
+ lastDGRecord.join((AbstractEscherHolderRecord) record);
+ return null;
+ }
+ if (record.getSid() == ContinueRecord.sid) {
+ ContinueRecord contRec = (ContinueRecord) record;
+
+ if (_lastRecord instanceof ObjRecord || _lastRecord instanceof TextObjectRecord) {
+ // Drawing records have a very strange continue behaviour.
+ //There can actually be OBJ records mixed between the continues.
+ _lastDrawingRecord.processContinueRecord(contRec.getData());
+ //we must remember the position of the continue record.
+ //in the serialization procedure the original structure of records must be preserved
+ if (_shouldIncludeContinueRecords) {
+ return record;
+ }
+ return null;
+ }
+ if (_lastRecord instanceof DrawingGroupRecord) {
+ ((DrawingGroupRecord) _lastRecord).processContinueRecord(contRec.getData());
+ return null;
+ }
+ if (_lastRecord instanceof DrawingRecord) {
+// ((DrawingRecord) _lastRecord).appendContinueRecord(contRec.getData());
+ return contRec;
+ }
+ if (_lastRecord instanceof UnknownRecord) {
+ //Gracefully handle records that we don't know about,
+ //that happen to be continued
+ return record;
+ }
+ if (_lastRecord instanceof EOFRecord) {
+ // This is really odd, but excel still sometimes
+ // outputs a file like this all the same
+ return record;
+ }
+ throw new RecordFormatException("Unhandled Continue Record followining " + _lastRecord.getClass());
+ }
+ _lastRecord = record;
+ if (record instanceof DrawingRecord) {
+ _lastDrawingRecord = (DrawingRecord) record;
+ }
+ return record;
+ }
}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@poi.apache.org
For additional commands, e-mail: commits-help@poi.apache.org