AssetManager and native code - android-ndk

I have a config.txt file. The file is not compressed during the apk build using the nocompress extension="txt" option. Then I'm openning in my java code asset manager and passing it to the native function. Finally I'm opening a File* using the below code.
The problem is that when calling fgets(line, 32, file) - where line is char * - the content of line is not what is the first line of the file.
AAssetManager* mgr = AAssetManager_fromJava(env, assetManager);
if(NULL == mgr) return -1;
AAsset* asset = AAssetManager_open(mgr, "config.txt", AASSET_MODE_UNKNOWN);
if (NULL == asset) {
return -1;
}
off_t start, length;
int fd = AAsset_openFileDescriptor(asset, &start, &length);
if (fd < 0)
return -1;
FILE * file = fdopen(fd, "r");

As you can see in https://code.google.com/p/java-ide-droid/source/browse/trunk/jni/aapt/jni/Package.cpp (search for "static const char* kNoCompressExt" ) txt is not in the exclude list and may be compressed!
Actually this should lead to fd beeing smaller than zero.

Related

RECOVER Pset_4 CS50 - Images recovered are incomplete

So I'm doing the CS50 pset4 recover task (where you need to search for jpg files on a memory card and whenever you find one- you open a new file and write the jpg found to the new file). I have written the code in a slightly different manner then what is told in the course but I think(hope) my logic is right. I am able to recover all 50 images but the images are incomplete and distorted. Also for some reason the 050th image is not opening. Here is my code
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
typedef uint8_t BYTE; //defining a byte = 8 bits or 8 0's or 1's
int main(int argc, char *argv[]) {
//assigning variables
int BLOCK_SIZE = 512;
BYTE buffer[BLOCK_SIZE];
int i = 0;
char* nf = malloc(sizeof(int)*3);
//checking to see a file name is given
if (argc != 2)
{
printf("Usage: ./recover IMAGE\n");
return 1;
}
//opening said file
FILE *rfile = fopen(argv[1], "r");
if(rfile == NULL)
{
printf("File '%s' does not exist\n", argv[1]);
return 1;
}
//opening a copy
FILE *c = fopen(argv[1], "r");
if(c == NULL)
{
printf("File '%s' does not exist\n", argv[1]);
return 1;
}
//checking 512 bytes again and again for orginal
while (fread (buffer, 1, BLOCK_SIZE, rfile) == BLOCK_SIZE)
{
fseek(c, ftell(rfile) , SEEK_SET); //fread (buffer, 1, BLOCK_SIZE, c);
sprintf(nf, "%03i.jpg", i); //000, 001, 002
//opening a file to write in
FILE *img = fopen(nf, "w");
if(img == NULL)
{
return 1;
}
//Is it a jpeg!?
if (buffer[0]==0xff && buffer[1]==0xd8 && buffer[2]==0xff && (buffer[3] & 0xf0) == 0xe0)
{
//writing the img in a file called img
fwrite(buffer, 512, 1, img);
fwrite(c, BLOCK_SIZE, 2048, img);
i++; //making sure a new file is opened next time
}
fclose(img);
}
fclose(c);
fclose(rfile);
free(nf); }

CS50 Recover runs and recovers all files except the first one

My question is regarding the Recover assignment as part of CS50.
The code is running (finally) and it produces 50 JPEG files, and most of them are the correct images, except the first file is not an image, therefore it doesn't pass check50.
I have spent a long time trying to figure out what the problem is but I cannot pinpoint it so I am hoping someone might be able to help me out so I can move on.
Thanks in advance! Here is my code:
int main(int argc, char *argv[])
{
// ensure proper usage
if (argc != 2)
{
fprintf(stderr, "Usage: Name of Memory Card File\n");
return 1;
}
char *readfile = argv[1];
// open memory card file
FILE *card_ptr = fopen(readfile, "r");
if (card_ptr == NULL)
{
fprintf(stderr, "Could not open %s.\n", readfile);
return 2;
}
//Declare a buffer to read into
unsigned char *buffer = malloc(512);
//to check if we have already found a file
bool (jpgAlreadyNew) = false;
//declare counter for the number of files found and a file pointer
int filenumber = 0;
FILE *new_jpg_ptr = NULL;
char filename[8];
//read in bytes until reach EOF
while (fread(buffer, 1, 512, card_ptr) != 0x00)
{
//if we reach the header pattern of bytes
if (buffer [0] == 0xff && buffer [1] == 0xd8 && buffer [2] == 0xff && (buffer [3] & 0xf0) == 0xe0)
{
//if there is not already a JPEG file found
if (!jpgAlreadyNew)
{
//change the bool value
(jpgAlreadyNew) = true;
//open new file
sprintf(filename, "%03i.jpg", filenumber);
new_jpg_ptr = fopen(filename, "w");
if (new_jpg_ptr == NULL)
{
return 3;
}
//add to counter of files found
filenumber++;
//write files from buffer into new img file
fwrite(buffer, 1, 512, new_jpg_ptr);
}
//if there is already a JPEG file found
if (jpgAlreadyNew)
{
//close the previous file which would now be complete
fclose(new_jpg_ptr);
//open new file
sprintf(filename, "%03i.jpg", filenumber);
new_jpg_ptr = fopen(filename, "w");
if (new_jpg_ptr == NULL)
{
return 4;
}
//add to counter of files found
filenumber++;
//write files from buffer into new img file
fwrite(buffer, 1, 512, new_jpg_ptr);
}
}
// else if we do not see pattern of header bytes
else
{
//if already found a jpg file which is open then write the bytes to that file
if (jpgAlreadyNew)
{
fwrite(buffer, 1, 512, new_jpg_ptr);
}
//if no file found yet, discard and move on
if (!jpgAlreadyNew)
{
continue;
}
}
}
//free memory
free (buffer);
//close pointers and end program successfully
fclose(card_ptr);
fclose(new_jpg_ptr);
return 0;
}
Let's walk through the program starting with finding the first jpeg signature:
This if (!jpgAlreadyNew) evaluates to true, so it enters the if block; the first thing it does is (jpgAlreadyNew) = true;. When it is done creating the file and writing the first block, what happens next? This if (jpgAlreadyNew). Which also evaluates to true. So it closes 000.jpg and moves along.
Since jpgAlreadyNew is a boolean, an if {} else {} construct would suffice.

Unable to open renamed image

I am having a rather strange problem.
I'm trying to open the last modified image with :
std::string exec(string cmd) {
FILE* pipe = popen(cmd.c_str(), "r");
if (!pipe) return "ERROR";
char buffer[128];
std::string result = "";
if(fgets(buffer, 128, pipe) != NULL)
result = buffer;
pclose(pipe);
result[strlen(result.c_str()) - 1] = '\0';
return result;
}
int main(int argc, char **argv) {
string s = exec("ls ./images -1t | tail -1 &> text.txt");
Mat img = imread(s);
imshow("image", img);
waitKey(0);
return 0;
}
This piece of code works fine. But whenever I rename the file and run this code, the imshow part crashes saying the image has size 0. When I try to print the file name, I get it correct in both cases.
Why is this happening?

Error when reading from Linux FIFO

In the embedded application I'm working on we have a serial port abstraction, and I'm currently working on a simulated variant of said abstraction to use when you are not running on the 'real' hardware. I'm using FIFO files for this, as you can then plug in whathever software you want to communicate with the actual application but I'm having trouble with the "read" function, which flags that you gave it an invalid fd. Though I have used debugging tools to verify that the fd passed to it is the same as has been opened earlier so it should be valid. I cannot find any cause for this problem.
FIFO files are opened through this function:
int createOpenFifo(const std::string& path, int flags)
{
int fd = open(path.c_str(), flags);
if (fd < 0)
{
mkfifo(path.c_str(), 0777);
fd = open(path.c_str(), flags);
if (fd < 0)
{
return -1;
}
}
return fd;
}
And the FIFOs are then written to using the following function:
int write_serial(handle_t handle, size_t length, const uint8_t* pData)
{
SerialFifoData* data = static_cast<SerialFifoData*>(handle);
size_t written = 0;
while (written < length)
{
int result = write(data->writeFd, pData + written, length - written);
if (result < 0)
{
return -1;
}
written += result;
}
return 0;
}
And finally read from using this function:
int read_serial(handle_t handle, size_t buffer_size, uint8_t* pBuffer, size_t* bytes_read)
{
SerialFifoData* data = static_cast<SerialFifoData*>(handle);
int return_val = read(data->readFd, pBuffer, buffer_size);
if (return_val < 0)
{
if (errno == EAGAIN || errno == EWOULDBLOCK) // Non-blocking, no data
// which flag is raised
// varies between POSIX
// implementations
{
*bytes_read = 0;
return -2;
}
return -1;
}
*bytes_read = return_val;
return 0;
}
I have verified that each function recieves correct input, and the read and write calls are nearly identical to those used for the actual serial port code (the only difference is how the FD is extracted from the handle) where they work just fine.

Hiding a Cmd Window which is shown on using system() command.

I have created a User interface in C++\CLI application which uses a C dll for manipulating exif files. This C dll uses system() function opens cmd window and a notepad file for editing and when we close the note pad file the entered data is edited to the exif header comment. Now I have to hide this cmd window I have used "start \b" but this close the cmd window this results in editing of exif header without entering data into the note pad file.
The code for this function is as following.
FILE * file;
int a;
char QuotedPath[PATH_MAX+10];
file = fopen(TempFileName, "w");
if (file == NULL)
{
fprintf(stderr, "Can't create file '%s'\n",TempFileName);
ErrFatal("could not create temporary file");
}
fwrite(Comment, CommentSize, 1, file);
fclose(file);
fflush(stdout); // So logs are contiguous.
{
char * Editor;
Editor = getenv("EDITOR");
if (Editor == NULL)
{
#ifdef _WIN32
Editor = "notepad";
#else
Editor = "vi";
#endif
}
if (strlen(Editor) > PATH_MAX) ErrFatal("env too long");
sprintf(QuotedPath, "%s \"%s\"",Editor, TempFileName);
a = system(QuotedPath);
}
if (a != 0)
{
char message[50]= "";
strcpy(message, "Editor failed to launch");
MessageBoxA(hWnd,message,"Error : ",MB_ICONWARNING);
// perror("Editor failed to launch");
exit(-1);
}
if (hFileOpen != NULL)
{
file = fopen(TempFileName, "r");
if (file == NULL)
{
ErrFatal("could not open temp file for read");
}
// Read the file back in.
CommentSize = fread(Comment, 1, 999, file);
fclose(file);
unlink(TempFileName);
return CommentSize;
}
The best way (in my humble opinion) is to use shellexecuteEx to run the specified exe, this will return a handle to the executed process which you can then monitor and close when finished with it.
Note: I think you should consider reformatting you code blocks

Resources