/*******************************************************************************
* Copyright (c) 2015 Sierra Wireless and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.html.
*
* Contributors:
* Sierra Wireless - initial API and implementation
*******************************************************************************/
package org.eclipse.leshan.core.node.codec.text;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Date;
import org.eclipse.leshan.core.model.LwM2mModel;
import org.eclipse.leshan.core.model.ResourceModel;
import org.eclipse.leshan.core.model.ResourceModel.Type;
import org.eclipse.leshan.core.node.LwM2mNode;
import org.eclipse.leshan.core.node.LwM2mPath;
import org.eclipse.leshan.core.node.LwM2mSingleResource;
import org.eclipse.leshan.core.node.ObjectLink;
import org.eclipse.leshan.core.node.codec.CodecException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class LwM2mNodeTextDecoder {
private static final Logger LOG = LoggerFactory.getLogger(LwM2mNodeTextDecoder.class);
public static LwM2mNode decode(byte[] content, LwM2mPath path, LwM2mModel model) throws CodecException {
if (!path.isResource())
throw new CodecException("Invalid path %s : TextDecoder decodes resource only", path);
ResourceModel rDesc = model.getResourceModel(path.getObjectId(), path.getResourceId());
String strValue = content != null ? new String(content, StandardCharsets.UTF_8) : "";
if (rDesc != null && rDesc.type != null) {
return LwM2mSingleResource.newResource(path.getResourceId(), parseTextValue(strValue, rDesc.type, path),
rDesc.type);
} else {
// unknown resource, returning a default string value
return LwM2mSingleResource.newStringResource(path.getResourceId(), strValue);
}
}
private static Object parseTextValue(String value, Type type, LwM2mPath path) throws CodecException {
LOG.trace("TEXT value for path {} and expected type {}: {}", path, type, value);
switch (type) {
case STRING:
return value;
case INTEGER:
try {
return Long.valueOf(value);
} catch (NumberFormatException e) {
throw new CodecException("Invalid value [%s] for integer resource [%s]", value, path);
}
case BOOLEAN:
switch (value) {
case "0":
return false;
case "1":
return true;
default:
throw new CodecException("Invalid value [%s] for boolean resource [%s]", value, path);
}
case FLOAT:
try {
return Double.valueOf(value);
} catch (NumberFormatException e) {
throw new CodecException("Invalid value [%s] for float resource [%s]", value, path);
}
case TIME:
// number of seconds since 1970/1/1
try {
return new Date(Long.valueOf(value) * 1000L);
} catch (NumberFormatException e) {
throw new CodecException("Invalid value [%s] for date resource [%s]", value, path);
}
case OBJLNK:
String[] intArr = value.split(":");
if (intArr.length != 2)
throw new CodecException("Invalid value %s for objectLink resource [%s]", Arrays.toString(intArr),
path);
try {
return new ObjectLink(Integer.parseInt(intArr[0]), Integer.parseInt(intArr[1]));
} catch (NumberFormatException e) {
throw new CodecException("Invalid value %s for objectLink resource [%s] ", Arrays.toString(intArr),
path);
}
case OPAQUE:
// not specified
default:
throw new CodecException("Could not handle %s value with TEXT encoder for resource %s", type, path);
}
}
}