001: /* ====================================================================
002: Licensed to the Apache Software Foundation (ASF) under one or more
003: contributor license agreements. See the NOTICE file distributed with
004: this work for additional information regarding copyright ownership.
005: The ASF licenses this file to You under the Apache License, Version 2.0
006: (the "License"); you may not use this file except in compliance with
007: the License. You may obtain a copy of the License at
008:
009: http://www.apache.org/licenses/LICENSE-2.0
010:
011: Unless required by applicable law or agreed to in writing, software
012: distributed under the License is distributed on an "AS IS" BASIS,
013: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: See the License for the specific language governing permissions and
015: limitations under the License.
016: ==================================================================== */
017:
018: package org.apache.poi.hslf.record;
019:
020: import org.apache.poi.util.LittleEndian;
021: import java.io.IOException;
022: import java.io.OutputStream;
023: import java.util.Hashtable;
024:
025: /**
026: * A UserEdit Atom (type 4085). Holds information which bits of the file
027: * were last used by powerpoint, the version of powerpoint last used etc.
028: *
029: * ** WARNING ** stores byte offsets from the start of the PPT stream to
030: * other records! If you change the size of any elements before one of
031: * these, you'll need to update the offsets!
032: *
033: * @author Nick Burch
034: */
035:
036: public class UserEditAtom extends PositionDependentRecordAtom {
037: public static final int LAST_VIEW_NONE = 0;
038: public static final int LAST_VIEW_SLIDE_VIEW = 1;
039: public static final int LAST_VIEW_OUTLINE_VIEW = 2;
040: public static final int LAST_VIEW_NOTES = 3;
041:
042: private byte[] _header;
043: private static long _type = 4085l;
044: private byte[] reserved;
045:
046: private int lastViewedSlideID;
047: private int pptVersion;
048: private int lastUserEditAtomOffset;
049: private int persistPointersOffset;
050: private int docPersistRef;
051: private int maxPersistWritten;
052: private short lastViewType;
053:
054: // Somewhat user facing getters
055: public int getLastViewedSlideID() {
056: return lastViewedSlideID;
057: }
058:
059: public short getLastViewType() {
060: return lastViewType;
061: }
062:
063: // Scary internal getters
064: public int getLastUserEditAtomOffset() {
065: return lastUserEditAtomOffset;
066: }
067:
068: public int getPersistPointersOffset() {
069: return persistPointersOffset;
070: }
071:
072: public int getDocPersistRef() {
073: return docPersistRef;
074: }
075:
076: public int getMaxPersistWritten() {
077: return maxPersistWritten;
078: }
079:
080: // More scary internal setters
081: public void setLastUserEditAtomOffset(int offset) {
082: lastUserEditAtomOffset = offset;
083: }
084:
085: public void setPersistPointersOffset(int offset) {
086: persistPointersOffset = offset;
087: }
088:
089: public void setLastViewType(short type) {
090: lastViewType = type;
091: }
092:
093: public void setMaxPersistWritten(int max) {
094: maxPersistWritten = max;
095: }
096:
097: /* *************** record code follows ********************** */
098:
099: /**
100: * For the UserEdit Atom
101: */
102: protected UserEditAtom(byte[] source, int start, int len) {
103: // Sanity Checking
104: if (len < 34) {
105: len = 34;
106: }
107:
108: // Get the header
109: _header = new byte[8];
110: System.arraycopy(source, start, _header, 0, 8);
111:
112: // Get the last viewed slide ID
113: lastViewedSlideID = (int) LittleEndian.getInt(source,
114: start + 0 + 8);
115:
116: // Get the PPT version
117: pptVersion = (int) LittleEndian.getInt(source, start + 4 + 8);
118:
119: // Get the offset to the previous incremental save's UserEditAtom
120: // This will be the byte offset on disk where the previous one
121: // starts, or 0 if this is the first one
122: lastUserEditAtomOffset = (int) LittleEndian.getInt(source,
123: start + 8 + 8);
124:
125: // Get the offset to the persist pointers
126: // This will be the byte offset on disk where the preceding
127: // PersistPtrFullBlock or PersistPtrIncrementalBlock starts
128: persistPointersOffset = (int) LittleEndian.getInt(source,
129: start + 12 + 8);
130:
131: // Get the persist reference for the document persist object
132: // Normally seems to be 1
133: docPersistRef = (int) LittleEndian.getInt(source,
134: start + 16 + 8);
135:
136: // Maximum number of persist objects written
137: maxPersistWritten = (int) LittleEndian.getInt(source,
138: start + 20 + 8);
139:
140: // Last view type
141: lastViewType = (short) LittleEndian.getShort(source,
142: start + 24 + 8);
143:
144: // There might be a few more bytes, which are a reserved field
145: reserved = new byte[len - 26 - 8];
146: System.arraycopy(source, start + 26 + 8, reserved, 0,
147: reserved.length);
148: }
149:
150: /**
151: * We are of type 4085
152: */
153: public long getRecordType() {
154: return _type;
155: }
156:
157: /**
158: * At write-out time, update the references to PersistPtrs and
159: * other UserEditAtoms to point to their new positions
160: */
161: public void updateOtherRecordReferences(
162: Hashtable oldToNewReferencesLookup) {
163: // Look up the new positions of our preceding UserEditAtomOffset
164: if (lastUserEditAtomOffset != 0) {
165: Integer newLocation = (Integer) oldToNewReferencesLookup
166: .get(new Integer(lastUserEditAtomOffset));
167: if (newLocation == null) {
168: throw new RuntimeException(
169: "Couldn't find the new location of the UserEditAtom that used to be at "
170: + lastUserEditAtomOffset);
171: }
172: lastUserEditAtomOffset = newLocation.intValue();
173: }
174:
175: // Ditto for our PersistPtr
176: Integer newLocation = (Integer) oldToNewReferencesLookup
177: .get(new Integer(persistPointersOffset));
178: if (newLocation == null) {
179: throw new RuntimeException(
180: "Couldn't find the new location of the PersistPtr that used to be at "
181: + persistPointersOffset);
182: }
183: persistPointersOffset = newLocation.intValue();
184: }
185:
186: /**
187: * Write the contents of the record back, so it can be written
188: * to disk
189: */
190: public void writeOut(OutputStream out) throws IOException {
191: // Header
192: out.write(_header);
193:
194: // Write out the values
195: writeLittleEndian(lastViewedSlideID, out);
196: writeLittleEndian(pptVersion, out);
197: writeLittleEndian(lastUserEditAtomOffset, out);
198: writeLittleEndian(persistPointersOffset, out);
199: writeLittleEndian(docPersistRef, out);
200: writeLittleEndian(maxPersistWritten, out);
201: writeLittleEndian(lastViewType, out);
202:
203: // Reserved fields
204: out.write(reserved);
205: }
206: }
|