Reputation: 587
I want to write a class to be used in comunicaion between Java and C++
There are a lot of discussion about Java and C++ communication. Here I'm not requesting how to communicate, I konw an i know how.
I create a
OutputStream os = socketChannel.socket().getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter( os);
BufferedWriter wr = new BufferedWriter( osw );
then I write
String data= dataArea.getText();
wr.write( dataArea.getText() );
wr.write('\0');//here is the wire with C++
wr.flush(); // flushes the stream
I send some text:
Hi this is a test
i send also
character as dollar $ ...
or other stange é*"£$%&/(()=?'^ìì[]@!<>#òùèé+*
and so on
So reading raw text send between two system i see:
00000000 48 69 20 74 68 69 73 20 69 73 20 61 20 74 65 73 Hi this is a tes
00000010 74 0A 69 20 73 65 6E 64 20 61 6C 73 6F 20 0A 63 t.i send also .c
00000020 68 61 72 61 63 74 65 72 20 61 73 20 64 6F 6C 6C haracter as doll
00000030 61 72 20 24 20 2E 2E 2E 0A 6F 72 20 6F 74 68 65 ar $ ... .or othe
00000040 72 20 73 74 61 6E 67 65 20 C3 A9 2A 22 C2 A3 24 r stange ..*"..$
00000050 25 26 2F 28 28 29 3D 3F 27 5E C3 AC C3 AC 5B 5D %&/(()=? '^....[]
00000060 40 21 3C 3E 23 C3 B2 C3 B9 C3 A8 C3 A9 2B 2A 0A @!<>#... .....+*.
00000070 61 6E 64 20 73 6F 20 6F 6E 00 and so o n.
This is near the solution.
changing CHARSET "US-ASCII" I obtain
Hi this is a test
i send also
character as dollar $ ...
or other stange é*"£$%&/(()=?'^ìì[]@!<>#òùèé+*
and so on
00000000 48 69 20 74 68 69 73 20 69 73 20 61 20 74 65 73 Hi this is a tes
00000010 74 0A 20 20 20 20 69 20 73 65 6E 64 20 61 6C 73 t. i send als
00000020 6F 20 0A 20 20 20 20 63 68 61 72 61 63 74 65 72 o . c haracter
00000030 20 61 73 20 64 6F 6C 6C 61 72 20 24 20 2E 2E 2E as doll ar $ ...
00000040 0A 20 20 20 20 6F 72 20 6F 74 68 65 72 20 73 74 . or other st
00000050 61 6E 67 65 20 3F 2A 22 3F 24 25 26 2F 28 28 29 ange ?*" ?$%&/(()
00000060 3D 3F 27 5E 3F 3F 5B 5D 40 21 3C 3E 23 3F 3F 3F =?'^??[] @!<>#???
00000070 3F 2B 2A 0A 20 20 20 20 61 6E 64 20 73 6F 20 6F ?+*. and so o
00000080 6E 00
This is near my purpose.
I need to transfer only ASCII with extended characters "è"-->E8
Then I need to put '\0' at the end of the string.
'\0' is message terminator.
Now the question: using Java i like to create a Writer or stream writer to output the specific binary data format.
At what level is correct to work with OutputStreamWriter
or BufferedWriter
and should I rewrite from scratch extend or use some library?
Are some example all around about what I like to do?
I'll do the same for input
I like to write it in this form because tomorrow when I rewrite C++ server in Java I use on the both side DataOutputStream.
Using a while
is not a nice solution I prefer a more Java integrated solution.
Upvotes: 1
Views: 2709
Reputation: 587
I have done a possible solution Based on BufferedWriter and BufferedReader, i used ISO-8859-1 that is correct ASCII extended character encoding.
OutputStream os = socketChannel.socket().getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os, "ISO-8859-1");
TBufferedWriter bw = new TBufferedWriter (osw);
bw.writeTMessageFlushing( dataArea.getText() );
InputStream is = socketChannel.socket().getInputStream();
InputStreamReader isr= new InputStreamReader(is, "ISO-8859-1") ;
TBufferedReader br= new TBufferedReader(isr);
// wait for response
String responseLine = br.readTMessage();
I have simply opened the source of BufferedWriter and BufferedReader andlooked how to obtain my interaction.
BufferedReader can not be simply extended because the use of some function.(It should be rewritten from java Boys). It extends Buffered Reader but is unuseful
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.Writer;
public class TBufferedWriter extends BufferedWriter {
public TBufferedWriter(Writer out){
super( out );
}
public TBufferedWriter(Writer out, int sz){
super( out, sz );
}
public void writeTMessage(String message) throws IOException {
synchronized (lock) {
super.write( message );
super.write('\0');
}
}
public void writeTMessageFlushing(String message) throws IOException {
synchronized (lock) {
super.write( message );
super.write('\0');
super.flush();
}
}
}
import java.io.BufferedReader;
import java.io.IOException;
import java.io.Reader;
public class TBufferedReader extends BufferedReader {
private Reader in;
private char cb[];
private int nChars, nextChar;
private static final int INVALIDATED = -2;
private static final int UNMARKED = -1;
private int markedChar = UNMARKED;
private int readAheadLimit = 0; /* Valid only when markedChar > 0 */
/** If the next character is a line feed, skip it */
private boolean skipNUL = false;
/** The skipLF flag when the mark was set */
private boolean markedSkipLF = false;
private static int defaultCharBufferSize = 8192;
private static int defaultExpectedLineLength = 80;
/**
* Creates a buffering character-input stream that uses an input buffer of
* the specified size.
*
* @param in A Reader
* @param sz Input-buffer size
*
* @exception IllegalArgumentException If sz is <= 0
*/
public TBufferedReader( Reader in, int sz ) {
super( in );
if (sz <= 0) {
throw new IllegalArgumentException( "Buffer size <= 0" );
}
this.in = in;
cb = new char[ sz ];
nextChar = nChars = 0;
}
/**
* Creates a buffering character-input stream that uses a default-sized
* input buffer.
*
* @param in A Reader
*/
public TBufferedReader( Reader in ) {
this( in, defaultCharBufferSize );
}
/** Checks to make sure that the stream has not been closed */
private void ensureOpen() throws IOException {
if (in == null) {
throw new IOException( "Stream closed" );
}
}
/**
* Fills the input buffer, taking the mark into account if it is valid.
*/
private void fill() throws IOException {
int dst;
if (markedChar <= UNMARKED) {
/* No mark */
dst = 0;
} else {
/* Marked */
int delta = nextChar - markedChar;
if (delta >= readAheadLimit) {
/* Gone past read-ahead limit: Invalidate mark */
markedChar = INVALIDATED;
readAheadLimit = 0;
dst = 0;
} else {
if (readAheadLimit <= cb.length) {
/* Shuffle in the current buffer */
System.arraycopy( cb, markedChar, cb, 0, delta );
markedChar = 0;
dst = delta;
} else {
/* Reallocate buffer to accommodate read-ahead limit */
char ncb[] = new char[ readAheadLimit ];
System.arraycopy( cb, markedChar, ncb, 0, delta );
cb = ncb;
markedChar = 0;
dst = delta;
}
nextChar = nChars = delta;
}
}
int n;
do {
n = in.read( cb, dst, cb.length - dst );
} while (n == 0);
if (n > 0) {
nChars = dst + n;
nextChar = dst;
}
}
/**
* Reads a line of text. A line is considered to be terminated by any one
* of a line feed ('\0')
*
* @param ignoreNUL If true, the next '\0' will be skipped
*
* @return A String containing the contents of the line, not including
* any line-termination characters, or null if the end of the
* stream has been reached
*
* @see java.io.LineNumberReader#readLine()
*
* @exception IOException If an I/O error occurs
*/
String readTMessage( boolean ignoreNUL ) throws IOException {
StringBuffer s = null;
int startChar;
synchronized (lock) {
ensureOpen();
boolean omitNUL = ignoreNUL || skipNUL;
bufferLoop: for (;;) {
if (nextChar >= nChars) {
fill();
}
if (nextChar >= nChars) { /* EOF */
if (s != null && s.length() > 0) {
return s.toString();
} else {
return null;
}
}
boolean eol = false;
char c = 0;
int i;
/* Skip a leftover '\0', if necessary */
if (omitNUL && (cb[nextChar] == '\0')) {
nextChar++;
}
skipNUL = false;
omitNUL = false;
charLoop: for (i = nextChar; i < nChars; i++) {
c = cb[i];
if ((c == '\0')) {
eol = true;
break charLoop;
}
}
startChar = nextChar;
nextChar = i;
if (eol) {
String str;
if (s == null) {
str = new String( cb, startChar, i - startChar );
} else {
s.append( cb, startChar, i - startChar );
str = s.toString();
}
nextChar++;
if (c == '\0') {
skipNUL = true;
}
return str;
}
if (s == null) {
s = new StringBuffer( defaultExpectedLineLength );
}
s.append( cb, startChar, i - startChar );
}
}
}
/**
* Reads a line of text. A line is considered to be terminated by any one
* of a line feed ('\n'), a carriage return ('\r'), or a carriage return
* followed immediately by a linefeed.
*
* @return A String containing the contents of the line, not including
* any line-termination characters, or null if the end of the
* stream has been reached
*
* @exception IOException If an I/O error occurs
*
* @see java.nio.file.Files#readAllLines
*/
public String readTMessage() throws IOException {
return readTMessage( false );
}
}
Other interesting class are
and
org.apache.james.util.CharTerminatedInputStream
I add some news about CharTerminatedInputStream. Using thtat class is dangerous, because you need to manage the correct character set in use. An outputStream is more high level and you can interpose an InputStreamReader.
Upvotes: 1
Reputation: 14853
This stream is auto flush enabled and US-ASCII, as you want.
OutputStream os = socketChannel.socket().getOutputStream();
PrintStream ps = new PrintStream( os, true, "US-ASCII" );
ps.print( "tange é*"£$%&/(()=?'^ìì[]@!<>#òùèé+*" );
os.write( (byte)0 ); // end-of-message
Upvotes: 1