1 /******************************************************************************* 2 * Copyright (c) 2015, 2016 Google, Inc and others. 3 * 4 * This program and the accompanying materials 5 * are made available under the terms of the Eclipse Public License 2.0 6 * which accompanies this distribution, and is available at 7 * https://www.eclipse.org/legal/epl-2.0/ 8 * 9 * SPDX-License-Identifier: EPL-2.0 10 * 11 * Contributors: 12 * Stefan Xenos (Google) - Initial implementation 13 *******************************************************************************/ 14 package org.eclipse.jdt.internal.core.nd.field; 15 16 import org.eclipse.jdt.internal.core.nd.Nd; 17 import org.eclipse.jdt.internal.core.nd.db.ModificationLog; 18 import org.eclipse.jdt.internal.core.nd.db.ModificationLog.Tag; 19 import org.eclipse.jdt.internal.core.nd.db.Database; 20 import org.eclipse.jdt.internal.core.nd.db.EmptyString; 21 import org.eclipse.jdt.internal.core.nd.db.IString; 22 23 /** 24 * Declares a Nd field of type string. Can be used in place of {@link Field}<{@link String}> in order to 25 * avoid extra GC overhead. 26 */ 27 public class FieldString extends BaseField implements IDestructableField { 28 public static final int RECORD_SIZE = Database.STRING_SIZE; 29 private static final char[] EMPTY_CHAR_ARRAY = new char[0]; 30 private final Tag putTag; 31 private final Tag destructTag; 32 FieldString(String structName, int fieldNumber)33 public FieldString(String structName, int fieldNumber) { 34 this.putTag = ModificationLog.createTag("Writing field " + fieldNumber + ", a " + getClass().getSimpleName() //$NON-NLS-1$//$NON-NLS-2$ 35 + " in struct " + structName); //$NON-NLS-1$ 36 this.destructTag = ModificationLog 37 .createTag("Destructing field " + fieldNumber + ", a " + getClass().getSimpleName() //$NON-NLS-1$//$NON-NLS-2$ 38 + " in struct " + structName); //$NON-NLS-1$ 39 } 40 get(Nd nd, long address)41 public IString get(Nd nd, long address) { 42 Database db = nd.getDB(); 43 long namerec = db.getRecPtr(address + this.offset); 44 45 if (namerec == 0) { 46 return EmptyString.create(); 47 } 48 return db.getString(namerec); 49 } 50 put(Nd nd, long address, char[] newString)51 public void put(Nd nd, long address, char[] newString) { 52 Database db = nd.getDB(); 53 db.getLog().start(this.putTag); 54 try { 55 if (newString == null) { 56 newString = EMPTY_CHAR_ARRAY; 57 } 58 IString name= get(nd, address); 59 if (name.compare(newString, true) != 0) { 60 name.delete(); 61 if (newString != null && newString.length > 0) { 62 db.putRecPtr(address + this.offset, db.newString(newString).getRecord()); 63 } else { 64 db.putRecPtr(address + this.offset, 0); 65 } 66 } 67 } finally { 68 db.getLog().end(this.putTag); 69 } 70 } 71 put(Nd nd, long address, String newString)72 public void put(Nd nd, long address, String newString) { 73 put(nd, address, newString.toCharArray()); 74 } 75 76 @Override destruct(Nd nd, long address)77 public void destruct(Nd nd, long address) { 78 Database db = nd.getDB(); 79 db.getLog().start(this.destructTag); 80 try { 81 get(nd, address).delete(); 82 nd.getDB().putRecPtr(address + this.offset, 0); 83 } finally { 84 db.getLog().end(this.destructTag); 85 } 86 } 87 88 @Override getRecordSize()89 public int getRecordSize() { 90 return RECORD_SIZE; 91 } 92 } 93