I have the following native code that copies from a file into a buffer and then copies the
contents of that buffer into a jbytearray.
JNIEXPORT void JNICALL Java_com_test(JNIEnv * env, jobject){
int file_descriptor = 100;
JNIEnv * jni_env = env;
FILE* file = fdopen(file_descriptor, "r");
unsigned char* buffer;
int size_of_file = 1000000;
fread(buffer, 1, static_cast<size_t>(size_of_file), file);
imageArr = static_cast<jbyteArray>(jni_env->NewByteArray(static_cast<jsize> (size_of_file)));
jni_env->SetByteArrayRegion (imageArr, 0, static_cast<jsize>
(size_of_file ), (jbyte*)buffer);
}
As this code runs in a loop, I would like to optimize this as much as possible. Is there any way to directly read from the file to the jbyteArray? I am aware jbyteArray is a pointer to a struct. Is there any way to set the fields of this struct directly instead of using the setByteArrayRegion() function?
If not, is there any other function that I can use to read from a file to a jbytearray?
In short, no. You can probably do it, but it probably wont be much faster and if something with the implementation changed in the JVM your code would stop working. You are dealing with file I/O so I don't think SetByteArrayRegion is your real bottleneck here.
Related
I'm in need of reading base64 encoded PNG image, stored as char array/null terminated string, and I'm stuck. Here is what I have found out for now:
Libpng is capable of changing it's workings, by using png_set_*_fn().
reading functions must have prototype alike this one : void user_read_data(png_structp png_ptr, png_bytep data, size_t length); and must check for EOF errors.
Original read function (which reads from png file directly) calls an fread function and dumps everything to memory pointed by data. I have no idea how libpng knows about image size.
So, here is my implementation of read function
size_t base64_to_PNG(const char *const base64_png, png_bytep out)
{
size_t encoded_size, decoded_count;
size_t decoded_size = base64_decoded_block_size(base64_png, &encoded_size);
decoded_count = base64_decode_block(base64_png, encoded_size, (char*)out);
if(decoded_count != decoded_size)
return 0;
return decoded_size;
}
void my_read_png_from_data_uri(png_structp png_ptr, png_bytep data, size_t length)
{
const char *base64_encoded_png = NULL;
size_t PNG_bytes_len;
if(png_ptr == NULL)
return;
base64_encoded_png = png_get_io_ptr(png_ptr);
PNG_bytes_len = base64_to_PNG(base64_encoded_png, data);
if(PNG_bytes_len != length)
png_error(png_ptr, "Error occured during decoding of the image data");
}
I do believe that information about the decoded image size is lost, and I'm going straight to the segfault with that, as I'll be writing to some random address, but I have no idea how to tell libpng how much memory I need. Can you please help me with that?
I`m writing the VB.net and need to call API(c language DLL)
My test sample code as follow
//Read Source File
char *SourceFilePath = "C:\\Docs\\Scandi\\attach\\verifyTest\\center.xml";
FILE *sourcefile= fopen(SourceFilePath, "rb");
if (!sourcefile)
{
printf("Error=%s\n", *SourceFilePath);
return;
}
fseek(sourcefile,0,SEEK_END);
long src_ch_len = ftell(sourcefile);
rewind(sourcefile);
unsigned char *src_ch =(unsigned char*)malloc(sizeof(char)*src_ch_len);
result = fread(src_ch,1,src_ch_len,sourcefile);
if(result!=src_ch_len)
{
printf("Reading Error=%s\n", *sourcefile);
return;
}
fclose(sourcefile);
//Read Data File
//Skip...
rc = BasicVerify(algorithm, data, dataLen, key, signature, signatureLen);
API Function definition
unsigned long verify(unsigned long algorithm, unsigned char *data, int dataLen,unsigned char *signature, int signatureLen, char *cerFile)
How to convert fopen(SourceFilePath, "rb") and fread(src_ch,1,src_ch_len,sourcefile) to VB.NET
Thanks
The analogue to fopen using the modes "rb" in VB .NET appears to be the FileStream class using the FileAccess.Read mode. From there you can use the FileStream.Read method as an analogue for fread. For example:
dim sourceFile as FileStream
sourceFile = new FileStream("C:\\Docs\\Scandi\\attach\\verifyTest\\center.xml", FileAccess.Read)
dim result as Integer
result = sourceFile.Read(array, 0, array.Length)
However, it seems from the fseek followed by ftell in your C code, you want to read the entire file into memory. This is often frowned upon since a file could be many gigabytes in size. If you really want to do that, use the File.ReadAllBytes method, for example:
dim src_ch as Byte()
src_ch = File.ReadAllBytes("C:\\Docs\\Scandi\\attach\\verifyTest\\center.xml")
I'm currently trying to write a general function to measure the time another function func needs for execution. I'm able to calculate the time with <time.h> and so on.
My approach looks something like this:
void measure_time(void *(func)(), unsigned loops);
For now it is enough if the result is just printed within measure_time (later I could let measure_time return some information).
I'm able to calculate the execution time and so on (with <time.h>) but at the moment my problem is that I want this to be a general function and it should be able to take all sort of functions 'func' with different return types and different argument sizes/types.
Currently I have no clue how I could manage to give measure_time the function 'func' and let it execute it with arguments I am able to specify.
For example:
int a[1000] = {15, 53, ..., 42};
void sort_something(int *a, int n_elements) { ... };
void measure_time(sort_somthing(a, 1000), 100);
This should call sort_something 100 times with the arguments "a and 1000" and measure the time needed for the execution.
I'm more than happy to give some more information if you need them.
Cheers!
LastSeconds
The general scheme should be:
void general_timer(void (*function)(void *context), void *context, int loops);
This takes a function that returns no value and takes a single void * argument for context, and passes the context. Depending on what you need to pass as context, that might be the address of a structure, or something as simple as a FILE *.
Inside the implementation:
void general_timer(void (*function)(void *context), void *context, int loops)
{
Clock clk;
clk_init(&clk);
clk_start(&clk);
for (int i = 0; i < loops; i++
(*function)(context);
clk_stop(&clk);
char buffer[32];
printf("%s seconds for %d iterations\n",
clk_elapsed_microsecs(&clk, buffer, sizeof(buffer)), loops);
}
Where the type Clock and the functions starting clk_ are parts of a high-resolution timing package, using whatever is convenient.
You could write the function call as:
function(context);
It would work exactly the same. This is the more modern style; I prefer the old-fashioned (*function)(context) call as it makes it clear that function is a function pointer, not the name of a function. YMMV.
Yes, I do have a specific implementation of such a package. However, the concept applies readily regardless of how you implement it.
You might have a function to be timed. It might use the structure:
struct TwoFiles
{
FILE *f_in;
FILE *f_out;
};
and the function might be:
void file_copier(void *ctxt)
{
struct TwoFiles *info = ctxt;
char buffer[4096];
size_t bytes;
rewind(info->f_in);
rewind(info->f_out);
while ((bytes = fread(buffer, sizeof(buffer), sizeof(char), info->f_in)) > 0)
{
if (frwite(buffer, bytes, sizeof(char), info->f_out) != bytes)
{
…report error…abandon loop…
}
}
}
and the call might be:
struct TwoFiles ctxt;
ctxt.f_in = fopen(some_file_name, "r");
ctxt.f_out = fopen(another_name, "w");
general_timer(file_copier, &ctxt, 100);
Note that to be useful, the file copier function needed to rewind the input and output file streams so that it would do work each time the general timer function calls it. That is, however, a detail for the specific task on hand.
I'm looking for a non invasive way of writing a local variable into a file to use it as a debugging mechanism. The non invasive part means that the debug code should have as little execution time as possible and should minimally interfere with the method that's being debugged.
Example:
Somewhere deep inside the code there is a method.
unsigned int method(short *frame, int length)
{
process-frame(short *frame, int length);
}
It gets called 100 times a second and I would like to print out the content of frame. Since the process is time sensitive I can't print to the terminal but will print into the file in ram. Am looking for a way to do it inside the function scope.
The best I've come so far is this. Am open for other answers with a more optimized approach
unsigned int method(short *frame, int length)
{
static FILE * rawPcmLog;
if (rawPcmLog == NULL) rawPcmLog = fopen("/tmp/rawPcm","w");
int i;
for (i=0; i<length; i++){
fwrite(frame,length, 1,rawPcmLog);
}
process-frame(short *frame, int length);
}
I have a struct which holds some ByteArray data
typedef struct {
uint32_t length;
uint8_t* bytes;
} FREByteArray;
And here I am trying to save this to a file
FREByteArray byteArray;
if((fileToWrite = fopen(filePath, "wb+")) != NULL){
fwrite(&byteArray.bytes, 1, byteArray.length, fileToWrite);
fclose(fileToWrite);
}
But this doesn't seem to be saving all of the data, the saved file size is 16KB, actual data is about 32KB. I think fwrite is not able to write the whole bytearray to the file.
Is this the correct way to save the ByteArray? Is there a limit how much fwrite can handle in a single call?
Replace
fwrite(&byteArray.bytes, 1, byteArray.length, fileToWrite);
with
fwrite(byteArray.bytes, 1, byteArray.length, fileToWrite);
And as pointed out by #Sourav Ghosh make sure that byteArray.bytes is pointing to the correct source location.