ByteString(Binary) was added in the Value of OCRepresentation.
But, RE layer does not covered ByteString type.
In this patch, ByteString type is added in RE layer
for synchronization with OC.
patch 2 : Fix memory leak
Change-Id: I5e52fea9b7d4b5b09384fa24446f550d93b89395
Signed-off-by: koushik.girijala <g.koushik@samsung.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/16029
Reviewed-by: Abhishek Pandey <abhi.siso@samsung.com>
Reviewed-by: JungYong KIM <jyong2.kim@samsung.com>
Tested-by: jenkins-iotivity <jenkins-iotivity@opendaylight.org>
Reviewed-by: Uze Choi <uzchoi@samsung.com>
--- /dev/null
+package org.iotivity.service;
+
+/**
+ * This Class represents byte string value for RcsResourceAttributes.
+ */
+public class RcsByteString {
+
+ private byte[] mData;
+ private long mSize;
+
+ public RcsByteString(byte[] data, long size) {
+ this.mData = data;
+ this.mSize = size;
+ }
+
+ public byte[] getValue() {
+ return this.mData;
+ }
+
+ public long getSize() {
+ return this.mSize;
+ }
+}
\ No newline at end of file
* @see Type
*/
public static enum TypeId {
- NULL, BOOLEAN, INTEGER, DOUBLE, STRING, ATTRIBUTES, ARRAY;
+ NULL, BOOLEAN, INTEGER, DOUBLE, STRING, BYTESTRING, ATTRIBUTES, ARRAY;
}
/**
types.put(Integer.class, new Type(TypeId.INTEGER));
types.put(Double.class, new Type(TypeId.DOUBLE));
types.put(String.class, new Type(TypeId.STRING));
+ types.put(RcsByteString.class, new Type(TypeId.BYTESTRING));
types.put(RcsResourceAttributes.class, new Type(TypeId.ATTRIBUTES));
types.put(boolean[].class, new ArrayType(TypeId.BOOLEAN, 1));
types.put(int[].class, new ArrayType(TypeId.INTEGER, 1));
types.put(double[].class, new ArrayType(TypeId.DOUBLE, 1));
types.put(String[].class, new ArrayType(TypeId.STRING, 1));
+ types.put(RcsByteString[].class, new ArrayType(TypeId.BYTESTRING, 1));
types.put(RcsResourceAttributes[].class,
new ArrayType(TypeId.ATTRIBUTES, 1));
types.put(int[][].class, new ArrayType(TypeId.INTEGER, 2));
types.put(double[][].class, new ArrayType(TypeId.DOUBLE, 2));
types.put(String[][].class, new ArrayType(TypeId.STRING, 2));
+ types.put(RcsByteString[][].class, new ArrayType(TypeId.BYTESTRING, 2));
types.put(RcsResourceAttributes[][].class,
new ArrayType(TypeId.ATTRIBUTES, 2));
types.put(int[][][].class, new ArrayType(TypeId.INTEGER, 3));
types.put(double[][][].class, new ArrayType(TypeId.DOUBLE, 3));
types.put(String[][][].class, new ArrayType(TypeId.STRING, 3));
+ types.put(RcsByteString[][][].class, new ArrayType(TypeId.BYTESTRING, 3));
types.put(RcsResourceAttributes[][][].class,
new ArrayType(TypeId.ATTRIBUTES, 3));
/**
* Constructs a new value that holds a RcsResourceAttributes array.
*
- * @param value
- * a RcsResourceAttributes array
+ * @param value a RcsByteString array
+ * @throws NullPointerException if value is null.
+ */
+ public RcsValue(RcsByteString[] value) {
+ this((Object) value);
+ }
+
+ /**
+ * Constructs a new value that holds a two-dimensional RcsByteString array.
+ *
+ * @param value a two-dimensional RcsByteString array
+ * @throws NullPointerException if value is null.
+ */
+ public RcsValue(RcsByteString[][] value) {
+ this((Object) value);
+ }
+
+ /**
+ * Constructs a new value that holds a three-dimensional RcsByteString array.
+ *
+ * @param value a three-dimensional RcsByteString array
+ * @throws NullPointerException if value is null.
+ */
+ public RcsValue(RcsByteString[][][] value) {
+ this((Object) value);
+ }
+
+ /**
+ * Constructs a new value that holds a RcsResourceAttributes array.
*
* @throws NullPointerException
* if value is null.
}
/**
+ * Returns the value as an RcsByteString array, null if the value is not the
+ * desired type.
+ *
+ * @return an RcsByteString array
+ */
+ public RcsByteString[] asByteStringArray() {
+ return getOrNull();
+ }
+
+ /**
+ * Returns the value as a two-dimensional RcsByteString array, null if the
+ * value is not the desired type.
+ *
+ * @return a two-dimensional RcsByteString array
+ */
+ public RcsByteString[][] asByteString2DArray() {
+ return getOrNull();
+ }
+
+ /**
+ * Returns the value as a three-dimensional RcsByteString array, null if the
+ * value is not the desired type.
+ *
+ * @return a three-dimensional RcsByteString array
+ */
+ public RcsByteString[][][] asByteString3DArray() {
+ return getOrNull();
+ }
+
+ /**
* Returns the value as an attributes array, null if the value is not the
* desired type.
*
jobject g_obj_TypeId_Integer;
jobject g_obj_TypeId_Double;
jobject g_obj_TypeId_String;
+ jobject g_obj_TypeId_ByteString;
jobject g_obj_TypeId_Attributes;
jobject g_obj_TypeId_Array;
static constexpr char className[] = "L" CLS_NAME_STRING ";";
};
constexpr char JniTypeTrait< std::string >::className[];
+ template< typename ENV >
+ inline RCSByteString invoke_ByteString_byteStringValue(JNIEnvWrapper *env, jobject byteStringObj)
+ {
+ EXPECT_RET(byteStringObj, "byteStringObj is null!", { });
+
+ jclass g_cls_RCSByteString = env->FindClassAsGlobalRef(CLS_NAME_RESOURCEBYTESTRING);
+
+ static jfieldID field_data = env->GetFieldID(g_cls_RCSByteString, "mData", "[B");
+ static jfieldID field_length = env->GetFieldID(g_cls_RCSByteString, "mSize", "J");
+
+ jbyteArray jDataInfo = (jbyteArray)env->GetObjectField(byteStringObj, field_data);
+ jlong jDataLength = env->GetLongField(byteStringObj, field_length);
+
+ jbyte *byteStringData = env->GetByteArrayElements(jDataInfo, NULL);
+
+ RCSByteString byteString((uint8_t *)byteStringData, (size_t)jDataLength);
+
+ env->ReleaseByteArrayElements(jDataInfo, (jbyte*) byteStringData, JNI_ABORT);
+ env->DeleteGlobalRef(g_cls_RCSByteString);
+
+ return byteString;
+ }
+
+ template< typename ENV >
+ inline jobject newRCSByteStringObject(ENV* env, const RCSByteString& value)
+ {
+ jsize jSize = (jsize)value.size();
+
+ jbyteArray jData = env->NewByteArray(jSize);
+
+ std::vector<uint8_t> byteString = value.getByteString();
+
+ env->SetByteArrayRegion(jData, 0, jSize, (const jbyte*)&byteString[0]);
+
+ jclass g_cls_RCSByteString = env->FindClassAsGlobalRef(CLS_NAME_RESOURCEBYTESTRING);
+ jmethodID g_ctor_RCSByteString = env->GetConstructorID(g_cls_RCSByteString, "([BJ)V");
+
+ EXPECT_RET(g_ctor_RCSByteString, "g_ctor_RCSByteString is null!", { });
+
+ jobject jObj = (jobject)env->NewObject(g_cls_RCSByteString, g_ctor_RCSByteString, jData,
+ (jlong)jSize);
+
+ EXPECT_RET(jObj, "jObj is null!", { });
+
+ return jObj;
+ }
+
+ template<>
+ struct JniTypeTrait< RCSByteString >: public ObjectType
+ {
+ static decltype(&invoke_ByteString_byteStringValue<JNIEnvWrapper>) converter;
+
+ static decltype(&newRCSByteStringObject<JNIEnvWrapper>) newObjectFunc;
+
+ static constexpr char className[] = CLS_NAME_RESOURCEBYTESTRING;
+ };
+ constexpr char JniTypeTrait< RCSByteString >::className[];
+ decltype(&invoke_ByteString_byteStringValue<JNIEnvWrapper>) JniTypeTrait< RCSByteString >::converter =
+ &invoke_ByteString_byteStringValue<JNIEnvWrapper>;
+
+ decltype(&newRCSByteStringObject<JNIEnvWrapper>) JniTypeTrait< RCSByteString >::newObjectFunc =
+ &newRCSByteStringObject<JNIEnvWrapper>;
template<>
struct JniTypeTrait< RCSResourceAttributes >: public ObjectType
case RCSResourceAttributes::TypeId::STRING:
return toNativeValue< std::string >(env, val, depth);
+ case RCSResourceAttributes::TypeId::BYTESTRING:
+ return toNativeValue< RCSByteString >(env, val, depth);
+
case RCSResourceAttributes::TypeId::ATTRIBUTES:
return toNativeValue< RCSResourceAttributes >(env, val, depth);
}
value.get< typename SeqType< DEPTH, std::string >::type >(),
Int2Type< DEPTH >{ });
+ case RCSResourceAttributes::TypeId::BYTESTRING:
+ return createJavaObject(env,
+ value.get< typename SeqType< DEPTH, RCSByteString >::type >(),
+ Int2Type< DEPTH > { });
+
case RCSResourceAttributes::TypeId::ATTRIBUTES:
return createJavaObject(env,
value.get< typename SeqType< DEPTH, RCSResourceAttributes >::type >(),
if (env->IsSameObject(g_obj_TypeId_Integer, typeIdObj)) return TypeId::INT;
if (env->IsSameObject(g_obj_TypeId_Double, typeIdObj)) return TypeId::DOUBLE;
if (env->IsSameObject(g_obj_TypeId_String, typeIdObj)) return TypeId::STRING;
+ if (env->IsSameObject(g_obj_TypeId_ByteString, typeIdObj)) return TypeId::BYTESTRING;
if (env->IsSameObject(g_obj_TypeId_Attributes, typeIdObj)) return TypeId::ATTRIBUTES;
if (env->IsSameObject(g_obj_TypeId_Array, typeIdObj)) return TypeId::VECTOR;
g_obj_TypeId_Integer = getTypeIdObj(env, "INTEGER");
g_obj_TypeId_Double = getTypeIdObj(env, "DOUBLE");
g_obj_TypeId_String = getTypeIdObj(env, "STRING");
+ g_obj_TypeId_ByteString = getTypeIdObj(env, "BYTESTRING");
g_obj_TypeId_Attributes = getTypeIdObj(env, "ATTRIBUTES");
g_obj_TypeId_Array = getTypeIdObj(env, "ARRAY");
}
env->DeleteGlobalRef(g_obj_TypeId_Integer);
env->DeleteGlobalRef(g_obj_TypeId_Double);
env->DeleteGlobalRef(g_obj_TypeId_String);
+ env->DeleteGlobalRef(g_obj_TypeId_ByteString);
env->DeleteGlobalRef(g_obj_TypeId_Attributes);
env->DeleteGlobalRef(g_obj_TypeId_Array);
}
return ret;
}
- jobjectArray NewObjectArray(jsize len, jclass cls, jobject init)
+ jbyteArray NewByteArray(jsize len)
+ {
+ auto ret = m_env->NewByteArray(len);
+ if (m_env->ExceptionCheck()) throw JavaException();
+ return ret;
+ }
+
+ jobjectArray NewObjectArray(jsize len, jclass cls, jobject init)
{
auto ret = m_env->NewObjectArray(len, cls, init);
if (m_env->ExceptionCheck()) throw JavaException();
return ret;
}
+ jbyte *GetByteArrayElements(jbyteArray array, jboolean *value)
+ {
+ auto ret = m_env->GetByteArrayElements(array, value);
+ if (m_env->ExceptionCheck()) throw JavaException();
+ return ret;
+ }
+
void SetObjectArrayElement(jobjectArray array, jsize index, jobject val)
{
m_env->SetObjectArrayElement(array, index, val);
if (m_env->ExceptionCheck()) throw JavaException();
}
+ void SetByteArrayRegion(jbyteArray array, jsize start, jsize len, const jbyte *buf)
+ {
+ m_env->SetByteArrayRegion(array, start, len, buf);
+ if (m_env->ExceptionCheck()) throw JavaException();
+ }
+
void* GetPrimitiveArrayCritical(jarray array, jboolean* isCopy)
{
auto ret = m_env->GetPrimitiveArrayCritical(array, isCopy);
if (m_env->ExceptionCheck()) throw JavaException();
}
- void ThrowNew(jclass cls, const char* msg) {
+ void ReleaseByteArrayElements(jbyteArray array, jbyte* byteArray, int mode)
+ {
+ m_env->ReleaseByteArrayElements(array, byteArray, mode);
+ if (m_env->ExceptionCheck()) throw JavaException();
+ }
+
+ void ThrowNew(jclass cls, const char* msg)
+ {
m_env->ThrowNew(cls, msg);
throw JavaException();
}
#define CLS_NAME_RESOURCEATTRIBUTES PACKAGE_NAME "/RcsResourceAttributes"
#define CLS_NAME_REMOTERESOURCEOBJECT PACKAGE_NAME "/client/RcsRemoteResourceObject"
+#define CLS_NAME_RESOURCEBYTESTRING PACKAGE_NAME "/RcsByteString"
#define CLS_NAME_OBJECT "java/lang/Object"
#define CLS_NAME_STRING "java/lang/String"