Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to use this for binary file uploads #881

Closed
tilakhere opened this issue Dec 17, 2017 · 5 comments
Closed

How to use this for binary file uploads #881

tilakhere opened this issue Dec 17, 2017 · 5 comments
Labels
kind: question solution: proposed fix a fix for the issue has been proposed and waits for confirmation

Comments

@tilakhere
Copy link

tilakhere commented Dec 17, 2017

untitled.zip

  • What is the issue you have?
    I am writing a code where the front end sends a file within a json object
    I have file in js["body"] the contents of the file.
    I also have the size of the file in js["size"]
    where js is the json object as

JSON OBJECT IS {
"body": "-\u001e_}x#\u0000\u0000\u0000#B����!",
"filename": "untitled.txt",
"size": 16
}

body is the file content and size is the size of the file in bytes

On printing js["body"] the file contents are correct.
Now I need to send this file via socket to another service.
For that I tried stringifying it, memcpy into char* buffer, memcpy in void* buffer but none seems to work correctly.

What is the correct method to copy js["body"] byte by byte into a char*, so that I may send it over a socket to another service which saves it as a actual file.

How do I do that?

sample code I am using

cout<<"File content is "<<js["body"]<<endl;
cout<<"File content as string is "<<js["body"].get<string>()<<endl;
void *file1 = (unsigned char*)malloc(16);
memcpy(file1, &js["body"], 16);
cout<<"File content as char buffer is "<<file1<<endl;

Output I am getting is

File content is "-\u001e_}x#\u0000\u0000\u0000#B����!"
File content as string is -�_}x##B����!
File content as char buffer is 0x1e4cfc0

Only the first output is correct in this case which I am getting by directly printing js["body"]

Any pointers would be highly appreciated.

ENVIRONMENT
OS : ubuntu 16.04
COMPILER : g++ (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
ATTACHED is the binary file within the zip which I am uploading.

Thanks

@nlohmann
Copy link
Owner

I assume that your file content is stored as a string in the JSON object. The library stores it as std::string, and you can access it by reference like

std::string &ref = js["body"].get_ref<std::string&>();

Then you can do whatever you would have done with a std::string.

However, please note the library assumes UTF-8 encoded strings. If the parser or serializer encounters invalid UTF-8 byte sequences, it will throw an exception.

@nlohmann nlohmann added kind: question solution: proposed fix a fix for the issue has been proposed and waits for confirmation labels Dec 17, 2017
@tilakhere
Copy link
Author

I did that but as you see
cout<<"File content is "<<js["body"]<<endl;
prints

File content is "-\u001e_}x#\u0000\u0000\u0000#B����!"

and
cout<<"File content as string is "<<js["body"].get<string>()<<endl;
prints

File content as string is -�_}x##B����!

which are different.

Do I need to send my binary file as a base64 encoded string from the front end to save it properly?

@nlohmann
Copy link
Owner

Oh, now I understand.

If you pass a JSON value to a stream like std::cout << val;, then it is serialized a JSON text representation, calling the dump() function. The JSON standard then requires that, certain control characters must be escaped. This explains the \u0000 entries.

So std::cout << val; is equivalent to std::cout << val.dump();. If you just want the string, use std::cout << val.get<std::string>();.

@nlohmann
Copy link
Owner

Any news on this?

@tilakhere
Copy link
Author

tilakhere commented Dec 21, 2017

Hey sorry forgot to update this.....figured it out....to enable file uploads and downloads had to convert binary file into base64 encoded string before sending the json from frontend...and back to base64 decode when user wants to download it again

Marking it as close

Thanks for your help

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind: question solution: proposed fix a fix for the issue has been proposed and waits for confirmation
Projects
None yet
Development

No branches or pull requests

2 participants