tracefw/tracecompiler/src/com.nokia.tracecompiler/src/com/nokia/tracecompiler/decodeplugins/dictionary/DictionaryFileWriter.java
changeset 56 aa2539c91954
parent 54 a151135b0cf9
child 60 e54443a6878c
child 62 1c2bb2fc7c87
equal deleted inserted replaced
54:a151135b0cf9 56:aa2539c91954
     1 /*
       
     2 * Copyright (c) 2008-2010 Nokia Corporation and/or its subsidiary(-ies). 
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:
       
    15 *
       
    16 * Writer for dictionary file
       
    17 *
       
    18 */
       
    19 package com.nokia.tracecompiler.decodeplugins.dictionary;
       
    20 
       
    21 import java.io.File;
       
    22 import java.util.ArrayList;
       
    23 import java.util.Collections;
       
    24 import java.util.Comparator;
       
    25 import java.util.Iterator;
       
    26 
       
    27 import com.nokia.tracecompiler.decodeplugins.dictionary.encoder.DataType;
       
    28 import com.nokia.tracecompiler.decodeplugins.dictionary.encoder.Dictionary;
       
    29 import com.nokia.tracecompiler.decodeplugins.dictionary.encoder.LocationStore;
       
    30 import com.nokia.tracecompiler.decodeplugins.dictionary.encoder.TraceComponent;
       
    31 import com.nokia.tracecompiler.decodeplugins.dictionary.encoder.TraceDataStore;
       
    32 import com.nokia.tracecompiler.decodeplugins.dictionary.encoder.TraceDictionaryEncoder;
       
    33 import com.nokia.tracecompiler.decodeplugins.dictionary.encoder.TypeDef;
       
    34 import com.nokia.tracecompiler.decodeplugins.dictionary.encoder.TypeDefStore;
       
    35 import com.nokia.tracecompiler.engine.LocationListBase;
       
    36 import com.nokia.tracecompiler.engine.LocationProperties;
       
    37 import com.nokia.tracecompiler.file.FileUtils;
       
    38 import com.nokia.tracecompiler.model.Trace;
       
    39 import com.nokia.tracecompiler.model.TraceConstantTable;
       
    40 import com.nokia.tracecompiler.model.TraceConstantTableEntry;
       
    41 import com.nokia.tracecompiler.model.TraceGroup;
       
    42 import com.nokia.tracecompiler.model.TraceModel;
       
    43 import com.nokia.tracecompiler.model.TraceObjectUtils;
       
    44 import com.nokia.tracecompiler.model.TraceParameter;
       
    45 import com.nokia.tracecompiler.project.FormattingUtils;
       
    46 import com.nokia.tracecompiler.project.PropertyNames;
       
    47 import com.nokia.tracecompiler.project.TraceProjectAPI;
       
    48 import com.nokia.tracecompiler.project.TraceProjectAPI.TraceFormatFlags;
       
    49 import com.nokia.tracecompiler.rules.FillerParameterRule;
       
    50 import com.nokia.tracecompiler.rules.HiddenTraceObjectRule;
       
    51 import com.nokia.tracecompiler.source.SourceConstants;
       
    52 import com.nokia.tracecompiler.source.SourceUtils;
       
    53 
       
    54 /**
       
    55  * Writer for dictionary file
       
    56  * 
       
    57  */
       
    58 final class DictionaryFileWriter {
       
    59 
       
    60 	/**
       
    61 	 * Comparator for file references
       
    62 	 */
       
    63 	private final class FileRefComparator implements
       
    64 			Comparator<DictionaryFileRef> {
       
    65 		public int compare(DictionaryFileRef o1, DictionaryFileRef o2) {
       
    66 			int val = o1.path.compareTo(o2.path);
       
    67 			if (val == 0) {
       
    68 				val = o1.file.compareTo(o2.file);
       
    69 			}
       
    70 			return val;
       
    71 		}
       
    72 	}
       
    73 
       
    74 	/**
       
    75 	 * Dictionary file
       
    76 	 */
       
    77 	private DictionaryFile dictionaryFile;
       
    78 
       
    79 	/**
       
    80 	 * Sequential number for trace definitions
       
    81 	 */
       
    82 	private int defref;
       
    83 
       
    84 	/**
       
    85 	 * Sequential number for file definitions
       
    86 	 */
       
    87 	private int fileref;
       
    88 
       
    89 	/**
       
    90 	 * Constructor
       
    91 	 * 
       
    92 	 * @param dictionaryFile
       
    93 	 *            the dictionary file
       
    94 	 */
       
    95 	DictionaryFileWriter(DictionaryFile dictionaryFile) {
       
    96 		this.dictionaryFile = dictionaryFile;
       
    97 	}
       
    98 
       
    99 	/**
       
   100 	 * Writes the dictionary file
       
   101 	 */
       
   102 	void write() {
       
   103 		defref = 0;
       
   104 		fileref = 0;
       
   105 		File file = new File(dictionaryFile.getAbsolutePathWithID());
       
   106 		// Delete removes possible read-only flags
       
   107 		if (file.exists()) {
       
   108 			file.delete();
       
   109 		}
       
   110 
       
   111 		TraceDictionaryEncoder encoder = new TraceDictionaryEncoder();
       
   112 		File path = file.getParentFile();
       
   113 		if (!path.exists()) {
       
   114 			FileUtils.createDirectories(path);
       
   115 		}
       
   116 		encoder.createNewDictionary(file.getAbsolutePath());
       
   117 		Dictionary.startDictionary();
       
   118 		createTypedefs();
       
   119 		createDefs();
       
   120 		createLocations();
       
   121 		createComponent();
       
   122 		Dictionary.endDictionary();
       
   123 	}
       
   124 
       
   125 	/**
       
   126 	 * Creates the type definitions
       
   127 	 */
       
   128 	private void createTypedefs() {
       
   129 		TypeDefStore.startTypeDefs();
       
   130 		ArrayList<String> typeList = buildTypeList();
       
   131 		writeTypeDefinitions(typeList);
       
   132 		TypeDefStore.endTypeDefs();
       
   133 	}
       
   134 
       
   135 	/**
       
   136 	 * Builds the list of parameter types
       
   137 	 * 
       
   138 	 * @return the list of types found from the model
       
   139 	 */
       
   140 	private ArrayList<String> buildTypeList() {
       
   141 		TraceModel model = dictionaryFile.getOwner().getModel();
       
   142 		ArrayList<String> typeList = new ArrayList<String>();
       
   143 		for (TraceGroup group : model) {
       
   144 			for (Trace trace : group) {
       
   145 				for (TraceParameter parameter : trace) {
       
   146 					if ((parameter.getExtension(HiddenTraceObjectRule.class) == null)
       
   147 							|| (parameter
       
   148 									.getExtension(FillerParameterRule.class) != null)) {
       
   149 						String type = parameter.getType();
       
   150 						if (!typeList.contains(type)) {
       
   151 							typeList.add(type);
       
   152 						}
       
   153 					}
       
   154 				}
       
   155 			}
       
   156 		}
       
   157 		return typeList;
       
   158 	}
       
   159 
       
   160 	/**
       
   161 	 * Writes the data type definitions
       
   162 	 * 
       
   163 	 * @param typeList
       
   164 	 *            the list of data types
       
   165 	 */
       
   166 	private void writeTypeDefinitions(ArrayList<String> typeList) {
       
   167 		for (String type : typeList) {
       
   168 			DataType dt = mapTypeToDataType(type);
       
   169 			if (dt != null) {
       
   170 				// Normal parameters
       
   171 				int size = mapParameterTypeToSize(type);
       
   172 				String formatChar = SourceUtils.mapNormalTypeToFormat(type);
       
   173 				if (formatChar != null && formatChar.length() > 1
       
   174 						&& formatChar.charAt(0) == '%') {
       
   175 					formatChar = formatChar.substring(1);
       
   176 					TypeDefStore.writeTypeDef(type, size, formatChar, dt);
       
   177 
       
   178 					// Write alternative format characters
       
   179 					writeAlternativeFormatChars(formatChar, type, size, dt);
       
   180 
       
   181 				} else {
       
   182 					TypeDefStore.writeTypeDef(type, size, null, dt);
       
   183 				}
       
   184 			} else {
       
   185 				// Enum parameters
       
   186 				TraceModel model = dictionaryFile.getOwner().getModel();
       
   187 				TraceConstantTable table = model.findConstantTableByName(type);
       
   188 				if (table != null) {
       
   189 					TypeDefStore.startTypeDef(table.getName(),
       
   190 							mapParameterTypeToSize(table.getType()), null,
       
   191 							DataType.ENUM);
       
   192 					for (TraceConstantTableEntry entry : table) {
       
   193 						TypeDef.writeTypeMember(entry.getID(), entry.getName(),
       
   194 								null);
       
   195 					}
       
   196 					TypeDefStore.endTypeDef();
       
   197 				}
       
   198 			}
       
   199 		}
       
   200 	}
       
   201 
       
   202 	/**
       
   203 	 * Writes alternative format characters to the Dictionary
       
   204 	 * 
       
   205 	 * @param formatChar
       
   206 	 *            formatchar
       
   207 	 * @param type
       
   208 	 *            parameter type
       
   209 	 * @param size
       
   210 	 *            parameter size
       
   211 	 * @param dt
       
   212 	 *            data type
       
   213 	 */
       
   214 	private void writeAlternativeFormatChars(String formatChar, String type,
       
   215 			int size, DataType dt) {
       
   216 
       
   217 		// If there's big L, write also 'll' type
       
   218 		if (formatChar.indexOf('L') != -1) {
       
   219 
       
   220 			// Double small l
       
   221 			String newFormatChar = formatChar.replace("L", "ll"); //$NON-NLS-1$ //$NON-NLS-2$
       
   222 			TypeDefStore.writeTypeDef(type, size, newFormatChar, dt);
       
   223 			writeCapitalHexType(newFormatChar, type, size, dt);
       
   224 
       
   225 		}
       
   226 
       
   227 		// Write alternative option to float types
       
   228 		else if (formatChar.equals("f") || formatChar.equals("e") //$NON-NLS-1$//$NON-NLS-2$
       
   229 				|| formatChar.equals("g")) { //$NON-NLS-1$
       
   230 
       
   231 			String newFormatChar = 'L' + formatChar;
       
   232 			TypeDefStore.writeTypeDef(type, size, newFormatChar, dt);
       
   233 		}
       
   234 
       
   235 		else {
       
   236 			// If length is one, add also formatchar with "l"
       
   237 			if (formatChar.length() == 1) {
       
   238 				String newFormatChar = "l" + formatChar; //$NON-NLS-1$
       
   239 				TypeDefStore.writeTypeDef(type, size, newFormatChar, dt);
       
   240 				writeCapitalHexType(newFormatChar, type, size, dt);
       
   241 			}
       
   242 
       
   243 			// Check capital hex need
       
   244 			writeCapitalHexType(formatChar, type, size, dt);
       
   245 		}
       
   246 	}
       
   247 
       
   248 	/**
       
   249 	 * Writes capital hex type
       
   250 	 * 
       
   251 	 * @param formatChar
       
   252 	 *            formatchar
       
   253 	 * @param type
       
   254 	 *            parameter type
       
   255 	 * @param size
       
   256 	 *            parameter size
       
   257 	 * @param dt
       
   258 	 *            data type
       
   259 	 */
       
   260 	private void writeCapitalHexType(String formatChar, String type, int size,
       
   261 			DataType dt) {
       
   262 
       
   263 		// Write also capital X if there are hex values
       
   264 		if (formatChar.indexOf('x') != -1) {
       
   265 			type = type.toUpperCase();
       
   266 			TypeDefStore.writeTypeDef(type, size, formatChar.replace('x', 'X'),
       
   267 					dt);
       
   268 		}
       
   269 	}
       
   270 
       
   271 	/**
       
   272 	 * Gets the parameter size from type
       
   273 	 * 
       
   274 	 * @param type
       
   275 	 *            the type
       
   276 	 * @return the size in bytes
       
   277 	 */
       
   278 	private int mapParameterTypeToSize(String type) {
       
   279 		int size = SourceUtils.mapParameterTypeToSize(type);
       
   280 		if (size == 0) {
       
   281 			if (type.equals(TraceParameter.ASCII)) {
       
   282 				size = 1;
       
   283 			} else if (type.equals(TraceParameter.UNICODE)) {
       
   284 				size = 2; // CodForChk_Dis_Magic
       
   285 			}
       
   286 		}
       
   287 		return size;
       
   288 	}
       
   289 
       
   290 	/**
       
   291 	 * Creates the trace definitions
       
   292 	 */
       
   293 	private void createDefs() {
       
   294 		// This should check for duplicates
       
   295 		TraceDataStore.startDataStore();
       
   296 		TraceModel model = dictionaryFile.getOwner().getModel();
       
   297 		TraceProjectAPI api = model.getExtension(TraceProjectAPI.class);
       
   298 		for (TraceGroup group : model) {
       
   299 			for (Trace trace : group) {
       
   300 				trace.addExtension(new DictionaryDefRef(++defref));
       
   301 				TraceFormatFlags flags = new TraceFormatFlags();
       
   302 				flags.isFormattingSupported = true;
       
   303 				String data = api.formatTraceForExport(trace, flags);
       
   304 				data = replaceUnescapeQuotes(data);
       
   305 				TraceDataStore.writeData(defref, DataType.STRING, data);
       
   306 			}
       
   307 		}
       
   308 		TraceDataStore.endDataStore();
       
   309 	}
       
   310 
       
   311 	/**
       
   312 	 * Replaces unescape quates
       
   313 	 * 
       
   314 	 * @param data
       
   315 	 *            the data
       
   316 	 * @return the new string
       
   317 	 */
       
   318 	private String replaceUnescapeQuotes(String data) {
       
   319 		data = data.replace("\\\"", "\""); //$NON-NLS-1$ //$NON-NLS-2$
       
   320 		return data;
       
   321 	}
       
   322 
       
   323 	/**
       
   324 	 * Maps a basic type to a Dictionary data type
       
   325 	 * 
       
   326 	 * @param type
       
   327 	 *            the type
       
   328 	 * @return the data type
       
   329 	 */
       
   330 	private DataType mapTypeToDataType(String type) { // CodForChk_Dis_ComplexFunc
       
   331 		DataType retval;
       
   332 		// Unsigned is not supported in Dictionary
       
   333 		if (type.equals(TraceParameter.SDEC32)) {
       
   334 			retval = DataType.INTEGER;
       
   335 		} else if (type.equals(TraceParameter.HEX32)) {
       
   336 			retval = DataType.HEX;
       
   337 		} else if (type.equals(TraceParameter.UDEC32)) {
       
   338 			retval = DataType.INTEGER;
       
   339 		} else if (type.equals(TraceParameter.OCT32)) {
       
   340 			retval = DataType.OCTAL;
       
   341 		} else if (type.equals(TraceParameter.SDEC16)) {
       
   342 			retval = DataType.INTEGER;
       
   343 		} else if (type.equals(TraceParameter.HEX16)) {
       
   344 			retval = DataType.HEX;
       
   345 		} else if (type.equals(TraceParameter.UDEC16)) {
       
   346 			retval = DataType.INTEGER;
       
   347 		} else if (type.equals(TraceParameter.OCT16)) {
       
   348 			retval = DataType.OCTAL;
       
   349 		} else if (type.equals(TraceParameter.SDEC8)) {
       
   350 			retval = DataType.INTEGER;
       
   351 		} else if (type.equals(TraceParameter.HEX8)) {
       
   352 			retval = DataType.HEX;
       
   353 		} else if (type.equals(TraceParameter.UDEC8)) {
       
   354 			retval = DataType.INTEGER;
       
   355 		} else if (type.equals(TraceParameter.OCT8)) {
       
   356 			retval = DataType.OCTAL;
       
   357 		} else if (type.equals(TraceParameter.SDEC64)) {
       
   358 			retval = DataType.INTEGER;
       
   359 		} else if (type.equals(TraceParameter.HEX64)) {
       
   360 			retval = DataType.HEX;
       
   361 		} else if (type.equals(TraceParameter.UDEC64)) {
       
   362 			retval = DataType.INTEGER;
       
   363 		} else if (type.equals(TraceParameter.OCT64)) {
       
   364 			retval = DataType.OCTAL;
       
   365 		} else if (type.equals(TraceParameter.ASCII)) {
       
   366 			retval = DataType.STRING;
       
   367 		} else if (type.equals(TraceParameter.UNICODE)) {
       
   368 			retval = DataType.STRING;
       
   369 		} else if (type.equals(TraceParameter.FLOAT_FIX)) {
       
   370 			retval = DataType.FLOAT;
       
   371 		} else if (type.equals(TraceParameter.FLOAT_EXP)) {
       
   372 			retval = DataType.FLOAT;
       
   373 		} else if (type.equals(TraceParameter.FLOAT_OPT)) {
       
   374 			retval = DataType.FLOAT;
       
   375 		} else if (type.equals(TraceParameter.POINTER)) {
       
   376 			retval = DataType.HEX;
       
   377 		} else {
       
   378 			retval = null;
       
   379 		}
       
   380 		return retval;
       
   381 	}
       
   382 
       
   383 	/**
       
   384 	 * Creates the location definitions
       
   385 	 */
       
   386 	private void createLocations() {
       
   387 		ArrayList<DictionaryFileRef> files = new ArrayList<DictionaryFileRef>();
       
   388 		LocationStore.startLocations();
       
   389 		for (TraceGroup group : dictionaryFile.getOwner().getModel()) {
       
   390 			for (Trace trace : group) {
       
   391 				writeLocation(files, trace);
       
   392 			}
       
   393 		}
       
   394 		// Build XML and assign ID's to refs
       
   395 		Collections.sort(files, new FileRefComparator());
       
   396 		String lastpath = null;
       
   397 		for (DictionaryFileRef ref : files) {
       
   398 			if (!ref.path.equals(lastpath)) {
       
   399 				if (lastpath != null) {
       
   400 					LocationStore.endPath();
       
   401 				}
       
   402 				LocationStore.startPath(ref.path);
       
   403 				lastpath = ref.path;
       
   404 			}
       
   405 			LocationStore.writeFile(++fileref, ref.file);
       
   406 			ref.refid = fileref;
       
   407 		}
       
   408 		if (lastpath != null) {
       
   409 			LocationStore.endPath();
       
   410 		}
       
   411 		LocationStore.endLocations();
       
   412 	}
       
   413 
       
   414 	/**
       
   415 	 * Writes the location of a trace
       
   416 	 * 
       
   417 	 * @param files
       
   418 	 *            file references
       
   419 	 * @param trace
       
   420 	 *            trace to be written
       
   421 	 */
       
   422 	private void writeLocation(ArrayList<DictionaryFileRef> files, Trace trace) {
       
   423 		LocationProperties loc = findFirstLocation(trace);
       
   424 		if (loc != null) {
       
   425 			String path = loc.getFilePath();
       
   426 			String file = loc.getFileName();
       
   427 			if (path != null) {
       
   428 				path = FileUtils.convertSeparators(
       
   429 						SourceConstants.FORWARD_SLASH_CHAR, path, true);
       
   430 				// TODO: Remove drive letter. Actually cannot remove drive
       
   431 				// letter because EPOCROOT might not be in the root of the drive
       
   432 			}
       
   433 			DictionaryFileRef ref = getRef(files, file, path);
       
   434 			if (ref == null) {
       
   435 				ref = new DictionaryFileRef(file, path, trace);
       
   436 				files.add(ref);
       
   437 				trace.addExtension(ref);
       
   438 			} else {
       
   439 				trace.addExtension(ref);
       
   440 			}
       
   441 		}
       
   442 	}
       
   443 
       
   444 	/**
       
   445 	 * Finds the first location from trace
       
   446 	 * 
       
   447 	 * @param trace
       
   448 	 *            the trace
       
   449 	 * @return the location
       
   450 	 */
       
   451 	private LocationProperties findFirstLocation(Trace trace) {
       
   452 		Iterator<LocationListBase> itr = trace
       
   453 				.getExtensions(LocationListBase.class);
       
   454 		LocationProperties loc = null;
       
   455 		while (itr.hasNext() && loc == null) {
       
   456 			Iterator<LocationProperties> locs = itr.next().iterator();
       
   457 			if (locs.hasNext()) {
       
   458 				loc = locs.next();
       
   459 			}
       
   460 		}
       
   461 		return loc;
       
   462 	}
       
   463 
       
   464 	/**
       
   465 	 * Gets a file reference
       
   466 	 * 
       
   467 	 * @param files
       
   468 	 *            the list of file references
       
   469 	 * @param file
       
   470 	 *            file name
       
   471 	 * @param path
       
   472 	 *            file path
       
   473 	 * @return the file reference
       
   474 	 */
       
   475 	private DictionaryFileRef getRef(ArrayList<DictionaryFileRef> files,
       
   476 			String file, String path) {
       
   477 		DictionaryFileRef retval = null;
       
   478 		for (int i = 0; i < files.size() && retval == null; i++) {
       
   479 			DictionaryFileRef ref = files.get(i);
       
   480 			if (ref.file.equals(file) && ref.path.equals(path)) {
       
   481 				retval = ref;
       
   482 			}
       
   483 		}
       
   484 		return retval;
       
   485 	}
       
   486 
       
   487 	/**
       
   488 	 * Creates the component definition
       
   489 	 */
       
   490 	private void createComponent() {
       
   491 		TraceModel model = dictionaryFile.getOwner().getModel();
       
   492 		int compid = model.getID();
       
   493 		// Component prefix and suffix are in property file.
       
   494 		// If not there, the default values are used
       
   495 		String prefix = TraceObjectUtils.findProperty(model,
       
   496 				PropertyNames.PREFIX);
       
   497 		if (prefix == null || prefix.length() == 0) {
       
   498 			prefix = FormattingUtils.getDefaultComponentPrefix(model);
       
   499 		}
       
   500 		String suffix = TraceObjectUtils.findProperty(model,
       
   501 				PropertyNames.SUFFIX);
       
   502 		if (suffix == null || suffix.length() == 0) {
       
   503 			suffix = FormattingUtils.getDefaultComponentSuffix(model);
       
   504 		}
       
   505 		Dictionary.startComponent(compid, dictionaryFile.getProjectName(),
       
   506 				prefix, suffix);
       
   507 		for (TraceGroup group : model) {
       
   508 			createGroup(group);
       
   509 		}
       
   510 		Dictionary.endComponent();
       
   511 	}
       
   512 
       
   513 	/**
       
   514 	 * Creates a group definition
       
   515 	 * 
       
   516 	 * @param group
       
   517 	 *            the group
       
   518 	 */
       
   519 	private void createGroup(TraceGroup group) {
       
   520 		String prefix = TraceObjectUtils.findProperty(group,
       
   521 				PropertyNames.PREFIX);
       
   522 		if (prefix == null || prefix.length() == 0) {
       
   523 			prefix = FormattingUtils.getDefaultGroupPrefix(group);
       
   524 		}
       
   525 		String suffix = TraceObjectUtils.findProperty(group,
       
   526 				PropertyNames.SUFFIX);
       
   527 		if (suffix == null || suffix.length() == 0) {
       
   528 			suffix = FormattingUtils.getDefaultGroupSuffix(group);
       
   529 		}
       
   530 		TraceComponent.startGroup(group.getID(), group.getName(), prefix,
       
   531 				suffix);
       
   532 		for (Trace trace : group) {
       
   533 			createTrace(trace);
       
   534 		}
       
   535 		TraceComponent.endGroup();
       
   536 	}
       
   537 
       
   538 	/**
       
   539 	 * Creates a trace definition
       
   540 	 * 
       
   541 	 * @param trace
       
   542 	 *            the trace
       
   543 	 */
       
   544 	private void createTrace(Trace trace) {
       
   545 		DictionaryDefRef defref = trace.getExtension(DictionaryDefRef.class);
       
   546 		if (defref != null) {
       
   547 			DictionaryFileRef fileref = trace
       
   548 					.getExtension(DictionaryFileRef.class);
       
   549 			com.nokia.tracecompiler.decodeplugins.dictionary.encoder.TraceGroup.startTrace(defref
       
   550 					.getRefId(), trace.getName());
       
   551 			if (fileref != null) {
       
   552 				writeTraceWithLocation(fileref.getRefId(), trace);
       
   553 			} else {
       
   554 				com.nokia.tracecompiler.decodeplugins.dictionary.encoder.Trace.writeInstance(trace
       
   555 						.getID(), 0, 0, "", //$NON-NLS-1$
       
   556 						""); //$NON-NLS-1$
       
   557 			}
       
   558 			com.nokia.tracecompiler.decodeplugins.dictionary.encoder.TraceGroup.endTrace();
       
   559 		}
       
   560 		trace.removeExtensions(DictionaryRef.class);
       
   561 
       
   562 	}
       
   563 
       
   564 	/**
       
   565 	 * Writes a trace which has a source location
       
   566 	 * 
       
   567 	 * @param refId
       
   568 	 *            file reference number
       
   569 	 * @param trace
       
   570 	 *            the trace
       
   571 	 */
       
   572 	private void writeTraceWithLocation(int refId, Trace trace) {
       
   573 		LocationProperties loc = findFirstLocation(trace);
       
   574 		int line = 0;
       
   575 		String className = ""; //$NON-NLS-1$
       
   576 		String functionName = ""; //$NON-NLS-1$
       
   577 		if (loc != null) {
       
   578 			line = loc.getLineNumber();
       
   579 			className = loc.getClassName();
       
   580 			functionName = loc.getFunctionName();
       
   581 		}
       
   582 		com.nokia.tracecompiler.decodeplugins.dictionary.encoder.Trace.writeInstance(trace.getID(),
       
   583 				refId, line, functionName, className);
       
   584 	}
       
   585 
       
   586 }