C sharp to Java : MemoryStream and BinaryReader - java

I am working on a network device and catching packets from it over network as UDP. In some parts i need to parse a byte array (packetBuffer) to get session header but i couldn't. I found a part of code but unfortunatelly it is C sharp and i also couldn't convert it to java. It is like below;
MemoryStream memstream = new MemoryStream(packetbuffer);
BinaryReader binreader = new BinaryReader(memstream);
byte[] sessionheader = binreader.ReadBytes(4);
ushort ROapdu_type = correctendianshortus(binreader.ReadUInt16());
I need to find what MemoryStream and BinaryReader in C# equivalent in Java is.
I appreciate for all your helps.

you can use getData to get byte[], then extract 4 bytes from the result array and use ByteBuffer.wrap(result4Byte).getInt() to convert it into int(you may need to use order to set byte ordering to little/big endian)

Related

Equivalent Java function Base64.encode(byte, 0) in Swift

I have the following function in Java(write inside an Android app)
Bitmap bm = BitmapFactory.decodeFile(stringPath);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bm.compress(Bitmap.CompressFormat.JPEG, 100, baos); // bm is the bitmap object era quality 100
byte[] byteData = baos.toByteArray();
byte[] newB = Base64.encode(byteData,0);
It get an Image file and convert it to a byte array.
I need that to work on Swift.
I was able to convert the byteData to Int8, the equivalent of byte array in Swift.
I use the code below:
let filename = "RES4010110001"
let test_image:UIImage = UIImage(named: filename)!
let dataImage = UIImageJPEGRepresentation(test_image, 1)! as Data
var bytes: [Int8] = dataImage.map{Int8(bitPattern: $0)}
When I print this data using print(bytes) I got the same results on iOS and Android when I compare the "byteData" from Android and "bytes" from iOS
But I don't know what is the Java equivalent function below on Swift
Base64.encode(byteData,0);
How can I create an equivalent function on Swift of the function above?
For me, it appears that this function is encoding a byte array. But I have no idea of how I can encode a Int8 Array.
I said Int8 because for me, Int8 is the Swift equivalent of byte type in Java.
edit: I want to encode a Int8 array, I guess this is what the Java function (the function in the post title) is doing inside the Android app.
You can use base64EncodedData to encode your Data to get an encoded Data, rather than working with [Int8].
The Java code passes 0 (DEFAULT) as the flags. According to the docs, this means it's compliant with RFC 2045. RFC 2045 says that lines should be no more than 76 characters, so we should pass lineLength76Characters. RFC 2045 also requires CRLF as line endings, but base64EncodedData seems to insert them automatically even if we don't pass endLineWithCarriageReturn and endLineWithLineFeed.
let filename = "RES4010110001"
if let testImage = UIImage(named: filename),
let dataImage = testImage.jpegData(compressionQuality: 1) {
let encodedData = dataImage.base64EncodedData(options: [.lineLength76Characters])
} else {
// failed to get the UIImage, or the JPEG data, handle the error here...
}
I suggest that you do not work with [Int8] here. The byte[]s in the Java code are clearly not just "lists of numbers between -128 and 127". They represent data buffers, and those are represented by the Data struct in Swift. Don't worry, Both Data and [Int8] share a very similar set of protocol conformances, like MutableCollection, RangeReplaceableCollection, RandomAccessCollection etc. You can do almost everything you can do to an Int8 array, to a Data.
I was able to find an definite answer using part of the answer created by
#Sweeper and from another answer published here on Stackoverflow
let filename = "RES4010110001"
let test_image:UIImage = UIImage(named: filename)!
let dataImage = UIImageJPEGRepresentation(test_image, 1)! as Data // use apenas este que é correto, o galvez usa jpg no android
let dataImageStringBase64:String = dataImage.base64EncodedString(options: [.lineLength76Characters])
let byteArray = [UInt8](dataImageStringBase64.utf8)
The answer posted by #Sweeper just miss this line
let byteArray = [UInt8](dataImageStringBase64.utf8)
This last line of code made the code works perfectly for me.

Java: How to restore string data which was compressed with python's zlib encoder

I send data through the socket from python to java.
So on the python 2.7 side I have:
s = "this is test str"
compressed = s.encode('zlib')
push_to_tcp_socket(compressed)
So I need to restore initial string on the java side. How I could do that?
You will need to send gthe length of the string, or close the connection so you know where the last byte is.
The most likely class to help you is the DeflatorInputStream which youc an use once the bytes have been read. This is a bare wrapper for the zlib class. I haven't tested it works with python but it's you best option.
You can try other compressions like Snappy or LZ4 which have cross platform support.
I assumed you already know the networking part on Java. You can use Inflater class to get your string like in javadocs
// Decompress the bytes
Inflater decompresser = new Inflater();
decompresser.setInput(output, 0, compressedDataLength);
byte[] result = new byte[100];
int resultLength = decompresser.inflate(result);
decompresser.end();
//Then create string in java i assumed you are using python 2 and string is ASCII
String str = new String(result,"US-ASCII")

Big Endian or Small Endian while storing the data into Cassandra?

I need to write Byte Array value into Cassandra using Java code. Then I will be having my C++ program to read that same Byte Array data from Cassandra.
That Byte Array is made up of three Byte Arrays as described below -
short schemaId = 32767;
long lastModifiedDate = "1379811105109L";
byte[] avroBinaryValue = os.toByteArray();
Now, I will write schemaId , lastModifiedDate and avroBinaryValue together into a single Byte Array and that resulting Byte Array, I will write back into Cassandra and then I will be having my C++ program which will retrieve that Byte Array data from Cassandra and then deserialize it to extract schemaId , lastModifiedDate and avroBinaryValue from it.
So now I am confuse whether I should be using Big Endian here in my Java code while writing to Cassandra? Or small Endian Byte Order here while storing the data into Cassandra?
Below is the code, I have got so far in Java which will serialize everything into a Single Byte Array...
public static void main(String[] args) throws Exception {
String os = "whatever os is";
byte[] avroBinaryValue = os.getBytes();
long lastModifiedDate = 1379811105109L;
short schemaId = 32767;
ByteArrayOutputStream byteOsTest = new ByteArrayOutputStream();
DataOutputStream outTest = new DataOutputStream(byteOsTest);
outTest.writeShort(schemaId); // first write schemaId
outTest.writeLong(lastModifiedDate); // second lastModifiedDate
outTest.writeInt(avroBinaryValue.length); // then attributeLength
outTest.write(avroBinaryValue); // then its value
byte[] allWrittenBytesTest = byteOsTest.toByteArray();
// write this allWrittenBytesTest into Cassandra
// now deserialize it and extract everything from it
DataInputStream inTest = new DataInputStream(new ByteArrayInputStream(allWrittenBytesTest));
short schemaIdTest = inTest.readShort();
long lastModifiedDateTest = inTest.readLong();
int sizeAvroTest = inTest.readInt();
byte[] avroBinaryValue1 = new byte[sizeAvroTest];
inTest.read(avroBinaryValue1, 0, sizeAvroTest);
System.out.println(schemaIdTest);
System.out.println(lastModifiedDateTest);
System.out.println(new String(avroBinaryValue1));
}
And I am also trying to see whether there is any efficient or proper way of doing this in Java as I need to retrieve this data from Cassandra using C++ program so I don't want to have any problem on C++ side as well.. So I am trying to make sure when I am writing this data to Cassandra from Java side, everything looks good..
Right now, for testing what I was doing is- I was writing this Byte Array into a file from Java program and I am reading that same file using C++ program and then deserializing that Byte Array accordingly..
I hope my question is clear enough.. Can anybody help me with this?
Why not use a serailization framwework like google protobuf (http://code.google.com/p/protobuf/) this way you need not worry about the low level details and read and write back from any language and tools

Protocol Buffer: From Java to Objective-C using byte[]

I am currently using google's protocol buffers. It works painlessly between Java and C#, however I am running into problems trying to achieve the same use with Obj-c.
The Java WS returns a byte[]. The code that uses the protocol buffer API is simple enough:
productGroup.toByteArray();
I am able to recreate the object with Skeet's C# port, using:
byte[] result = searchWebService.SearchProductsProtocolBuffer(search);
ProductProtoGroup products = ProductProtoGroup.ParseFrom(result);
However, on the obj-c side, I am struggling to work with the return value.
The NSString I receive from the same web service RPC is this:
CmYKEzgwMDAwMUFELTEzMjUyNzk5MTQySUZPT0QgJiBCRV...
I'm not quite sure what to do with this, because I don't know what it is, save it was generated from an array of bytes. I tried parsing it directly to NSData using
NSData* data = [returnValue dataUsingEncoding:NSUTF8StringEncoding];
but on [ProductProtoGroup parseFromData:data];, I get an InvalidProtocolBuffer
I've checked on the Java side what byte string/hexadecimal representations of the original byte[], and it doesn't match the string I receive from the ws.
Hexadecimal is 0-F. Perhaps each byte was converted to a char? No, that doesn't match.
Any help would be appreciated.
Dane
With a fresher mind and some helpful comments, I finally got it.
I was wondering how the web service automagically sent a byte[] in Java, then reconstructed it in C# later, and also how to store this message later.
Turns out the string,
CmYKEzgwMDAwMUFELTEzMjUyNzk5MTQySUZPT0QgJiBCRV...
was indeed what was being sent in the soap envelopes. So inbetween creation of a byte[] in Java and transmission, something was happening. Looking at the message handler in C#,
[System.Web.Services.Protocols.SoapDocumentMethodAttribute("",
RequestNamespace="x", ResponseNamespace="x",
Use=System.Web.Services.Description.SoapBindingUse.Literal,
ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]
[return: System.Xml.Serialization.XmlElementAttribute("return",
Form=System.Xml.Schema.XmlSchemaForm.Unqualified,
DataType="base64Binary", IsNullable=true)]
public byte[] searchProductProtocolBuffer([System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)] string arg0)
{
object[] results = this.Invoke("searchProductProtocolBuffer", new object[] {
arg0});
return ((byte[])(results[0]));
}
So base64Binary!, which I admittedly am meeting for the first time. Poking around, Skeet says it is the safest way:
How can I safely convert a byte array into a string and back?
So, knowing the encoding, the solution becomes straight forward. Using the algorithm presented in an answer to this question: How do I do base64 encoding on iphone-sdk?, my final code becomes:
NSString* returnValue = [WebServiceUtil processStringReturnValue:value];
NSData* data = [Encoding base64DataFromString:returnValue];
ProductProtoGroup* products = [ProductProtoGroup parseFromData:data];
I know very little about Objective C, but an NSString is no byte array. Have you tried converting the NSString to char* using -[NSString UTF8String]?

transfer jpeg from c++ to android (java)

I am struggling with the transfer of a simple jpeg file inside an ID3v2 tag from c++ over a TCP socket to java (Android). The library "taglib" offers to extract this file and I am able to save the jpeg as a new file.
The send function looks like this
char *parameter_full = new char[f3->picture().size()+2];
sprintf(parameter_full,"%s\n\0",f3->picture().data());
// send
result = send(c,parameter_full,strlen(parameter_full),0);
delete[] parameter_full;
where
f3->picture().data() returns a pointer to the internal data structure (it returns char*) and
f3->picture().size() returns the size of the array.
Then Android receives it with
String imageString = inFromServer.readLine();
byte[] imageBytes = imageString.getBytes();
Bitmap cover = BitmapFactory.decodeByteArray(imageBytes,0,imageBytes.length);
But somehow decodeByteArray always returns null. My idea is that Java doesn't receive the image correctly because imageString only consists of 4 characters...while the extracted jpeg file has a size of 12.7 KB.
But what has gone wrong?
Martin
You shouldn't use string functions on byte data because 0 values are taken as string terminators. Try looking into memcpy on the C++ side if you need to copy the char* and also the byte[] read functions for InputStream on the Java side.

Categories

Resources