diff -r ed1c9f64298a -r 5b9d4d8641ce trace/traceviewer/com.nokia.trace.dictionary/src/com/nokia/trace/dictionary/model/handlers/DefHandler.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/trace/traceviewer/com.nokia.trace.dictionary/src/com/nokia/trace/dictionary/model/handlers/DefHandler.java Wed Jun 23 14:49:59 2010 +0300 @@ -0,0 +1,432 @@ +/* + * Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies). + * All rights reserved. + * This component and the accompanying materials are made available + * under the terms of "Eclipse Public License v1.0" + * which accompanies this distribution, and is available + * at the URL "http://www.eclipse.org/legal/epl-v10.html". + * + * Initial Contributors: + * Nokia Corporation - initial contribution. + * + * Contributors: + * + * Description: + * + * Def handler + * + */ +package com.nokia.trace.dictionary.model.handlers; + +import org.xml.sax.Attributes; + +import com.nokia.trace.dictionary.TraceDictionaryEngine; +import com.nokia.trace.dictionary.model.DecodeObject; +import com.nokia.trace.dictionary.model.DictionaryContentHandler; +import com.nokia.trace.dictionary.model.DictionaryDecodeModel; +import com.nokia.trace.dictionary.model.TraceData; +import com.nokia.trace.dictionary.model.decodeparameters.ArrayParameter; +import com.nokia.trace.dictionary.model.decodeparameters.ConstantParameter; +import com.nokia.trace.dictionary.model.decodeparameters.DecodeParameter; +import com.nokia.trace.dictionary.model.decodeparameters.HexParameter; +import com.nokia.trace.dictionary.model.decodeparameters.IntegerParameter; +import com.nokia.trace.eventrouter.TraceEvent; + +/** + * Def handler + */ +final class DefHandler extends BaseHandler { + + /** + * Tag name this handler handles + */ + private static final String DEF_TAG = "def"; //$NON-NLS-1$ + + /** + * Bytes in block + */ + private int bytesInBlock; + + /** + * Constructor + * + * @param model + * the model + */ + DefHandler(DictionaryDecodeModel model) { + super(model, DEF_TAG); + } + + /* + * (non-Javadoc) + * + * @see com.nokia.trace.dictionary.model.handlers.BaseHandler# + * processStartElement(org.xml.sax.Attributes, + * com.nokia.trace.dictionary.model.DictionaryContentHandler) + */ + @Override + public void processStartElement(Attributes atts, + DictionaryContentHandler handler) { + TraceData traceData = new TraceData( + Integer.parseInt(atts.getValue(ID)), atts.getValue(TYPE)); + handler.catchElementContents(traceData); + } + + /* + * (non-Javadoc) + * + * @see + * com.nokia.trace.dictionary.model.handlers.BaseHandler#processEndElement + * (java.lang.StringBuffer, java.lang.Object, + * com.nokia.trace.dictionary.model.DictionaryContentHandler, + * com.nokia.trace.dictionary.model.DecodeObject) + */ + @Override + public void processEndElement(StringBuffer elementContent, + Object unFinishedObject, DictionaryContentHandler handler, + DecodeObject parentObject) { + + TraceData traceData = (TraceData) unFinishedObject; + + // Check if there is only one variable in the trace. If + // split has two parts, there is only one variable indicator + if (elementContent.toString().split(VARIABLE_INDICATOR).length <= 2) { + traceData.setContainsOnlyOneVariable(true); + } + + int startOffset = 0; + int foundOffset = 0; + int endOffset = 0; + + // Search all variables from the string + while ((foundOffset = elementContent.indexOf(VARIABLE_INDICATOR, + startOffset)) != -1) { + createConstantParameter(elementContent, traceData, startOffset, + foundOffset); + + String parameterType; + StringBuilder digitsSB = new StringBuilder(); + boolean isArray = false; + + int nextCharOffset = foundOffset + 1; + + // First gather all possible digits to variable. e.g. from %02x + // gather 02 + char c = elementContent.charAt(nextCharOffset); + while (Character.isDigit(c)) { + digitsSB.append(c); + nextCharOffset++; + c = elementContent.charAt(nextCharOffset); + } + + // Check if next char is { + if (c == START_BRACKET) { + // Find offset of char } + endOffset = elementContent.indexOf(Character + .toString(END_BRACKET), foundOffset) + 1; + + // End offset was not found,let's change it to end of whole + // string to get some reasonable error message + if (endOffset == 0) { + endOffset = elementContent.length(); + } + + // Try to find array indicator characters + int indexOfBrackets = elementContent.indexOf(ARRAY_INDICATOR, + nextCharOffset); + // Indicator is found and is inside this parameter -> array + if (indexOfBrackets != -1 + && indexOfBrackets + ARRAY_INDICATOR.length() < endOffset) { + isArray = true; + } + + // Parse from between + parameterType = elementContent.substring(nextCharOffset, + endOffset); + + // Next char is not {, so it's a format char + } else { + + // If the first char is L, l, or h, format char has 2 or 3 chars + if (c == FORMATCHAR_INDICATOR_BIG_L + || c == FORMATCHAR_INDICATOR_SMALL_L + || c == FORMATCHAR_INDICATOR_H) { + c = elementContent.charAt(nextCharOffset + 1); + + // Next char is also h or l, format char is 3 chars + if (c == FORMATCHAR_INDICATOR_H + || c == FORMATCHAR_INDICATOR_SMALL_L) { + parameterType = elementContent.substring( + nextCharOffset, nextCharOffset + + LONG_FORMATCHAR_LENGTH + 1); + endOffset = nextCharOffset + LONG_FORMATCHAR_LENGTH + 1; + + // Format char is 2 chars + } else { + parameterType = elementContent.substring( + nextCharOffset, nextCharOffset + + LONG_FORMATCHAR_LENGTH); + endOffset = nextCharOffset + LONG_FORMATCHAR_LENGTH; + } + + // Only 1 char + } else { + parameterType = elementContent.substring(nextCharOffset, + nextCharOffset + SHORT_FORMATCHAR_LENGTH); + endOffset = nextCharOffset + SHORT_FORMATCHAR_LENGTH; + } + } + + DecodeParameter parameter; + + // Array parameter + if (isArray) { + parameter = handleArray(traceData, parameterType, digitsSB + .toString()); + + // Normal parameter + } else { + parameter = getDecodeParameter(parameterType, digitsSB + .toString()); + + if (parameter != null) { + // Add possible fillers before this new parameter + addFillers(traceData, parameter.getSize()); + + // Add to the parameter list + traceData.addDecodeParameter(parameter); + } + } + + // Parameter couldn't be found or created, inform user + if (parameter == null) { + postParameterNotFoundMsg(handler, parameterType); + } + + // Set start offset to previous end offset + startOffset = endOffset; + } // while ends + + // Create constant from the remaining + createConstantParameter(elementContent, traceData, startOffset, + elementContent.length()); + + // Add trace data to model + model.addTraceData(traceData); + + // Null bytes in block value afterwards + bytesInBlock = 0; + } + + /** + * Handles array + * + * @param traceData + * trace data + * @param parameterType + * parameter type + * @param digits + * @return created parameter or null if cannot be created + */ + private DecodeParameter handleArray(TraceData traceData, + String parameterType, String digits) { + DecodeParameter parameter = null; + + // Remove array indicator and try decode parameter again + String arrayContainsStr = parameterType.replace(ARRAY_INDICATOR, ""); //$NON-NLS-1$ + DecodeParameter arrayContains = getDecodeParameter(arrayContainsStr, + digits); + + // Basic type is found, create array parameter and add it + // also to the model and to the trace parameter list + if (arrayContains != null) { + parameter = new ArrayParameter(parameterType, false, arrayContains); + + model.addDecodeParameter(parameter); + traceData.addDecodeParameter(parameter); + } + + return parameter; + } + + /** + * Gets (either from model or creates new) decode parameter + * + * @param parameterType + * parameter type to be get + * @param digits + * possible format digits + * @return found or new decode parameter or null if not found + */ + private DecodeParameter getDecodeParameter(String parameterType, + String digits) { + String parameterWithFormat = digits + parameterType; + + // Find from parameter list using the possible formatting (e.g. %02) + DecodeParameter parameter = model + .getDecodeParameter(parameterWithFormat); + + // Not found, try to find without the formatting + if (parameter == null) { + parameter = model.getDecodeParameter(parameterType); + + // If found, we need to create new decode parameter with the + // formatting included + if (parameter != null) { + parameter = createNewFormatDecodeParameter(parameter, + parameterWithFormat, digits); + } + } + + return parameter; + } + + /** + * Create new decode parameter with formatting + * + * @param oldParameter + * old parameter + * @param parameterWithFormat + * new parameter name + * @param digits + * how should the parameter be formatted + * @return new decode parameter + */ + private DecodeParameter createNewFormatDecodeParameter( + DecodeParameter oldParameter, String parameterWithFormat, + String digits) { + DecodeParameter newParameter = null; + + // This is already checked with "isDigit()" so doesn't need try catch + int digit = Integer.parseInt(digits); + + // Integer parameter + if (oldParameter instanceof IntegerParameter) { + newParameter = new IntegerParameter(parameterWithFormat, false, + oldParameter.getSize(), true); + ((IntegerParameter) newParameter).setFormatToChars(digit); + } + + // Hex parameter + else if (oldParameter instanceof HexParameter) { + newParameter = new HexParameter(parameterWithFormat, false, + oldParameter.getSize()); + ((HexParameter) newParameter) + .setPrintInUpperCase(((HexParameter) oldParameter) + .getPrintInUpperCase()); + ((HexParameter) newParameter).setFormatToChars(digit); + } + + // Add to the parameter list + if (newParameter != null) { + model.addDecodeParameter(newParameter); + } + + return newParameter; + } + + /** + * Posts parameter not found message to user + * + * @param handler + * Dictionary handler + * @param parameterType + * parameter type that is not found + */ + private void postParameterNotFoundMsg(DictionaryContentHandler handler, + String parameterType) { + String parameterNotFound = Messages + .getString("DefHandler.ParameterNotFoundMsg"); //$NON-NLS-1$ + TraceEvent event = new TraceEvent(TraceEvent.ERROR, parameterNotFound + + parameterType); + event.setCategory(EVENT_CATEGORY); + event.setSource(Integer.valueOf(handler.getLocator().getLineNumber())); + TraceDictionaryEngine.postEvent(event); + } + + /** + * Adds possible filler parameters to traceData + * + * @param traceData + * traceData + * @param paramSize + * size of the new item + */ + private void addFillers(TraceData traceData, int paramSize) { + // Parameters are aligned to 32 bits. Parameter after + // end-of-string is aligned dynamically and thus no filler is + // created for it + if (paramSize == 0 || paramSize == 4 || paramSize == 8) { + if (bytesInBlock > 0) { + int fillerCount = 4 - bytesInBlock; + for (int i = 0; i < fillerCount; i++) { + traceData.addDecodeParameter(model.getFillerParameter()); + } + bytesInBlock = 0; + } + } else if (paramSize == 2) { + if (bytesInBlock == 1 || bytesInBlock == 3) { + traceData.addDecodeParameter(model.getFillerParameter()); + // If there was 1 existing byte and filler was added, + // the number of bytes in the block is now 4 including + // the 2-byte parameter. If there was 3 bytes, the + // filler brings it to 4 and the 16-bit parameter + // changes it to 2 + bytesInBlock += 3; + } else { + bytesInBlock += 2; + } + if (bytesInBlock >= 4) { + bytesInBlock -= 4; + } + } else { + bytesInBlock++; + if (bytesInBlock == 4) { + bytesInBlock = 0; + } + } + } + + /** + * Create constant parameter + * + * @param elementContent + * buffer where data is + * @param traceData + * TraceData where to insert this parameter + * @param startOffset + * start offset from buffer + * @param endOffset + * end offset from buffer + */ + private void createConstantParameter(StringBuffer elementContent, + TraceData traceData, int startOffset, int endOffset) { + + // Remove line breaks from the buffer + int len = elementContent.length(); + for (int i = 0; i < len; i++) { + char c = elementContent.charAt(i); + if (c == '\n' || c == '\r') { + elementContent.setCharAt(i, ' '); + } + } + + // First create constant parameter + String constantPar = elementContent.substring(startOffset, endOffset); + if (constantPar.length() > 0) { + // Try to find from the list + ConstantParameter parameter = model + .getConstantParameter(constantPar); + + // Couldn't be found + if (parameter == null) { + parameter = new ConstantParameter(constantPar, false); + } + + // Add to lists + traceData.addDecodeParameter(parameter); + model.addConstantParameter(parameter); + } + } + +}