From 7222245b33ed701cfb19eba2db610e9e2ba51384 Mon Sep 17 00:00:00 2001 From: Nick Burch Date: Sun, 19 Mar 2006 16:29:31 +0000 Subject: [PATCH] Improve the child record adding code git-svn-id: https://svn.apache.org/repos/asf/jakarta/poi/trunk@386996 13f79535-47bb-0310-9956-ffa450edef68 --- .../poi/hslf/record/RecordContainer.java | 108 ++++++++++++++---- 1 file changed, 85 insertions(+), 23 deletions(-) diff --git a/src/scratchpad/src/org/apache/poi/hslf/record/RecordContainer.java b/src/scratchpad/src/org/apache/poi/hslf/record/RecordContainer.java index b3d9dee3f..cd7aa16b3 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/record/RecordContainer.java +++ b/src/scratchpad/src/org/apache/poi/hslf/record/RecordContainer.java @@ -35,6 +35,7 @@ import java.io.ByteArrayOutputStream; public abstract class RecordContainer extends Record { protected Record[] _children; + private Boolean addingChildRecordLock = new Boolean(true); /** * Return any children @@ -51,40 +52,101 @@ public abstract class RecordContainer extends Record * return the new list. */ public Record[] appendChildRecord(Record newChild, Record[] children) { - Record[] r = new Record[children.length + 1]; - System.arraycopy(children,0,r,0,children.length); - r[r.length-1] = newChild; + Record[] r; + synchronized(addingChildRecordLock) { + r = new Record[children.length + 1]; + System.arraycopy(children,0,r,0,children.length); + r[r.length-1] = newChild; + } return r; } + /** + * Finds the location of the given child record + */ + private int findChildLocation(Record child) { + // Synchronized as we don't want things changing + // as we're doing our search + synchronized(addingChildRecordLock) { + for(int i=0; i<_children.length; i++) { + if(_children[i].equals(child)) { + return i; + } + } + } + return -1; + } + + /** + * Adds the given new Child Record at the given location, + * shuffling everything from there on down by one + * @param newChild + * @param position + */ + private void addChildAt(Record newChild, int position) { + synchronized(addingChildRecordLock) { + Record[] newChildren = new Record[_children.length+1]; + // Move over to the new array, shuffling on by one after + // the addition point + for(int i=0; i<_children.length; i++) { + if(i == position) { + newChildren[i] = newChild; + } + + if(i >= position) { + newChildren[i+1] = _children[i]; + } + if(i < position) { + newChildren[i] = _children[i]; + } + } + + // Special case - new record goes at the end + if(position == _children.length) { + newChildren[position] = newChild; + } + + // All done, replace our child list + _children = newChildren; + } + } + /** * Adds the given Child Record after the supplied record * @param newChild * @param after */ - public synchronized void addChildAfter(Record newChild, Record after) { - boolean added = false; - Record[] newChildren = new Record[_children.length+1]; - for(int i=0; i<_children.length; i++) { - int newPos = i; - if(added) { newPos++; } - - newChildren[newPos] = _children[i]; - if(_children[i].equals(after)) { - // Found one to add after - added = true; - newPos++; - newChildren[newPos] = newChild; + public void addChildAfter(Record newChild, Record after) { + synchronized(addingChildRecordLock) { + // Decide where we're going to put it + int loc = findChildLocation(after); + if(loc == -1) { + throw new IllegalArgumentException("Asked to add a new child after another record, but that record wasn't one of our children!"); } - } - - if(added) { - _children = newChildren; - } else { - throw new IllegalArgumentException("Asked to add a new child after another record, but that record wasn't one of our children!"); + + // Add one place after the supplied record + addChildAt(newChild, loc+1); } } - + + /** + * Adds the given Child Record before the supplied record + * @param newChild + * @param after + */ + public void addChildBefore(Record newChild, Record before) { + synchronized(addingChildRecordLock) { + // Decide where we're going to put it + int loc = findChildLocation(before); + if(loc == -1) { + throw new IllegalArgumentException("Asked to add a new child before another record, but that record wasn't one of our children!"); + } + + // Add at the place of the supplied record + addChildAt(newChild, loc); + } + } + /** * Write out our header, and our children. * @param headerA the first byte of the header