From af6727408cbc5bbad23862ae0a29e47672f93a57 Mon Sep 17 00:00:00 2001 From: Scott Fennell Date: Tue, 10 Apr 2018 16:02:44 -0500 Subject: [PATCH] Limit log file size (#594) * #585 create new method to set max file size for DataRecordGroups. Needs testing and DRD interface function * #585 dre implementation and other improvements, needs more work * #585 update dre, add intf for drd max size functions. Still requires better comments, wiki updates, some refactoring, and testing * #585 refactor trick-dre * format trick-dre * improve readability of dre output for set_max_file_size --- include/trick/DRBinary.hh | 2 +- include/trick/DataRecordDispatcher.hh | 6 + include/trick/DataRecordGroup.hh | 17 + include/trick/data_record_proto.h | 3 + .../java/src/trick/dre/DreApplication.java | 1084 +++++++++-------- .../sim_services/DataRecord/DRAscii.cpp | 13 +- .../sim_services/DataRecord/DRBinary.cpp | 41 +- .../DataRecord/DataRecordDispatcher.cpp | 18 + .../DataRecord/DataRecordGroup.cpp | 20 +- .../DataRecord/data_record_utilities.cpp | 14 + 10 files changed, 707 insertions(+), 511 deletions(-) diff --git a/include/trick/DRBinary.hh b/include/trick/DRBinary.hh index c5ba3966..bcf5c4ef 100644 --- a/include/trick/DRBinary.hh +++ b/include/trick/DRBinary.hh @@ -117,7 +117,7 @@ namespace Trick { private: /** The log file.\n */ - int fp ; /**< trick_io(**) trick_units(--) */ + int fd ; /**< trick_io(**) trick_units(--) */ } ; diff --git a/include/trick/DataRecordDispatcher.hh b/include/trick/DataRecordDispatcher.hh index 32936e92..b1fb332c 100644 --- a/include/trick/DataRecordDispatcher.hh +++ b/include/trick/DataRecordDispatcher.hh @@ -100,6 +100,12 @@ namespace Trick { /** @brief Disable a group or all groups */ int record_now_group( const char * in_name ) ; + /** @brief set max file size for group */ + int set_group_max_file_size(const char * in_name, uint64_t bytes) ; + + /** @brief set max file size for all groups */ + int set_max_file_size(uint64_t bytes) ; + // override the default Schduler::add_sim_object virtual int add_sim_object( Trick::SimObject * in_object ) ; diff --git a/include/trick/DataRecordGroup.hh b/include/trick/DataRecordGroup.hh index 823fdb4d..43ff0fae 100644 --- a/include/trick/DataRecordGroup.hh +++ b/include/trick/DataRecordGroup.hh @@ -115,6 +115,12 @@ namespace Trick { /** Current write to file record number.\n */ unsigned int writer_num; /**< trick_io(**) trick_units(--) */ + /** Maximum file size for data record file in bytes.\n */ + uint64_t max_file_size; /**< trick_io(**) trick_units(--) */ + + /** Current file size for data record file in bytes.\n */ + uint64_t total_bytes_written; /**< trick_io(**) trick_units(--) */ + /** Buffer to hold formatted data ready for disk or other destination.\n */ char * writer_buff ; /**< trick_io(**) trick_units(--) */ @@ -207,6 +213,17 @@ namespace Trick { */ virtual int set_buffer_type(int buffer_type) ; + /** + @brief @userdesc Command to set the max file size in bytes. + This tells the data record group when it stops writing to the disk. + @par Python Usage: + @code .set_max_file_size() @endcode + @param type - the file size in bytes + @return always 0 + */ + virtual int set_max_file_size(uint64_t bytes) ; + + /** @brief @userdesc Command to print double variable values as single precision (float) in the log file to save space. @par Python Usage: diff --git a/include/trick/data_record_proto.h b/include/trick/data_record_proto.h index cd06c47b..bb1d557c 100644 --- a/include/trick/data_record_proto.h +++ b/include/trick/data_record_proto.h @@ -14,7 +14,10 @@ int dr_disable() ; int dr_enable_group( const char * in_name ) ; int dr_disable_group( const char * in_name ) ; int dr_record_now_group( const char * in_name ) ; +int dr_set_max_file_size ( uint64_t bytes ) ; void remove_all_data_record_groups() ; +int set_max_size_record_group (const char * in_name, uint64_t bytes ) ; + #ifdef __cplusplus int add_data_record_group( Trick::DataRecordGroup * in_group, Trick::DR_Buffering buffering = Trick::DR_Not_Specified ) ; diff --git a/trick_source/java/src/trick/dre/DreApplication.java b/trick_source/java/src/trick/dre/DreApplication.java index f3da41b3..b31151a5 100644 --- a/trick_source/java/src/trick/dre/DreApplication.java +++ b/trick_source/java/src/trick/dre/DreApplication.java @@ -7,41 +7,6 @@ package trick.dre; //======================================== // Imports //======================================== -import java.awt.BorderLayout; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; -import java.io.BufferedReader; -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileReader; -import java.io.FileWriter; -import java.io.IOException; -import java.util.Collection; -import java.util.Vector; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import javax.swing.Box; -import javax.swing.JCheckBoxMenuItem; -import javax.swing.JComponent; -import javax.swing.JLabel; -import javax.swing.JMenu; -import javax.swing.JMenuBar; -import javax.swing.JMenuItem; -import javax.swing.JOptionPane; -import javax.swing.JPanel; -import javax.swing.JPopupMenu; -import javax.swing.JRadioButtonMenuItem; -import javax.swing.JSeparator; -import javax.swing.JSplitPane; -import javax.swing.JTextField; -import javax.swing.JToolBar; -import javax.swing.tree.TreePath; -import javax.xml.parsers.ParserConfigurationException; import org.jdesktop.application.Action; import org.jdesktop.application.Application; @@ -49,381 +14,416 @@ import org.jdesktop.application.View; import org.jdesktop.swingx.JXLabel; import org.xml.sax.InputSource; import org.xml.sax.SAXException; - import trick.common.TrickApplication; import trick.common.ui.UIUtils; import trick.common.ui.components.NumberTextField; import trick.common.ui.panels.ListPanel; -import trick.sie.utils.SearchPanel; -import trick.sie.utils.SieResourceDomParser; -import trick.sie.utils.SieTemplate; -import trick.sie.utils.SieTreeModel; -import trick.sie.utils.SieVariableTree; +import trick.sie.utils.*; + +import javax.swing.*; +import javax.swing.tree.TreePath; +import javax.xml.parsers.ParserConfigurationException; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.io.*; +import java.util.Collection; +import java.util.StringTokenizer; +import java.util.Vector; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * Dre - data recording editor application. * - * @author Hong Chen + * @author Hong Chen + * @author Scott Fennell * @since Trick 10 + * @since Trick 17 */ public class DreApplication extends TrickApplication { - //======================================== - // Public data - //======================================== - - - //======================================== - // Protected data - //======================================== - protected static String sieResourcePath = null; - - //======================================== - // Private Data - //======================================== - private String single_prec_only; - private String frequency; - private String format; - private String buffering; - private Vector variables = new Vector(); - - /** The menu check box for Single Precision. */ - private JCheckBoxMenuItem singlePrecisionCheckBox; - - /** Popup window for clicking a tree node **/ + //======================================== + // Public data + //======================================== + + + //======================================== + // Protected data + //======================================== + protected static String sieResourcePath = null; + + //======================================== + // Private Data + //======================================== + private String single_prec_only; + private String frequency; + private String format; + private String buffering; + private Vector variables = new Vector(); + + /** + * The menu check box for Single Precision. + */ + private JCheckBoxMenuItem singlePrecisionCheckBox; + + /** + * Popup window for clicking a tree node + **/ private JPopupMenu treePopup = null; - + /** S_sie.resource xml parser */ //private SieResourceXMLParser sieXMLParser; - - /** The sim objects top level instances */ + + /** + * The sim objects top level instances + */ private Collection rootTemplates; - - /** The variable (sim objects) tree */ + + /** + * The variable (sim objects) tree + */ private SieVariableTree varTree; - - /** The search panel for the variable tree */ + + /** + * The search panel for the variable tree + */ private SearchPanel searchPanel; - - /** The selected variable list */ - private ListPanel selectedVarList; - - /** The text field that contains the group name */ + + /** + * The selected variable list + */ + private ListPanel selectedVarList; + + /** + * The text field that contains the group name + */ private JTextField nameField; - - /** The text field that contains the cycle frequency for recording */ + + /** + * The text field that contains the cycle frequency for recording + */ private NumberTextField cycleField; - + + /** + * The text field that contains the max file size for the group + */ + private NumberTextField maxFileSizeField; + + private JComboBox sizeUnitsBox; + + private JCheckBox unlimitedSizeBox; + private JRadioButtonMenuItem DRAscii_item; private JRadioButtonMenuItem DRBinary_item; private JRadioButtonMenuItem DRHDF5_item; - + private JRadioButtonMenuItem DRBuffer_item; private JRadioButtonMenuItem DRNoBuffer_item; private JRadioButtonMenuItem DRRingBuffer_item; //private JRadioButtonMenuItem DRThreadBuffer_item; - + private JRadioButtonMenuItem DRAlways_item; private JRadioButtonMenuItem DRChanges_item; private JRadioButtonMenuItem DRStepChanges_item; - + private boolean isSinglePrecision; - + /** * Vectors to contain the information on the variable * being added to the recording list. */ Vector nameSegment = new Vector(); Vector fullName = new Vector(); - - //======================================== - // Constructors - //======================================== - + + //======================================== + // Constructors + //======================================== + //======================================== // Actions //======================================== @Action public void openDR() { - File file = UIUtils.chooseOpenFile(null, null, "dr", getMainFrame()); - if (file != null) { - openFile(file); - } + File file = UIUtils.chooseOpenFile(null, null, "dr", getMainFrame()); + if (file != null) { + openFile(file); + } } - + @Action public void saveDR() { if (nameField.getText().trim().compareTo("") == 0) { - JOptionPane.showMessageDialog(getMainFrame(), "A group name must be entered!", - "Error", JOptionPane.ERROR_MESSAGE); - return; + JOptionPane.showMessageDialog(getMainFrame(), "A group name must be entered!", + "Error", JOptionPane.ERROR_MESSAGE); + return; } else if (nameField.getText().trim().contains(" ")) { - JOptionPane.showMessageDialog(getMainFrame(), "A group name can not have whitespace!", - "Error", JOptionPane.ERROR_MESSAGE); - return; + JOptionPane.showMessageDialog(getMainFrame(), "A group name can not have whitespace!", + "Error", JOptionPane.ERROR_MESSAGE); + return; } File file = UIUtils.chooseSaveFile(null, null, "dr", getMainFrame()); if (file != null) { - saveFile(file); + saveFile(file); } } - + @Action public void selectDRBinary() { - format = "DRBinary"; - DRAscii_item.setSelected(false); - DRBinary_item.setSelected(true); - DRHDF5_item.setSelected(false); + format = "DRBinary"; + DRAscii_item.setSelected(false); + DRBinary_item.setSelected(true); + DRHDF5_item.setSelected(false); } - + @Action public void selectDRAscii() { - format = "DRAscii"; - DRAscii_item.setSelected(true); - DRBinary_item.setSelected(false); - DRHDF5_item.setSelected(false); + format = "DRAscii"; + DRAscii_item.setSelected(true); + DRBinary_item.setSelected(false); + DRHDF5_item.setSelected(false); } - + @Action public void selectDRHDF5() { - format = "DRHDF5"; - DRAscii_item.setSelected(false); - DRBinary_item.setSelected(false); - DRHDF5_item.setSelected(true); - } - + format = "DRHDF5"; + DRAscii_item.setSelected(false); + DRBinary_item.setSelected(false); + DRHDF5_item.setSelected(true); + } + @Action public void selectDRAlways() { - frequency = "DR_Always"; - DRAlways_item.setSelected(true); - DRChanges_item.setSelected(false); - DRStepChanges_item.setSelected(false); + frequency = "DR_Always"; + DRAlways_item.setSelected(true); + DRChanges_item.setSelected(false); + DRStepChanges_item.setSelected(false); } - + @Action public void selectDRChanges() { - frequency = "DR_Changes"; - DRAlways_item.setSelected(false); - DRChanges_item.setSelected(true); - DRStepChanges_item.setSelected(false); + frequency = "DR_Changes"; + DRAlways_item.setSelected(false); + DRChanges_item.setSelected(true); + DRStepChanges_item.setSelected(false); } - + @Action public void selectDRStepChanges() { - frequency = "DR_Step_Changes"; - DRAlways_item.setSelected(false); - DRChanges_item.setSelected(false); - DRStepChanges_item.setSelected(true); - } - + frequency = "DR_Step_Changes"; + DRAlways_item.setSelected(false); + DRChanges_item.setSelected(false); + DRStepChanges_item.setSelected(true); + } + @Action public void toggleSinglePrecision() { - isSinglePrecision = singlePrecisionCheckBox.getState(); - if (isSinglePrecision) { - single_prec_only = "True"; - } else { - single_prec_only = "False"; - } + isSinglePrecision = singlePrecisionCheckBox.getState(); + if (isSinglePrecision) { + single_prec_only = "True"; + } else { + single_prec_only = "False"; + } } - + @Action public void selectDRBuffer() { - buffering = "DR_Buffer"; - DRBuffer_item.setSelected(true); - DRNoBuffer_item.setSelected(false); - DRRingBuffer_item.setSelected(false); - //DRThreadBuffer_item.setSelected(false); + buffering = "DR_Buffer"; + DRBuffer_item.setSelected(true); + DRNoBuffer_item.setSelected(false); + DRRingBuffer_item.setSelected(false); + //DRThreadBuffer_item.setSelected(false); } - + @Action public void selectDRNoBuffer() { - buffering = "DR_No_Buffer"; - DRBuffer_item.setSelected(false); - DRNoBuffer_item.setSelected(true); - DRRingBuffer_item.setSelected(false); - //DRThreadBuffer_item.setSelected(false); + buffering = "DR_No_Buffer"; + DRBuffer_item.setSelected(false); + DRNoBuffer_item.setSelected(true); + DRRingBuffer_item.setSelected(false); + //DRThreadBuffer_item.setSelected(false); } - + @Action public void selectDRRingBuffer() { - buffering = "DR_Ring_Buffer"; - DRBuffer_item.setSelected(false); - DRNoBuffer_item.setSelected(false); - DRRingBuffer_item.setSelected(true); - //DRThreadBuffer_item.setSelected(false); + buffering = "DR_Ring_Buffer"; + DRBuffer_item.setSelected(false); + DRNoBuffer_item.setSelected(false); + DRRingBuffer_item.setSelected(true); + //DRThreadBuffer_item.setSelected(false); } - + @Action public void selectDRThreadBuffer() { - buffering = "DR_Thread_Buffer"; - DRBuffer_item.setSelected(false); - DRNoBuffer_item.setSelected(false); - DRRingBuffer_item.setSelected(false); - //DRThreadBuffer_item.setSelected(true); + buffering = "DR_Thread_Buffer"; + DRBuffer_item.setSelected(false); + DRNoBuffer_item.setSelected(false); + DRRingBuffer_item.setSelected(false); + //DRThreadBuffer_item.setSelected(true); } - + @Action public void removeSelected() { - Object[] values = selectedVarList.getSelectedData(); - for (int i = 0; i < values.length; i++) { - variables.remove(values[i]); - } - selectedVarList.removeSelectedData(); + Object[] values = selectedVarList.getSelectedData(); + for (int i = 0; i < values.length; i++) { + variables.remove(values[i]); + } + selectedVarList.removeSelectedData(); } - + @Action public void removeAll() { - selectedVarList.removeAllData(); - variables.clear(); + selectedVarList.removeAllData(); + variables.clear(); } - + @Action public void addVariables() { for (SieTemplate thisValue : searchPanel.getSelectedValues()) { addVariable(thisValue.toString()); } } - - //======================================== - // Set/Get methods - //======================================== - - - - //======================================== - // Methods - //======================================== - /** + + + //======================================== + // Set/Get methods + //======================================== + + + //======================================== + // Methods + //======================================== + + /** * Main method for this application. + * * @param args command line arguments */ public static void main(String[] args) { Application.launch(DreApplication.class, args); } - + /** * Makes initialization as needed. This is called before startup(). - * + * * @see #startup - */ + */ @Override protected void initialize(String[] args) { super.initialize(args); File resourceFile = null; if (sieResourcePath == null) { - resourceFile = new File(resourceMap.getString("sie.resource.file")); + resourceFile = new File(resourceMap.getString("sie.resource.file")); } else { - resourceFile = new File(sieResourcePath); + resourceFile = new File(sieResourcePath); } //sieXMLParser = null; - if (resourceFile != null && !resourceFile.exists()) { + if (!resourceFile.exists()) { System.out.println(resourceFile.getName() + " file does not exist. Exit!!!"); System.exit(0); } - + try { - rootTemplates = SieResourceDomParser.parse(new InputSource(new FileInputStream(resourceFile))); - } catch (FileNotFoundException e) { - e.printStackTrace(); - } catch (ParserConfigurationException e) { - e.printStackTrace(); - } catch (SAXException e) { - e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); - } - - /*try { - sieXMLParser = new SieResourceXMLParser(resourceFile.getCanonicalPath()); + rootTemplates = SieResourceDomParser.parse(new InputSource(new FileInputStream(resourceFile))); + } catch (ParserConfigurationException | SAXException | IOException e) { + e.printStackTrace(); + } + + /*try { + sieXMLParser = new SieResourceXMLParser(resourceFile.getCanonicalPath()); sieXMLParser.runParser(); } catch (Exception e) { System.out.println("Failed to parse " + resourceFile.getName() + "!"); System.exit(0); }*/ - + treePopup = new JPopupMenu(); - + varTree = new SieVariableTree(); varTree.setRootInstances(rootTemplates); - - varTree.setShowsRootHandles(true); + + varTree.setShowsRootHandles(true); } - + /** - * Starts building GUI. This is called after initialize. + * Starts building GUI. This is called after initialize. * Once startup() is done, ready() is called. - * + * * @see #initialize * @see #ready */ @Override protected void startup() { super.startup(); - + View view = getMainView(); view.setComponent(createMainPanel()); view.setMenuBar(createMenuBar()); view.setToolBar(createToolBar()); - + getMainFrame().setMinimumSize(getMainFrame().getPreferredSize()); show(view); + + } /** * Creates the main panel. This is required by TrickApplication. - * + * * @return a {@link JComponent} as the main panel. */ @Override - protected JComponent createMainPanel() { - JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT); - JSplitPane treeSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT); - - searchPanel = new SearchPanel(); - + protected JComponent createMainPanel() { + JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT); + JSplitPane treeSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT); + + searchPanel = new SearchPanel(); + searchPanel.setAction(actionMap.get("addVariables")); - + searchPanel.setRootTemplates(rootTemplates); - + treeSplitPane.add(UIUtils.createSearchableTitledPanel("Variables", varTree, null)); treeSplitPane.add(searchPanel); - + splitPane.add(treeSplitPane); - splitPane.add(UIUtils.createSearchableTitledPanel("Selected Variables", createSelectedVariablesPanel(), null)); - - // create a mouse listener and add to tree + splitPane.add(UIUtils.createSearchableTitledPanel("Selected Variables", createSelectedVariablesPanel(), null)); + + // create a mouse listener and add to tree TreeMouseListener mouser = new TreeMouseListener(); - varTree.addMouseListener(mouser); - + varTree.addMouseListener(mouser); + return splitPane; } - + /** * Helper method for creating the variables tab. */ private JComponent createSelectedVariablesPanel() { - JPanel panel = new JPanel(); - panel.setLayout(new BorderLayout()); - panel.add(new JSeparator(), BorderLayout.NORTH); - selectedVarList = new ListPanel(); - String[] popupMenuActions = { "removeSelected", "removeAll"}; + JPanel panel = new JPanel(); + panel.setLayout(new BorderLayout()); + panel.add(new JSeparator(), BorderLayout.NORTH); + selectedVarList = new ListPanel(); + String[] popupMenuActions = {"removeSelected", "removeAll"}; selectedVarList.setPopup(createPopupMenu(popupMenuActions), 0); - panel.add(selectedVarList, BorderLayout.CENTER); - return panel; + panel.add(selectedVarList, BorderLayout.CENTER); + return panel; } - + /** - * Create the JMenuBar for this application. + * Create the JMenuBar for this application. */ @Override - protected JMenuBar createMenuBar() { - JMenuBar menuBar = super.createMenuBar(); - JMenu menu = menuBar.getMenu(0); + protected JMenuBar createMenuBar() { + JMenuBar menuBar = super.createMenuBar(); + JMenu menu = menuBar.getMenu(0); menu.add(new JSeparator(), 0); menu.add(new JMenuItem(getAction("saveDR")), 0); menu.add(new JMenuItem(getAction("openDR")), 0); - + menuBar.add(createOptionsMenu(), 1); - + return menuBar; } @@ -431,267 +431,385 @@ public class DreApplication extends TrickApplication { * Helper method for creating Options menu. */ private JMenu createOptionsMenu() { - JMenu optionsMenu = new JMenu(); - optionsMenu.setName("optionsMenu"); - - optionsMenu.add(new JLabel("Format ")); - - DRBinary_item = new JRadioButtonMenuItem(); + JMenu optionsMenu = new JMenu(); + optionsMenu.setName("optionsMenu"); + + optionsMenu.add(new JLabel("Format ")); + + DRBinary_item = new JRadioButtonMenuItem(); optionsMenu.add(DRBinary_item); DRBinary_item.setAction(getAction("selectDRBinary")); - - DRAscii_item = new JRadioButtonMenuItem(); + + DRAscii_item = new JRadioButtonMenuItem(); optionsMenu.add(DRAscii_item); DRAscii_item.setAction(getAction("selectDRAscii")); - - DRHDF5_item = new JRadioButtonMenuItem(); + + DRHDF5_item = new JRadioButtonMenuItem(); optionsMenu.add(DRHDF5_item); DRHDF5_item.setAction(getAction("selectDRHDF5")); - + selectDRBinary(); // by default, DR_Binary optionsMenu.addSeparator(); - + optionsMenu.add(new JLabel("Freq")); - - DRAlways_item = new JRadioButtonMenuItem(); + + DRAlways_item = new JRadioButtonMenuItem(); optionsMenu.add(DRAlways_item); DRAlways_item.setAction(getAction("selectDRAlways")); - - DRChanges_item = new JRadioButtonMenuItem(); + + DRChanges_item = new JRadioButtonMenuItem(); optionsMenu.add(DRChanges_item); DRChanges_item.setAction(getAction("selectDRChanges")); - - DRStepChanges_item = new JRadioButtonMenuItem(); + + DRStepChanges_item = new JRadioButtonMenuItem(); optionsMenu.add(DRStepChanges_item); DRStepChanges_item.setAction(getAction("selectDRStepChanges")); - + selectDRAlways(); // by default, DR_Always - + optionsMenu.addSeparator(); - + singlePrecisionCheckBox = new JCheckBoxMenuItem(getAction("toggleSinglePrecision")); toggleSinglePrecision(); - + optionsMenu.add(singlePrecisionCheckBox); optionsMenu.addSeparator(); - + optionsMenu.add(new JXLabel("Buffering")); - DRBuffer_item = new JRadioButtonMenuItem(); + DRBuffer_item = new JRadioButtonMenuItem(); optionsMenu.add(DRBuffer_item); DRBuffer_item.setAction(getAction("selectDRBuffer")); - - DRNoBuffer_item = new JRadioButtonMenuItem(); + + DRNoBuffer_item = new JRadioButtonMenuItem(); optionsMenu.add(DRNoBuffer_item); DRNoBuffer_item.setAction(getAction("selectDRNoBuffer")); - - DRRingBuffer_item = new JRadioButtonMenuItem(); + + DRRingBuffer_item = new JRadioButtonMenuItem(); optionsMenu.add(DRRingBuffer_item); - DRRingBuffer_item.setAction(getAction("selectDRRingBuffer")); - - //DRThreadBuffer_item = new JRadioButtonMenuItem("selectDRThreadBuffer"); + DRRingBuffer_item.setAction(getAction("selectDRRingBuffer")); + + //DRThreadBuffer_item = new JRadioButtonMenuItem("selectDRThreadBuffer"); //optionsMenu.add(DRThreadBuffer_item); //DRThreadBuffer_item.setAction(getAction("selectDRThreadBuffer")); - + selectDRBuffer(); // by default, DR_Buffer - - return optionsMenu; + + return optionsMenu; } - + /** * Creates the tool bar for the application. - * + * * @return a {@link JToolBar} for the application. */ @Override protected JToolBar createToolBar() { + + JToolBar toolBar = new JToolBar(); + + // add buttons String[] toolbarActionNames = {"openDR", "saveDR"}; - JToolBar toolBar = new JToolBar(); for (String actionName : toolbarActionNames) { if (actionName.equals("---")) { toolBar.addSeparator(); } else { toolBar.add(createButton(actionName, false)); } - } - toolBar.addSeparator(); - toolBar.add(new JLabel("DR Name (NO SPACE): ")); + } + + nameFieldInit(); + cycleFieldInit(); + maxFileSizeFieldInit(); + sizeUnitsBoxInit(); + unlimitedSizeBoxInit(); + + toolBar.addSeparator(); + toolBar.add(new JLabel("DR Name (NO SPACE): ")); + toolBar.add(nameField); + toolBar.add(Box.createHorizontalStrut(10)); + toolBar.add(new JLabel("DR Cycle: ")); + toolBar.add(cycleField); + toolBar.addSeparator(); + toolBar.add(new JLabel(" Max File Size: ")); + toolBar.add(maxFileSizeField); + toolBar.add(sizeUnitsBox); + toolBar.addSeparator(); + toolBar.add(unlimitedSizeBox); + toolBar.setSize(toolBar.getPreferredSize()); + toolBar.addSeparator(); + + return toolBar; + } + + private void nameFieldInit() { nameField = new JTextField(15); nameField.setMinimumSize(nameField.getPreferredSize()); nameField.setPreferredSize(nameField.getPreferredSize()); - nameField.setMaximumSize(nameField.getPreferredSize()); - toolBar.add(nameField); - - toolBar.add(Box.createHorizontalStrut(10)); - - toolBar.add(new JLabel("DR Cycle: ")); - cycleField= new NumberTextField("0.1", 5); - cycleField.setMinimumSize(cycleField.getPreferredSize()); - toolBar.add(cycleField); - - return toolBar; + nameField.setMaximumSize(nameField.getPreferredSize()); } - + + private void cycleFieldInit() { + cycleField = new NumberTextField("0.1", 5); + cycleField.setMinimumSize(cycleField.getPreferredSize()); + } + + private void maxFileSizeFieldInit() { + maxFileSizeField = new NumberTextField("1", 10); + maxFileSizeField.setMinimumSize((maxFileSizeField.getPreferredSize())); + } + + private void sizeUnitsBoxInit() { + String[] units = {"B", "KiB", "MiB", "GiB"}; + sizeUnitsBox = new JComboBox<>(units); + sizeUnitsBox.setSelectedItem(sizeUnitsBox.getItemAt(3)); + } + + private void unlimitedSizeBoxInit() { + unlimitedSizeBox = new JCheckBox("Unlimited File Size", false); + unlimitedSizeBox.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + updateUnlimited(); + } + }); + } + /** * routine to read the Frequency from the opened file. - * + * * @param string String the string read in from the opened file. */ private void readFrequency(String string) { - if (string.indexOf("trick.DR_Always") != -1) { - selectDRAlways(); - } else if (string.indexOf("trick.DR_Changes") != -1) { - selectDRChanges(); - } else if (string.indexOf("trick.DR_Step_Changes") != -1) { - selectDRStepChanges(); - } else { - System.out.println("Frequency Type is not recognized, defaulting to DR_Always"); - selectDRAlways(); - } + if (string.contains("trick.DR_Always")) { + selectDRAlways(); + } else if (string.contains("trick.DR_Changes")) { + selectDRChanges(); + } else if (string.contains("trick.DR_Step_Changes")) { + selectDRStepChanges(); + } else { + System.out.println("Frequency Type is not recognized, defaulting to DR_Always"); + selectDRAlways(); + } } - + /** * routine to read the Buffering from the opened file. - * + * * @param string String the string read in from the opened file. */ private void readBuffering(String string) { - if (string.indexOf("trick.DR_Buffer") != -1) { - selectDRBuffer(); - } else if (string.indexOf("trick.DR_No_Buffer") != -1) { - selectDRNoBuffer(); - } else if (string.indexOf("trick.DR_Ring_Buffer") != -1) { - selectDRRingBuffer(); - } else if (string.indexOf("trick.DR_Thread_Buffer") != -1) { - selectDRThreadBuffer(); - } else { - System.out.println("Buffering Type is not recognized, defaulting to DR_Buffer"); - selectDRBuffer(); - } + if (string.contains("trick.DR_Buffer")) { + selectDRBuffer(); + } else if (string.contains("trick.DR_No_Buffer")) { + selectDRNoBuffer(); + } else if (string.contains("trick.DR_Ring_Buffer")) { + selectDRRingBuffer(); + } else if (string.contains("trick.DR_Thread_Buffer")) { + selectDRThreadBuffer(); + } else { + System.out.println("Buffering Type is not recognized, defaulting to DR_Buffer"); + selectDRBuffer(); + } } - + /** * routine to read the Format from the opened file. - * + * * @param string String the string read in from the opened file. */ private void readFormat(String string) { - if (string.indexOf("DRBinary") != -1) { - selectDRBinary(); - } else if (string.indexOf("DRAscii") != -1) { - selectDRAscii(); - } else if (string.indexOf("DRHDF5") != -1) { - selectDRHDF5(); - } else { - System.out.println("Format Type is not recognized, defaulting to DR_Binary"); - selectDRBinary(); - } + if (string.contains("DRBinary")) { + selectDRBinary(); + } else if (string.contains("DRAscii")) { + selectDRAscii(); + } else if (string.contains("DRHDF5")) { + selectDRHDF5(); + } else { + System.out.println("Format Type is not recognized, defaulting to DR_Binary"); + selectDRBinary(); + } } - + + /** + * routine to read the Max File Size from the opened file. + * + * @param subs String the string read in from the opened file. + */ + private void readFileSize(String subs) { + StringTokenizer st = new StringTokenizer(subs); + String quantity = st.nextToken("*").trim(); + maxFileSizeField.setText(quantity); + if (maxFileSizeField.getText().equals("0")) { + unlimitedSizeBox.setSelected(true); + updateUnlimited(); + } else { + unlimitedSizeBox.setSelected(false); + maxFileSizeField.setEnabled(true); + sizeUnitsBox.setEnabled(true); + } + if (st.hasMoreElements()) { + String shift = st.nextToken("*").trim(); + switch (shift) { + case "1024": + sizeUnitsBox.setSelectedItem("KiB"); + break; + case "1048576": + sizeUnitsBox.setSelectedItem("MiB"); + break; + case "1073741824": + sizeUnitsBox.setSelectedItem("GiB"); + break; + } + } else { + sizeUnitsBox.setSelectedItem("B"); + } + } + + /** + * helper method to update GUI after unlimited file size is checked. + */ + private static String previousFileSize; + private static int previousUnitIndex; + + private void updateUnlimited() { + if (unlimitedSizeBox.isSelected()) { + previousFileSize = maxFileSizeField.getText(); + previousUnitIndex = sizeUnitsBox.getSelectedIndex(); + maxFileSizeField.setText("0"); + maxFileSizeField.setEnabled(false); + sizeUnitsBox.setSelectedIndex(0); + sizeUnitsBox.setEnabled(false); + } else { + maxFileSizeField.setEnabled(true); + sizeUnitsBox.setEnabled(true); + maxFileSizeField.setText(previousFileSize); + sizeUnitsBox.setSelectedIndex(previousUnitIndex); + } + } + /** * routine to read the contents of the opened file - * + * * @param file File the name of the file to open. */ private void openFile(File file) { - try { - variables.clear(); - selectedVarList.removeAllData(); - BufferedReader reader = new BufferedReader(new FileReader(file)); - try { - for (String line = reader.readLine(); line != null; line = reader.readLine()) { - if (line.indexOf("append") != -1) { - String[] segment = line.split("\""); - readFormat(line); - nameField.setText(segment[1]); - } else if (line.indexOf("add_data_record_group") != -1) { - readBuffering(line); - } else if (line.indexOf("drg[DR_GROUP_ID]") != -1) { - int indx = line.indexOf("("); - int len = line.length(); - if (line.indexOf("set_freq") != -1) { - readFrequency(line); - } else if (line.indexOf("enable") != -1) { - ; - } else if (line.indexOf("set_cycle") != -1) { - cycleField.setText(line.substring(indx+1,len-1)); - } else if (line.indexOf("add_variable") != -1) { - selectedVarList.addData(line.substring(indx+2,len-2)); - variables.add(line.substring(indx+2,len-2)); - } else if (line.indexOf("set_single_prec_only") != -1) { - if (line.substring(indx+1,len-1).equals("True")) { - singlePrecisionCheckBox.setState(true); - } else { - singlePrecisionCheckBox.setState(false); - } - - } - } - } - } - finally { - if (reader != null) { - reader.close(); - } - } - } - catch (Exception e) { - JOptionPane.showMessageDialog(getMainFrame(), e.toString(), "Error Reading File", JOptionPane.ERROR_MESSAGE); - } + try { + variables.clear(); + selectedVarList.removeAllData(); + BufferedReader reader = new BufferedReader(new FileReader(file)); + try { + for (String line = reader.readLine(); line != null; line = reader.readLine()) { + if (line.contains("append")) { + String[] segment = line.split("\""); + readFormat(line); + nameField.setText(segment[1]); + } else if (line.contains("add_data_record_group")) { + readBuffering(line); + } else if (line.contains("drg[DR_GROUP_ID]")) { + int indx = line.indexOf("("); + int len = line.length(); + if (line.contains("set_freq")) { + readFrequency(line); + } else if (line.contains("enable")) { + ; + } else if (line.contains("set_cycle")) { + cycleField.setText(line.substring(indx + 1, len - 1)); + } else if (line.contains("add_variable")) { + selectedVarList.addData(line.substring(indx + 2, len - 2)); + variables.add(line.substring(indx + 2, len - 2)); + } else if (line.contains("set_single_prec_only")) { + if (line.substring(indx + 1, len - 1).equals("True")) { + singlePrecisionCheckBox.setState(true); + } else { + singlePrecisionCheckBox.setState(false); + } + + } else if (line.contains("set_max_file_size")) { + readFileSize(line.substring(line.indexOf("(") + 1, line.indexOf(")"))); + } + } + } + } finally { + reader.close(); + } + } catch (Exception e) { + JOptionPane.showMessageDialog(getMainFrame(), e.toString(), "Error Reading File", JOptionPane.ERROR_MESSAGE); + } } - + /** * routine to write the saved options for data recording to a file. - * + * * @param file File the name of the file to save */ private void saveFile(File file) { - try { - BufferedWriter writer = new BufferedWriter(new FileWriter(file)); - try { - writer.write("global DR_GROUP_ID\n"); - writer.write("global drg\n"); - writer.write("try:\n"); - writer.write(" if DR_GROUP_ID >= 0:\n"); - writer.write(" DR_GROUP_ID += 1\n"); - writer.write("except NameError:\n"); - writer.write(" DR_GROUP_ID = 0\n" + - " drg = []\n\n"); - writer.write("drg.append(trick." + format + "(\"" + nameField.getText().trim() + "\"))\n"); - writer.write("drg[DR_GROUP_ID].set_freq(trick." + frequency + ")\n"); - writer.write("drg[DR_GROUP_ID].set_cycle(" + cycleField.getText() + ")\n"); - writer.write("drg[DR_GROUP_ID].set_single_prec_only(" + single_prec_only + ")\n"); + try { + BufferedWriter writer = new BufferedWriter(new FileWriter(file)); + try { + writer.write("global DR_GROUP_ID\n"); + writer.write("global drg\n"); + writer.write("try:\n"); + writer.write(" if DR_GROUP_ID >= 0:\n"); + writer.write(" DR_GROUP_ID += 1\n"); + writer.write("except NameError:\n"); + writer.write(" DR_GROUP_ID = 0\n" + + " drg = []\n\n"); + writer.write("drg.append(trick." + format + "(\"" + nameField.getText().trim() + "\"))\n"); + writer.write("drg[DR_GROUP_ID].set_freq(trick." + frequency + ")\n"); + writer.write("drg[DR_GROUP_ID].set_cycle(" + cycleField.getText() + ")\n"); + writer.write("drg[DR_GROUP_ID].set_single_prec_only(" + single_prec_only + ")\n"); + + for (String variable : variables) { + writer.write("drg[DR_GROUP_ID].add_variable(\"" + variable + "\")\n"); + } + writer.write("drg[DR_GROUP_ID].set_max_file_size(" + maxFileSizeField.getText().trim() + getMultiplier((String) sizeUnitsBox.getSelectedItem())); + writer.write("trick.add_data_record_group(drg[DR_GROUP_ID], trick." + buffering + ")\n"); + writer.write("drg[DR_GROUP_ID].enable()\n"); + } finally { + writer.close(); + } + } catch (Exception e) { + JOptionPane.showMessageDialog(getMainFrame(), e.toString(), + "Error Saving File", JOptionPane.ERROR_MESSAGE); + } + } + + + /** + * helper method to convert ComboBox index to a multiplier for filesize units + */ + private String getMultiplier(String unit) { + String multiplier = null; + switch (unit) { + case "B": + multiplier = ")\n"; + break; + case "KiB": + multiplier = " * 1024) # multiply converts KiB to B --Dr. Dre\n"; + break; + case "MiB": + multiplier = " * 1048576) # multiply converts MiB to B --Dr. Dre\n"; + break; + case "GiB": + multiplier = " * 1073741824) # multiply converts GiB to B --Dr. Dre\n"; + break; + } + return multiplier; + } - for (int i = 0; i < variables.size(); i++) { - writer.write("drg[DR_GROUP_ID].add_variable(\"" + variables.get(i) + "\")\n"); - } - writer.write("trick.add_data_record_group(drg[DR_GROUP_ID], trick." + buffering + ")\n"); - writer.write("drg[DR_GROUP_ID].enable()\n"); - } - finally { - if (writer != null) { - writer.close(); - } - } - } - catch (Exception e) { - JOptionPane.showMessageDialog(getMainFrame(), e.toString(), - "Error Saving File", JOptionPane.ERROR_MESSAGE); - } - } - /** * routine to add the subscripts to the variable name being created - * + * * @param index int the size of the segments array. */ private void addSubscript(int index) { if (nameSegment.get(index).dimensions.size() != 0) { - for (int j=0; j dimensions = new Vector(); } - + /** * Using an inner class to define MouseListener to help organize code better. * The goal of this class is to handle mouse calls and forward them * to the interested parties. */ private class TreeMouseListener extends MouseAdapter { - - + + //======================================== // MouseListener methods //======================================== + /** * Invoked when the mouse button has been clicked (pressed * and released) on a component. @@ -779,60 +900,59 @@ public class DreApplication extends TrickApplication { * @param e MouseEvent sent from system. */ @Override - public void mouseClicked(MouseEvent e) - { - SieTemplate clickedNode = null; - if (UIUtils.isDoubleClick(e) || UIUtils.isRightMouseClick(e)) { - TreePath clickedPath = varTree.getClosestPathForLocation(e.getX(), e.getY()); - - clickedNode = (SieTemplate)clickedPath.getLastPathComponent(); - + public void mouseClicked(MouseEvent e) { + SieTemplate clickedNode = null; + if (UIUtils.isDoubleClick(e) || UIUtils.isRightMouseClick(e)) { + TreePath clickedPath = varTree.getClosestPathForLocation(e.getX(), e.getY()); + + clickedNode = (SieTemplate) clickedPath.getLastPathComponent(); + if (UIUtils.isRightMouseClick(e)) { - if (clickedNode != null && clickedNode.isTrickManaged()) { + if (clickedNode != null && clickedNode.isTrickManaged()) { if (treePopup.getComponentCount() > 0) { treePopup.removeAll(); } - + JMenuItem firstItem = new JMenuItem(SieTreeModel.getPathName(clickedPath) + clickedNode); - if (clickedNode != null && varTree.getModel().isLeaf(clickedNode) && clickedNode.isTrickManaged()) { - firstItem.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - addVariable(e.getActionCommand()); - } - }); - treePopup.add(firstItem); - } else { - treePopup.add(new JLabel(" " + SieTreeModel.getPathName(clickedPath) + clickedNode)); - } - - treePopup.addSeparator(); - - if (clickedNode.enumeration != null) { - JMenu subMenu = new JMenu("Type: " + clickedNode.typeName); - for (final Object eachLabel : clickedNode.enumeration.pairs.keySet()) { - subMenu.add((String)eachLabel); - } - treePopup.add(subMenu); - } else { - treePopup.add("Type: " + clickedNode.typeName); + if (varTree.getModel().isLeaf(clickedNode) && clickedNode.isTrickManaged()) { + firstItem.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + addVariable(e.getActionCommand()); + } + }); + treePopup.add(firstItem); + } else { + treePopup.add(new JLabel(" " + SieTreeModel.getPathName(clickedPath) + clickedNode)); + } + + treePopup.addSeparator(); + + if (clickedNode.enumeration != null) { + JMenu subMenu = new JMenu("Type: " + clickedNode.typeName); + for (final Object eachLabel : clickedNode.enumeration.pairs.keySet()) { + subMenu.add((String) eachLabel); } - treePopup.add("Units: " + clickedNode.units); - - if (!treePopup.isVisible()) { + treePopup.add(subMenu); + } else { + treePopup.add("Type: " + clickedNode.typeName); + } + treePopup.add("Units: " + clickedNode.units); + + if (!treePopup.isVisible()) { treePopup.show(e.getComponent(), e.getX(), e.getY()); - } - } - } else if (clickedNode != null && varTree.getModel().isLeaf(clickedNode) && clickedNode.isTrickManaged()) { - addVariable(SieTreeModel.getPathName(clickedPath) + clickedNode); + } + } + } else if (clickedNode != null && varTree.getModel().isLeaf(clickedNode) && clickedNode.isTrickManaged()) { + addVariable(SieTreeModel.getPathName(clickedPath) + clickedNode); } - } - - if (!UIUtils.isRightMouseClick(e)) { - if (treePopup.isVisible()) { + } + + if (!UIUtils.isRightMouseClick(e)) { + if (treePopup.isVisible()) { treePopup.setVisible(false); } - } - } + } + } } - - } + +} diff --git a/trick_source/sim_services/DataRecord/DRAscii.cpp b/trick_source/sim_services/DataRecord/DRAscii.cpp index 1a28cf58..6635c6f6 100644 --- a/trick_source/sim_services/DataRecord/DRAscii.cpp +++ b/trick_source/sim_services/DataRecord/DRAscii.cpp @@ -1,4 +1,4 @@ - + /* PURPOSE: (Data record in ascii format.) @@ -46,6 +46,7 @@ int Trick::DRAscii::format_specific_header( std::fstream & out_st ) { int Trick::DRAscii::format_specific_init() { unsigned int jj ; + std::streampos before_write; /* Store log information in csv/txt file */ if ( ! delimiter.empty() && delimiter.compare(",") != 0 ) { @@ -70,7 +71,7 @@ int Trick::DRAscii::format_specific_init() { record = false ; return -1 ; } - + before_write = out_stream.tellp(); // Write out the title line of the recording file /* Start with the 1st item in the buffer which should be "sys.exec.out.time" */ out_stream << rec_buffer[0]->ref->reference ; @@ -81,6 +82,7 @@ int Trick::DRAscii::format_specific_init() { out_stream << " {" << rec_buffer[0]->ref->attr->units << "}" ; } } + /* Write out specified recorded parameters */ for (jj = 1; jj < rec_buffer.size() ; jj++) { out_stream << delimiter << rec_buffer[jj]->ref->reference ; @@ -94,7 +96,7 @@ int Trick::DRAscii::format_specific_init() { } } out_stream << std::endl ; - + total_bytes_written += out_stream.tellp() - before_write; return(0) ; } @@ -105,6 +107,7 @@ int Trick::DRAscii::format_specific_init() { -# Write out each of the other parameter values preceded by the delimiter to the temporary #writer_buff -# Write #writer_buff to the output file -# Flush the output file stream +-# Return the number of bytes written */ int Trick::DRAscii::format_specific_write_data(unsigned int writer_offset) { unsigned int ii ; @@ -128,8 +131,8 @@ int Trick::DRAscii::format_specific_write_data(unsigned int writer_offset) { /*! Flush the output */ out_stream.flush() ; - - return(0) ; + /*! +1 for endl */ + return(strlen(writer_buff) + 1) ; } /** diff --git a/trick_source/sim_services/DataRecord/DRBinary.cpp b/trick_source/sim_services/DataRecord/DRBinary.cpp index f42af3f4..eaa8f314 100644 --- a/trick_source/sim_services/DataRecord/DRBinary.cpp +++ b/trick_source/sim_services/DataRecord/DRBinary.cpp @@ -53,6 +53,8 @@ int Trick::DRBinary::format_specific_init() { unsigned int jj ; int write_value ; + /* number of bytes written to data record */ + int bytes = 0 ; union { long l; @@ -72,45 +74,48 @@ int Trick::DRBinary::format_specific_init() { writer_buff[record_size * rec_buffer.size() - 1] = 1 ; /* start header information in trk file */ - if ((fp = creat(file_name.c_str(), S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)) == -1) { + if ((fd = creat(file_name.c_str(), S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)) == -1) { record = false ; return (-1) ; } + + /* Check to see if data is being recorded in little endian * byte order, and add little endian line if so. */ byte_order_union.l = 1 ; if (byte_order_union.c[sizeof(long)-1] != 1) { - write( fp , "Trick-10-L", (size_t)10 ) ; + bytes += write( fd , "Trick-10-L", (size_t)10 ) ; + } else { - write( fp , "Trick-10-B", (size_t)10 ) ; + bytes += write( fd , "Trick-10-B", (size_t)10 ) ; } write_value = rec_buffer.size() ; - write( fp , &write_value , sizeof(int) ) ; + bytes += write( fd , &write_value , sizeof(int) ) ; for (jj = 0; jj < rec_buffer.size(); jj++) { /* name */ write_value = strlen(rec_buffer[jj]->ref->reference) ; - write( fp , &write_value , sizeof(int)) ; - write( fp , rec_buffer[jj]->ref->reference , write_value ) ; + bytes += write( fd , &write_value , sizeof(int)) ; + bytes += write( fd , rec_buffer[jj]->ref->reference , write_value ) ; /* units */ if ( rec_buffer[jj]->ref->attr->mods & TRICK_MODS_UNITSDASHDASH ) { write_value = strlen("--") ; - write( fp , &write_value , sizeof(int)) ; - write( fp , "--" , write_value ) ; + bytes += write( fd , &write_value , sizeof(int)) ; + bytes += write( fd , "--" , write_value ) ; } else { write_value = strlen(rec_buffer[jj]->ref->attr->units) ; - write( fp , &write_value , sizeof(int)) ; - write( fp , rec_buffer[jj]->ref->attr->units , write_value ) ; + bytes += write( fd , &write_value , sizeof(int)) ; + bytes += write( fd , rec_buffer[jj]->ref->attr->units , write_value ) ; } write_value = rec_buffer[jj]->ref->attr->type ; - write( fp , &write_value , sizeof(int)) ; + bytes += write( fd , &write_value , sizeof(int)) ; - write( fp , &rec_buffer[jj]->ref->attr->size , sizeof(int)) ; + bytes += write( fd , &rec_buffer[jj]->ref->attr->size , sizeof(int)) ; } - + total_bytes_written += bytes; return(0) ; } @@ -119,6 +124,7 @@ int Trick::DRBinary::format_specific_init() { -# While there is data in memory that has not been written to disk -# Write out each of the other parameter values to the temporary #writer_buff -# Write #writer_buff to the output file +-# return the number of bytes written */ int Trick::DRBinary::format_specific_write_data(unsigned int writer_offset) { @@ -171,9 +177,7 @@ int Trick::DRBinary::format_specific_write_data(unsigned int writer_offset) { } - write( fp , writer_buff , len) ; - - return(0) ; + return write( fd , writer_buff , len) ; } /** @@ -183,8 +187,7 @@ int Trick::DRBinary::format_specific_write_data(unsigned int writer_offset) { int Trick::DRBinary::format_specific_shutdown() { if ( inited ) { - close(fp) ; + close(fd) ; } return(0) ; -} - +} \ No newline at end of file diff --git a/trick_source/sim_services/DataRecord/DataRecordDispatcher.cpp b/trick_source/sim_services/DataRecord/DataRecordDispatcher.cpp index 5bb0838f..4e9f923f 100644 --- a/trick_source/sim_services/DataRecord/DataRecordDispatcher.cpp +++ b/trick_source/sim_services/DataRecord/DataRecordDispatcher.cpp @@ -313,6 +313,23 @@ int Trick::DataRecordDispatcher::record_now_group( const char * in_name ) { return 0 ; } +int Trick::DataRecordDispatcher::set_group_max_file_size(const char * in_name, uint64_t bytes){ + unsigned int ii ; + for ( ii = 0 ; ii < groups.size() ; ii++ ) { + if ( in_name == NULL or !groups[ii]->get_group_name().compare(in_name) ) + groups[ii]->set_max_file_size(bytes) ; + } + return 0 ; +} + +int Trick::DataRecordDispatcher::set_max_file_size(uint64_t bytes) { + unsigned int ii ; + for ( ii = 0 ; ii < groups.size() ; ii++ ) { + groups[ii]->set_max_file_size(bytes) ; + } + return 0 ; +} + /** @details -# Call every group's init job - only needed when restoring checkpoint @@ -325,3 +342,4 @@ int Trick::DataRecordDispatcher::init_groups() { } return 0 ; } + diff --git a/trick_source/sim_services/DataRecord/DataRecordGroup.cpp b/trick_source/sim_services/DataRecord/DataRecordGroup.cpp index 3b6e4b82..13118098 100644 --- a/trick_source/sim_services/DataRecord/DataRecordGroup.cpp +++ b/trick_source/sim_services/DataRecord/DataRecordGroup.cpp @@ -71,6 +71,8 @@ Trick::DataRecordGroup::DataRecordGroup( std::string in_name ) : max_num(100000), buffer_num(0), writer_num(0), + max_file_size(1<<30), // 1 GB + total_bytes_written(0), writer_buff(NULL), single_prec_only(false), buffer_type(DR_Buffer), @@ -193,6 +195,15 @@ int Trick::DataRecordGroup::set_buffer_type( int in_buffer_type ) { return(0) ; } +int Trick::DataRecordGroup::set_max_file_size( uint64_t bytes ) { + if(bytes == 0) { + max_file_size = UINT64_MAX ; + } else { + max_file_size = bytes ; + } + return(0) ; +} + int Trick::DataRecordGroup::set_single_prec_only( bool in_single_prec_only ) { single_prec_only = in_single_prec_only ; return(0) ; @@ -248,7 +259,7 @@ int Trick::DataRecordGroup::add_variable( std::string in_name , std::string alia } void Trick::DataRecordGroup::remove_variable( std::string in_name ) { - // Trim leading spaces + // Trim leading spaces++ in_name.erase( 0, in_name.find_first_not_of( " \t" ) ); // Trim trailing spaces in_name.erase( in_name.find_last_not_of( " \t" ) + 1); @@ -342,7 +353,7 @@ int Trick::DataRecordGroup::init() { int ret ; // reset counter here so we can "re-init" our recording - buffer_num = writer_num = 0 ; + buffer_num = writer_num = total_bytes_written = 0 ; output_dir = command_line_args_get_output_dir() ; /* this is the common part of the record file name, the format specific will add the correct suffix */ @@ -632,7 +643,7 @@ int Trick::DataRecordGroup::write_data(bool must_write) { unsigned int num_to_write ; unsigned int writer_offset ; - if ( record and inited and (buffer_type == DR_No_Buffer or must_write)) { + if ( record and inited and (buffer_type == DR_No_Buffer or must_write) and (total_bytes_written <= max_file_size)) { // buffer_mutex is used in this one place to prevent forced calls of write_data // to not overwrite data being written by the asynchronous thread. @@ -649,7 +660,8 @@ int Trick::DataRecordGroup::write_data(bool must_write) { while ( writer_num != local_buffer_num ) { writer_offset = writer_num % max_num ; - format_specific_write_data(writer_offset) ; + //! keep record of bytes written to file. Default max is 1GB + total_bytes_written += format_specific_write_data(writer_offset) ; writer_num++ ; } diff --git a/trick_source/sim_services/DataRecord/data_record_utilities.cpp b/trick_source/sim_services/DataRecord/data_record_utilities.cpp index ffb883ff..d5e4e469 100644 --- a/trick_source/sim_services/DataRecord/data_record_utilities.cpp +++ b/trick_source/sim_services/DataRecord/data_record_utilities.cpp @@ -78,3 +78,17 @@ extern "C" Trick::DataRecordGroup * get_data_record_group( std::string in_name ) } return NULL ; } + +extern "C" int set_max_size_record_group (const char * in_name, uint64_t bytes ) { + if ( the_drd != NULL ) { + return the_drd->set_group_max_file_size(in_name, bytes ) ; + } + return -1 ; +} + +extern "C" int dr_set_max_file_size ( uint64_t bytes ) { + if ( the_drd != NULL ) { + return the_drd->set_max_file_size( bytes ) ; + } + return -1 ; +}