PageRenderTime 47ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/jni/libmstring/mstring.cpp

https://github.com/k3170makan/mercury-agent
C++ | 172 lines | 92 code | 35 blank | 45 comment | 17 complexity | 9a80c269f9f46a5cc7aad28c8751db43 MD5 | raw file
Possible License(s): BSD-3-Clause-No-Nuclear-License-2014
  1. /*
  2. * mstring.cpp
  3. * Buffered String Search.
  4. *
  5. * Written by Rodrigo Chiossi <r.chiossi@samsung.com>
  6. *
  7. *
  8. * This is a native implementation of a buffered string search algorithm,
  9. * optimized to reduce the overhead of the JNI call.
  10. *
  11. * The number of strings found is usually very big which makes it impossible
  12. * return a list of jstrings objects back to java (due to the restriction of
  13. * 512 local references) without paying the price of DeleteLocalRef().
  14. *
  15. * This implementation creates a single Java string with all strings separated
  16. * by a new line. An actual list can be then retrieved in Java using
  17. * split("\n"), or any method alike.
  18. *
  19. * The chunk size was obtained by profiling the execution time over several
  20. * classes.dex extracted from apks. The best observed value was 16k.
  21. */
  22. #include <jni.h>
  23. #include <string.h>
  24. #include <android/log.h>
  25. #include <stdlib.h>
  26. #include <stdio.h>
  27. #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR , "mercury-native", __VA_ARGS__)
  28. #ifdef __cplusplus
  29. extern "C" {
  30. #endif
  31. #define CHUNK_SIZE 16348
  32. #define LIST_START_SIZE 4096
  33. #define MAX_STR_SIZE 4096
  34. #define MIN_STR_SIZE 4
  35. char read_buffer[CHUNK_SIZE];
  36. unsigned bytes_in_buffer;
  37. unsigned read_ptr;
  38. unsigned eof;
  39. char* string_list = NULL;
  40. /*
  41. * Function: Read a new chunk from the target file
  42. * Parameters: file - open file descriptor to the target
  43. */
  44. void reset_buffer(FILE* file) {
  45. bytes_in_buffer = fread(read_buffer,1,CHUNK_SIZE,file);
  46. read_ptr = 0;
  47. eof = 0;
  48. }
  49. /*
  50. * Function: Read a byte from the file buffer
  51. * Parameters: file - open file descriptor to the target
  52. * Return: Byte read
  53. */
  54. char read_char(FILE* file) {
  55. if (bytes_in_buffer != CHUNK_SIZE && read_ptr >= bytes_in_buffer) {
  56. eof = 1;
  57. return 0xff;
  58. }
  59. if (read_ptr == CHUNK_SIZE) {
  60. reset_buffer(file);
  61. }
  62. return read_buffer[read_ptr++];
  63. }
  64. /*
  65. * Function: Extract Strings from file
  66. * Parameters: path - taget file
  67. * Return: Number of uris found
  68. */
  69. int strings_file(const char* path) {
  70. FILE* file = fopen(path,"r");
  71. unsigned max_size = LIST_START_SIZE;
  72. unsigned cur_size = 0;
  73. char buffer[MAX_STR_SIZE];
  74. char* next_str;
  75. unsigned char c_byte;
  76. unsigned length;
  77. unsigned num_strings = 0;
  78. if (file == NULL) {
  79. LOGE("Error opening file : %s",path);
  80. return -1;
  81. }
  82. string_list = (char*) malloc(sizeof(char)*max_size);
  83. reset_buffer(file);
  84. c_byte = read_char(file);
  85. length = 0;
  86. while (!eof) {
  87. /* check if character is printable */
  88. while (0x20 <= c_byte && c_byte <= 0x7E && length < MAX_STR_SIZE - 1 && !eof) {
  89. buffer[length++] = c_byte;
  90. c_byte = read_char(file);
  91. }
  92. if (length >= MIN_STR_SIZE) {
  93. /* grow string list buffer if needed */
  94. if (cur_size+length >= max_size) {
  95. string_list = (char*) realloc(string_list, sizeof(char)*max_size*2);
  96. if (string_list == NULL) {
  97. LOGE("Error: Failed to allocate memory!");
  98. return -1;
  99. }
  100. max_size *= 2;
  101. }
  102. next_str = &string_list[cur_size];
  103. strncpy(next_str,buffer,length);
  104. next_str[length] = '\n';
  105. cur_size+=length+1;
  106. num_strings++;
  107. }
  108. /* start a new string */
  109. length = 0;
  110. c_byte = read_char(file);
  111. }
  112. string_list[cur_size] = '\0';
  113. fclose(file);
  114. return num_strings;
  115. }
  116. /*
  117. * Class: com_mwr_droidhg_util_Strings
  118. * Method: strings
  119. * Signature: (Ljava/lang/String;)[Ljava/lang/String;
  120. */
  121. JNIEXPORT jstring JNICALL Java_com_mwr_droidhg_util_Strings_get
  122. (JNIEnv *env, jclass obj, jstring jpath)
  123. {
  124. const char *path = env->GetStringUTFChars(jpath, 0);
  125. int num;
  126. /* Get string list */
  127. num = strings_file(path);
  128. if (num <= 0) return NULL;
  129. /* Convert to a Java String */
  130. env->ReleaseStringUTFChars(jpath, path);
  131. jstring ret = env->NewStringUTF(string_list);
  132. free(string_list);
  133. return ret;
  134. }
  135. #ifdef __cplusplus
  136. }
  137. #endif