问:
Android WebRTC setRemoteDescription
I'm trying to implement an RTC in my Android app.
My Android client is meant to be the offer.

I use setLocalDescription and send my SessionDescription.
The problem is when I create my own SessionDescription and try to use setRemoteDescription - I get a response that my SessionDescription is null although is isn't.
See the following code.

```<code>public class OfferActivity extends AppCompatActivity implements View.OnClickListener {

    final private String TAG = "App";

    private PeerConnectionFactory mFactory;
    private PeerConnection mPeerConnection;
    private DataChannel mDataChannel;
    private MediaConstraints mConstraints;

    PeerConnection.Observer mPeerConnectionObserver = new PeerConnection.Observer() {
        @Override
        public void onIceCandidate(IceCandidate iceCandidate) {
            IceCandidate candidate = new IceCandidate(iceCandidate.sdpMid, iceCandidate.sdpMLineIndex, "candidate");  // TODO: Edit
            Log.d(TAG, "pcObserver1 onIceCandidate() param: " + candidate.toString());
            mPeerConnection.addIceCandidate(candidate);
        }

        @Override
        public void onSignalingChange(PeerConnection.SignalingState signalingState) {
        }

        @Override
        public void onIceConnectionChange(PeerConnection.IceConnectionState iceConnectionState) {
        }

        @Override
        public void onIceGatheringChange(PeerConnection.IceGatheringState iceGatheringState) {
        }

        @Override
        public void onAddStream(MediaStream mediaStream) {
        }

        @Override
        public void onRemoveStream(MediaStream mediaStream) {
        }

        @Override
        public void onDataChannel(DataChannel dataChannel) {
            mDataChannel = dataChannel;
            mDataChannel.registerObserver(mDataChannelObserver);
        }

        @Override
        public void onRenegotiationNeeded() {
        }
    };

    DataChannel.Observer mDataChannelObserver = new DataChannel.Observer() {
        @Override
        public void onStateChange() {
            Log.d(TAG, "mDataChannelObserver onStateChange() " + mDataChannel.state().name());

            if (mDataChannel.state() == DataChannel.State.OPEN) {
                String data = mEt.getText().toString();
                ByteBuffer buffer = ByteBuffer.wrap(data.getBytes());
                mDataChannel.send(new DataChannel.Buffer(buffer, false));
            }
        }

        @Override
        public void onMessage(DataChannel.Buffer buffer) {
            Log.d(TAG, "mDataChannelObserver onMessage()");
            if (buffer.binary == false) {
                int limit = buffer.data.limit();
                byte[] datas = new byte[limit];
                buffer.data.get(datas);
                final String tmp = new String(datas);
                Log.d(TAG, "mDataChannelObserver onMessage: " + tmp);
                addText("mDataChannelObserver", tmp);
            }
        }
    };

    SdpObserver mSdpLocalObserver = new SdpObserver() {
        @Override
        public void onCreateSuccess(SessionDescription desc) {

            final SessionDescription.Type typeEnum = desc.type;
            final String type = typeEnum.canonicalForm();
            final String sdp = desc.description;

            if (typeEnum == SessionDescription.Type.OFFER) {
                mPeerConnection.setLocalDescription(mSdpLocalObserver, desc);
                // TODO: Here we will have the code that gets the other peer sdp
            } else if (typeEnum == SessionDescription.Type.ANSWER) {
                mPeerConnection.setRemoteDescription(mSdpLocalObserver, desc);
            } else {

                Log.d(TAG, "Something else was found at onCreateSuccess");
            }
            // TODO: This is debug only. the "setLocalDescription" does not need javascript interfaces (JSON)
            try {
                final JSONObject json = new JSONObject();
                json.put("type", type);
                json.put("sdp", sdp);
                Log.d(TAG, "mSdpLocalObserver onCreateSuccess() > sdp: " + json.toString());
            } catch (org.json.JSONException ex) {
            }
        }

        @Override
        public void onSetSuccess() {
            Log.d(TAG, "mSdpLocalObserver onCreateSuccess()");
        }

        @Override
        public void onCreateFailure(String s) {
            Log.d(TAG, "mSdpLocalObserver onCreateFailure() " + s);
        }

        @Override
        public void onSetFailure(String s) {
            Log.d(TAG, "mSdpLocalObserver onSetFailure() " + s);
        }
    };

    private TextView mTv;
    private EditText mEt;
    private Button mBtn;
    private EditText mEtRegister;
    private Button mBtnRegister;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mTv = (TextView) findViewById(R.id.mTv);
        mEt = (EditText) findViewById(R.id.mEt);
        mBtn = (Button) findViewById(R.id.mBtn);
        mEtRegister = (EditText) findViewById(R.id.mEtRegister);
        mBtnRegister = (Button) findViewById(R.id.mBtnRegister);
        mBtn.setOnClickListener(this);
        mBtnRegister.setOnClickListener(this);

        PeerConnectionFactory.initializeAndroidGlobals(getApplicationContext(), true, true, true, null);
        mFactory = new PeerConnectionFactory();

        final List<PeerConnection.IceServer> iceServers = new LinkedList<>();
        iceServers.add(new PeerConnection.IceServer("stun:xx.xx.xxx.xxx")); // TODO: Edit

        mConstraints = new MediaConstraints();
        mConstraints.optional.add(new MediaConstraints.KeyValuePair("DtlsSrtpKeyAgreement", "true"));
        mConstraints.optional.add(new MediaConstraints.KeyValuePair("RtpDataChannels", "true"));

        mPeerConnecti

                on = mFactory.createPeerConnection(iceServers, mConstraints, mPeerConnectionObserver);

        mDataChannel = mPeerConnection.createDataChannel("test", new DataChannel.Init()); // TODO: Edit

    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.d(TAG, "onDestroy()");
        if (mDataChannel != null) {
            mDataChannel.close();
            mDataChannel.unregisterObserver();
        }
        if (mPeerConnection != null) {
            mPeerConnection.close();

        }
    }

    @Override
    public void onClick(View v) {
        if (v == mBtnRegister) {
            String text = mEtRegister.getText().toString(); // .replace("\\r\\n","");
            final SessionDescription description = new SessionDescription(SessionDescription.Type.ANSWER, text);
            mPeerConnection.setRemoteDescription(mSdpLocalObserver, null);
        }
    }

    private DataChannel.Buffer send(String data) {
        ByteBuffer buffer = ByteBuffer.wrap(data.getBytes());
        return new DataChannel.Buffer(buffer, false);
    }

    private void addText(final String who, final String what) {
        OfferActivity.this.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                final String text = mTv.getText().toString() + "\n";
                mTv.setText(text + who + ": " + what);
                mEt.setText("");
            }
        });
    }

}
</code>```

My Logs:

```<code>01-19 16:12:51.447 9171-9239/com.walkme.rtc D/sample: pcObserver1 onRenegotiationNeeded()
01-19 16:12:51.879 9171-9239/com.walkme.rtc D/sample: pcObserver1 onSignalingChange() HAVE_LOCAL_OFFER
01-19 16:12:51.881 9171-9239/com.walkme.rtc D/sample: mSdpLocalObserver onCreateSuccess() > sdp: {"type":"offer","sdp":"v=0\r\no=- 8050881100630094562 2 IN IP4 127.0.0.1\r\ns=-\r\nt=0 0\r\na=group:BUNDLE data\r\na=msid-semantic: WMS\r\nm=application 9 RTP\/SAVPF 101\r\nc=IN IP4 0.0.0.0\r\nb=AS:30\r\na=rtcp:9 IN IP4 0.0.0.0\r\na=ice-ufrag:+f0buF4V2OXNT4sI\r\na=ice-pwd:\/QDilxDBndczNuvgPIBXZ7je\r\na=fingerprint:sha-256 E4:FB:1E:80:16:B8:4E:F9:B1:E3:81:B6:09:83:95:F3:B3:C2:34:DC:88:F4:C8:DF:9B:50:8A:00:0E:4D:AC:75\r\na=setup:actpass\r\na=mid:data\r\na=sendrecv\r\na=rtcp-mux\r\na=rtpmap:101 google-data\/90000\r\na=ssrc:1715303496 cname:NVNcmn2VpGpsfyFJ\r\na=ssrc:1715303496 msid:test test\r\na=ssrc:1715303496 mslabel:test\r\na=ssrc:1715303496 label:test\r\n"}
01-19 16:12:51.882 9171-9239/com.walkme.rtc D/sample: pcObserver1 onIceGatheringChange() GATHERING
01-19 16:12:51.883 9171-9239/com.walkme.rtc D/sample: pcObserver1 onIceGatheringChange() GATHERING
01-19 16:12:51.883 9171-9239/com.walkme.rtc D/sample: sdpObserver1 onCreateSuccess()
01-19 16:12:51.884 9171-9239/com.walkme.rtc D/sample: pcObserver1 onIceCandidate() param: data:0:candidate
01-19 16:12:51.885 9171-9239/com.walkme.rtc D/sample: pcObserver1 onIceCandidate() param: data:0:candidate
01-19 16:12:51.985 9171-9239/com.walkme.rtc D/sample: pcObserver1 onIceCandidate() param: data:0:candidate
01-19 16:12:51.986 9171-9239/com.walkme.rtc D/sample: pcObserver1 onIceCandidate() param: data:0:candidate
01-19 16:12:52.038 9171-9239/com.walkme.rtc D/sample: pcObserver1 onIceCandidate() param: data:0:candidate
01-19 16:12:52.039 9171-9239/com.walkme.rtc D/sample: pcObserver1 onIceCandidate() param: data:0:candidate
01-19 16:12:52.039 9171-9239/com.walkme.rtc D/sample: pcObserver1 onIceGatheringChange() COMPLETE
01-19 16:13:32.985 9171-9239/com.walkme.rtc D/sample: sdpObserver1 onSetFailure() SessionDescription is NULL.
01-19 16:14:16.864 11776-11844/com.walkme.rtc D/sample: pcObserver1 onRenegotiationNeeded()
01-19 16:14:16.974 11776-11844/com.walkme.rtc D/sample: pcObserver1 onSignalingChange() HAVE_LOCAL_OFFER
01-19 16:14:16.977 11776-11844/com.walkme.rtc D/sample: mSdpLocalObserver onCreateSuccess() > sdp: {"type":"offer","sdp":"v=0\r\no=- 3146545619962464613 2 IN IP4 127.0.0.1\r\ns=-\r\nt=0 0\r\na=group:BUNDLE data\r\na=msid-semantic: WMS\r\nm=application 9 RTP\/SAVPF 101\r\nc=IN IP4 0.0.0.0\r\nb=AS:30\r\na=rtcp:9 IN IP4 0.0.0.0\r\na=ice-ufrag:W3sKNep8dXP\/Ind5\r\na=ice-pwd:oOy9NblGeZxRWL\/bxSnFU8KD\r\na=fingerprint:sha-256 78:2E:EF:58:AD:11:E3:29:34:7C:94:48:E7:DC:98:90:17:D6:5E:0B:DC:72:3E:4A:5A:35:7F:C5:F8:D4:06:81\r\na=setup:actpass\r\na=mid:data\r\na=sendrecv\r\na=rtcp-mux\r\na=rtpmap:101 google-data\/90000\r\na=ssrc:3989867427 cname:JKXfZ0vrlT1jdURT\r\na=ssrc:3989867427 msid:test test\r\na=ssrc:3989867427 mslabel:test\r\na=ssrc:3989867427 label:test\r\n"}
01-19 16:14:16.978 11776-11844/com.walkme.rtc D/sample: pcObserver1 onIceGatheringChange() GATHERING
01-19 16:14:16.978 11776-11844/com.walkme.rtc D/sample: pcObserver1 onIceGatheringChange() GATHERING
01-19 16:14:16.978 11776-11844/com.walkme.rtc D/sample: sdpObserver1 onCreateSuccess()
01-19 16:14:16.980 11776-11844/com.walkme.rtc D/sample: pcObserver1 onIceCandidate() param: data:0:candidate
01-19 16:14:16.981 11776-11844/com.walkme.rtc D/sample: pcObserver1 onIceCandidate() param: data:0:candidate
01-19 16:14:17.082 11776-11844/com.walkme.rtc D/sample: pcObserver1 onIceCandidate() param: data:0:candidate
01-19 16:14:17.082 11776-11844/com.walkme.rtc D/sample: pcObserver1 onIceCandidate() param: data:0:candidate
01-19 16:14:17.136 11776-11844/com.walkme.rtc D/sample: pcObserver1 onIceCandidate() param: data:0:candidate
01-19 16:14:17.137 11776-11844/com.walkme.rtc D/sample: pcObserver1 onIceCandidate() param: data:0:candidate
01-19 16:14:17.138 11776-11844/com.walkme.rtc D/sample: pcObserver1 onIceGatheringChange() COMPLETE
01-19 16:14:22.769 11776-11844/com.walkme.rtc D/sample: sdpObserver1 onSetFailure() SessionDescription is NULL.
01-19 16:31:51.241 29355-29414/com.walkme.rtc D/sample: pcObserver1 onRenegotiationNeeded()
</code>```

EDIT

After further inspection the problem was with the codecs.
What I did was simply get the data as a string of json and then used JsonObject.

答:
I met the similar problem when I setLocalSDP, and got a setFailure back with the messge "session is null".
I checked my code and find the AudioTrack and AudioSource ID string I set contains blank space. As I remove the space, problem solved.
Slice of problem sdp:
a=ssrc:736062433 msid:media stream 1 audio track                                                                                a=ssrc:736062433 mslabel:media stream 1                                                                                a=ssrc:736062433 label:audio track 1
Then change Strings to:</p>

```<code>   private static final String AUDIO_TRACK_ID ="audio_track_1" ;

    private static final String LOCAL_MEDIA_STREAM_ID ="media_stream_1" ;``
</code>```

Title: Android WebRTC setRemoteDescription

Body:
I'm trying to implement an RTC in my Android app.
My Android client is meant to be the offer.

I use setLocalDescription and send my SessionDescription.
The problem is when I create my own SessionDescription and try to use setRemoteDescription - I get a response that my SessionDescription is null although is isn't.
See the following code.

public class OfferActivity extends AppCompatActivity implements View.OnClickListener {

    final private String TAG = "App";

    private PeerConnectionFactory mFactory;
    private PeerConnection mPeerConnection;
    private DataChannel mDataChannel;
    private MediaConstraints mConstraints;

    PeerConnection.Observer mPeerConnectionObserver = new PeerConnection.Observer() {
        @Override
        public void onIceCandidate(IceCandidate iceCandidate) {
            IceCandidate candidate = new IceCandidate(iceCandidate.sdpMid, iceCandidate.sdpMLineIndex, "candidate");  // TODO: Edit
            Log.d(TAG, "pcObserver1 onIceCandidate() param: " + candidate.toString());
            mPeerConnection.addIceCandidate(candidate);
        }

        @Override
        public void onSignalingChange(PeerConnection.SignalingState signalingState) {
        }

        @Override
        public void onIceConnectionChange(PeerConnection.IceConnectionState iceConnectionState) {
        }

        @Override
        public void onIceGatheringChange(PeerConnection.IceGatheringState iceGatheringState) {
        }

        @Override
        public void onAddStream(MediaStream mediaStream) {
        }

        @Override
        public void onRemoveStream(MediaStream mediaStream) {
        }

        @Override
        public void onDataChannel(DataChannel dataChannel) {
            mDataChannel = dataChannel;
            mDataChannel.registerObserver(mDataChannelObserver);
        }

        @Override
        public void onRenegotiationNeeded() {
        }
    };

    DataChannel.Observer mDataChannelObserver = new DataChannel.Observer() {
        @Override
        public void onStateChange() {
            Log.d(TAG, "mDataChannelObserver onStateChange() " + mDataChannel.state().name());

            if (mDataChannel.state() == DataChannel.State.OPEN) {
                String data = mEt.getText().toString();
                ByteBuffer buffer = ByteBuffer.wrap(data.getBytes());
                mDataChannel.send(new DataChannel.Buffer(buffer, false));
            }
        }

        @Override
        public void onMessage(DataChannel.Buffer buffer) {
            Log.d(TAG, "mDataChannelObserver onMessage()");
            if (buffer.binary == false) {
                int limit = buffer.data.limit();
                byte[] datas = new byte[limit];
                buffer.data.get(datas);
                final String tmp = new String(datas);
                Log.d(TAG, "mDataChannelObserver onMessage: " + tmp);
                addText("mDataChannelObserver", tmp);
            }
        }
    };

    SdpObserver mSdpLocalObserver = new SdpObserver() {
        @Override
        public void onCreateSuccess(SessionDescription desc) {

            final SessionDescription.Type typeEnum = desc.type;
            final String type = typeEnum.canonicalForm();
            final String sdp = desc.description;

            if (typeEnum == SessionDescription.Type.OFFER) {
                mPeerConnection.setLocalDescription(mSdpLocalObserver, desc);
                // TODO: Here we will have the code that gets the other peer sdp
            } else if (typeEnum == SessionDescription.Type.ANSWER) {
                mPeerConnection.setRemoteDescription(mSdpLocalObserver, desc);
            } else {

                Log.d(TAG, "Something else was found at onCreateSuccess");
            }
            // TODO: This is debug only. the "setLocalDescription" does not need javascript interfaces (JSON)
            try {
                final JSONObject json = new JSONObject();
                json.put("type", type);
                json.put("sdp", sdp);
                Log.d(TAG, "mSdpLocalObserver onCreateSuccess() > sdp: " + json.toString());
            } catch (org.json.JSONException ex) {
            }
        }

        @Override
        public void onSetSuccess() {
            Log.d(TAG, "mSdpLocalObserver onCreateSuccess()");
        }

        @Override
        public void onCreateFailure(String s) {
            Log.d(TAG, "mSdpLocalObserver onCreateFailure() " + s);
        }

        @Override
        public void onSetFailure(String s) {
            Log.d(TAG, "mSdpLocalObserver onSetFailure() " + s);
        }
    };

    private TextView mTv;
    private EditText mEt;
    private Button mBtn;
    private EditText mEtRegister;
    private Button mBtnRegister;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mTv = (TextView) findViewById(R.id.mTv);
        mEt = (EditText) findViewById(R.id.mEt);
        mBtn = (Button) findViewById(R.id.mBtn);
        mEtRegister = (EditText) findViewById(R.id.mEtRegister);
        mBtnRegister = (Button) findViewById(R.id.mBtnRegister);
        mBtn.setOnClickListener(this);
        mBtnRegister.setOnClickListener(this);

        PeerConnectionFactory.initializeAndroidGlobals(getApplicationContext(), true, true, true, null);
        mFactory = new PeerConnectionFactory();

        final List<PeerConnection.IceServer> iceServers = new LinkedList<>();
        iceServers.add(new PeerConnection.IceServer("stun:xx.xx.xxx.xxx")); // TODO: Edit

        mConstraints = new MediaConstraints();
        mConstraints.optional.add(new MediaConstraints.KeyValuePair("DtlsSrtpKeyAgreement", "true"));
        mConstraints.optional.add(new MediaConstraints.KeyValuePair("RtpDataChannels", "true"));

        mPeerConnecti

                on = mFactory.createPeerConnection(iceServers, mConstraints, mPeerConnectionObserver);

        mDataChannel = mPeerConnection.createDataChannel("test", new DataChannel.Init()); // TODO: Edit

    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.d(TAG, "onDestroy()");
        if (mDataChannel != null) {
            mDataChannel.close();
            mDataChannel.unregisterObserver();
        }
        if (mPeerConnection != null) {
            mPeerConnection.close();

        }
    }

    @Override
    public void onClick(View v) {
        if (v == mBtnRegister) {
            String text = mEtRegister.getText().toString(); // .replace("\\r\\n","");
            final SessionDescription description = new SessionDescription(SessionDescription.Type.ANSWER, text);
            mPeerConnection.setRemoteDescription(mSdpLocalObserver, null);
        }
    }

    private DataChannel.Buffer send(String data) {
        ByteBuffer buffer = ByteBuffer.wrap(data.getBytes());
        return new DataChannel.Buffer(buffer, false);
    }

    private void addText(final String who, final String what) {
        OfferActivity.this.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                final String text = mTv.getText().toString() + "\n";
                mTv.setText(text + who + ": " + what);
                mEt.setText("");
            }
        });
    }

}

My Logs:

01-19 16:12:51.447 9171-9239/com.walkme.rtc D/sample: pcObserver1 onRenegotiationNeeded()
01-19 16:12:51.879 9171-9239/com.walkme.rtc D/sample: pcObserver1 onSignalingChange() HAVE_LOCAL_OFFER
01-19 16:12:51.881 9171-9239/com.walkme.rtc D/sample: mSdpLocalObserver onCreateSuccess() > sdp: {"type":"offer","sdp":"v=0\r\no=- 8050881100630094562 2 IN IP4 127.0.0.1\r\ns=-\r\nt=0 0\r\na=group:BUNDLE data\r\na=msid-semantic: WMS\r\nm=application 9 RTP\/SAVPF 101\r\nc=IN IP4 0.0.0.0\r\nb=AS:30\r\na=rtcp:9 IN IP4 0.0.0.0\r\na=ice-ufrag:+f0buF4V2OXNT4sI\r\na=ice-pwd:\/QDilxDBndczNuvgPIBXZ7je\r\na=fingerprint:sha-256 E4:FB:1E:80:16:B8:4E:F9:B1:E3:81:B6:09:83:95:F3:B3:C2:34:DC:88:F4:C8:DF:9B:50:8A:00:0E:4D:AC:75\r\na=setup:actpass\r\na=mid:data\r\na=sendrecv\r\na=rtcp-mux\r\na=rtpmap:101 google-data\/90000\r\na=ssrc:1715303496 cname:NVNcmn2VpGpsfyFJ\r\na=ssrc:1715303496 msid:test test\r\na=ssrc:1715303496 mslabel:test\r\na=ssrc:1715303496 label:test\r\n"}
01-19 16:12:51.882 9171-9239/com.walkme.rtc D/sample: pcObserver1 onIceGatheringChange() GATHERING
01-19 16:12:51.883 9171-9239/com.walkme.rtc D/sample: pcObserver1 onIceGatheringChange() GATHERING
01-19 16:12:51.883 9171-9239/com.walkme.rtc D/sample: sdpObserver1 onCreateSuccess()
01-19 16:12:51.884 9171-9239/com.walkme.rtc D/sample: pcObserver1 onIceCandidate() param: data:0:candidate
01-19 16:12:51.885 9171-9239/com.walkme.rtc D/sample: pcObserver1 onIceCandidate() param: data:0:candidate
01-19 16:12:51.985 9171-9239/com.walkme.rtc D/sample: pcObserver1 onIceCandidate() param: data:0:candidate
01-19 16:12:51.986 9171-9239/com.walkme.rtc D/sample: pcObserver1 onIceCandidate() param: data:0:candidate
01-19 16:12:52.038 9171-9239/com.walkme.rtc D/sample: pcObserver1 onIceCandidate() param: data:0:candidate
01-19 16:12:52.039 9171-9239/com.walkme.rtc D/sample: pcObserver1 onIceCandidate() param: data:0:candidate
01-19 16:12:52.039 9171-9239/com.walkme.rtc D/sample: pcObserver1 onIceGatheringChange() COMPLETE
01-19 16:13:32.985 9171-9239/com.walkme.rtc D/sample: sdpObserver1 onSetFailure() SessionDescription is NULL.
01-19 16:14:16.864 11776-11844/com.walkme.rtc D/sample: pcObserver1 onRenegotiationNeeded()
01-19 16:14:16.974 11776-11844/com.walkme.rtc D/sample: pcObserver1 onSignalingChange() HAVE_LOCAL_OFFER
01-19 16:14:16.977 11776-11844/com.walkme.rtc D/sample: mSdpLocalObserver onCreateSuccess() > sdp: {"type":"offer","sdp":"v=0\r\no=- 3146545619962464613 2 IN IP4 127.0.0.1\r\ns=-\r\nt=0 0\r\na=group:BUNDLE data\r\na=msid-semantic: WMS\r\nm=application 9 RTP\/SAVPF 101\r\nc=IN IP4 0.0.0.0\r\nb=AS:30\r\na=rtcp:9 IN IP4 0.0.0.0\r\na=ice-ufrag:W3sKNep8dXP\/Ind5\r\na=ice-pwd:oOy9NblGeZxRWL\/bxSnFU8KD\r\na=fingerprint:sha-256 78:2E:EF:58:AD:11:E3:29:34:7C:94:48:E7:DC:98:90:17:D6:5E:0B:DC:72:3E:4A:5A:35:7F:C5:F8:D4:06:81\r\na=setup:actpass\r\na=mid:data\r\na=sendrecv\r\na=rtcp-mux\r\na=rtpmap:101 google-data\/90000\r\na=ssrc:3989867427 cname:JKXfZ0vrlT1jdURT\r\na=ssrc:3989867427 msid:test test\r\na=ssrc:3989867427 mslabel:test\r\na=ssrc:3989867427 label:test\r\n"}
01-19 16:14:16.978 11776-11844/com.walkme.rtc D/sample: pcObserver1 onIceGatheringChange() GATHERING
01-19 16:14:16.978 11776-11844/com.walkme.rtc D/sample: pcObserver1 onIceGatheringChange() GATHERING
01-19 16:14:16.978 11776-11844/com.walkme.rtc D/sample: sdpObserver1 onCreateSuccess()
01-19 16:14:16.980 11776-11844/com.walkme.rtc D/sample: pcObserver1 onIceCandidate() param: data:0:candidate
01-19 16:14:16.981 11776-11844/com.walkme.rtc D/sample: pcObserver1 onIceCandidate() param: data:0:candidate
01-19 16:14:17.082 11776-11844/com.walkme.rtc D/sample: pcObserver1 onIceCandidate() param: data:0:candidate
01-19 16:14:17.082 11776-11844/com.walkme.rtc D/sample: pcObserver1 onIceCandidate() param: data:0:candidate
01-19 16:14:17.136 11776-11844/com.walkme.rtc D/sample: pcObserver1 onIceCandidate() param: data:0:candidate
01-19 16:14:17.137 11776-11844/com.walkme.rtc D/sample: pcObserver1 onIceCandidate() param: data:0:candidate
01-19 16:14:17.138 11776-11844/com.walkme.rtc D/sample: pcObserver1 onIceGatheringChange() COMPLETE
01-19 16:14:22.769 11776-11844/com.walkme.rtc D/sample: sdpObserver1 onSetFailure() SessionDescription is NULL.
01-19 16:31:51.241 29355-29414/com.walkme.rtc D/sample: pcObserver1 onRenegotiationNeeded()

EDIT

After further inspection the problem was with the codecs.
What I did was simply get the data as a string of json and then used JsonObject.

Body:
I met the similar problem when I setLocalSDP, and got a setFailure back with the messge "session is null".
I checked my code and find the AudioTrack and AudioSource ID string I set contains blank space. As I remove the space, problem solved.
Slice of problem sdp:
a=ssrc:736062433 msid:media stream 1 audio track                                                                                a=ssrc:736062433 mslabel:media stream 1                                                                                a=ssrc:736062433 label:audio track 1
Then change Strings to:

   private static final String AUDIO_TRACK_ID ="audio_track_1" ;

    private static final String LOCAL_MEDIA_STREAM_ID ="media_stream_1" ;``


来源: stackexchange

问:
Read from Excel file — specific sheet
Simply put: I need to read from an xlsx file (rows), in the simplest way. That is, preferably without using third-party tools, or at least things that aren't available as nuget packages.

I've been trying for a while with IExcelDatareader, but I cannot figure out how to get data from a specific sheet.

This simple code snippet works, but it just reads the first worksheet:

```<code>FileStream stream = File.Open("C:\\test\\test.xlsx", FileMode.Open, FileAccess.Read);

IExcelDataReader excelReader = ExcelReaderFactory.CreateOpenXmlReader(stream);

excelReader.IsFirstRowAsColumnNames = true;

while (excelReader.Read()) {
    Console.WriteLine(excelReader.GetString(0));
}
</code>```

This prints the rows in the first worksheet, but ignores the others. Of course, there is nothing to suggest otherwise, but I cannot seem to find out how to specify the sheet name.

It strikes me that this should be quite easy?

Sorry for asking something which has been asked several times before, but the answer (here and elsewhere on the net) are a jungle of bad, plain wrong and outdated half-answers that's a nightmare to try and make sense of. Especially since almost everyone answering assumes that you know some specific details that are not always easy to find.

UPDATE:
As per daniell89's suggestion below, I've tried this:

```<code>FileStream stream = File.Open("C:\\test\\test.xlsx", FileMode.Open, FileAccess.Read);

IExcelDataReader excelReader = ExcelReaderFactory.CreateOpenXmlReader(stream);

excelReader.IsFirstRowAsColumnNames = true;

// Select the first or second sheet - this works:
DataTable specificWorkSheet = excelReader.AsDataSet().Tables[1];

// This works: Printing the first value in each column
foreach (var col in specificWorkSheet.Columns)
    Console.WriteLine(col.ToString());

// This does NOT work: Printing the first value in each row
foreach (var row in specificWorkSheet.Rows)
    Console.WriteLine(row.ToString());
</code>```

Printing each column heading with col.ToString() works fine.

Printing the first cell of each row with row.ToString() results in this output:

```<code>System.Data.DataRow
System.Data.DataRow
System.Data.DataRow
...
</code>```

One per row, so it's obviously getting the rows. But how to get the contents, and why does ToString() work for the columns and not for the rows?

答:
Maybe look at this answer: https://stackoverflow.com/a/32522041/5358389

```<code>DataSet workSheets= reader.AsDataSet();
</code>```

And then specific sheet:

```<code>DataTable specificWorkSheet = reader.AsDataSet().Tables[yourValue];
</code>```

Enumerating rows:

```<code>foreach (var row in specificWorkSheet.Rows)
     Console.WriteLine(((DataRow)row)[0]); // column identifier in square brackets
</code>```

ContentLicense: CC BY-SA 3.0

Title: Read from Excel file — specific sheet

Body:
Simply put: I need to read from an xlsx file (rows), in the simplest way. That is, preferably without using third-party tools, or at least things that aren't available as nuget packages.

I've been trying for a while with IExcelDatareader, but I cannot figure out how to get data from a specific sheet.

This simple code snippet works, but it just reads the first worksheet:

FileStream stream = File.Open("C:\\test\\test.xlsx", FileMode.Open, FileAccess.Read);

IExcelDataReader excelReader = ExcelReaderFactory.CreateOpenXmlReader(stream);

excelReader.IsFirstRowAsColumnNames = true;

while (excelReader.Read()) {
    Console.WriteLine(excelReader.GetString(0));
}

This prints the rows in the first worksheet, but ignores the others. Of course, there is nothing to suggest otherwise, but I cannot seem to find out how to specify the sheet name.

It strikes me that this should be quite easy?

Sorry for asking something which has been asked several times before, but the answer (here and elsewhere on the net) are a jungle of bad, plain wrong and outdated half-answers that's a nightmare to try and make sense of. Especially since almost everyone answering assumes that you know some specific details that are not always easy to find.

UPDATE:
As per daniell89's suggestion below, I've tried this:

FileStream stream = File.Open("C:\\test\\test.xlsx", FileMode.Open, FileAccess.Read);

IExcelDataReader excelReader = ExcelReaderFactory.CreateOpenXmlReader(stream);

excelReader.IsFirstRowAsColumnNames = true;

// Select the first or second sheet - this works:
DataTable specificWorkSheet = excelReader.AsDataSet().Tables[1];

// This works: Printing the first value in each column
foreach (var col in specificWorkSheet.Columns)
    Console.WriteLine(col.ToString());

// This does NOT work: Printing the first value in each row
foreach (var row in specificWorkSheet.Rows)
    Console.WriteLine(row.ToString());

Printing each column heading with col.ToString() works fine.

Printing the first cell of each row with row.ToString() results in this output:

System.Data.DataRow
System.Data.DataRow
System.Data.DataRow
...

One per row, so it's obviously getting the rows. But how to get the contents, and why does ToString() work for the columns and not for the rows?

Body:
Maybe look at this answer: https://stackoverflow.com/a/32522041/5358389

DataSet workSheets= reader.AsDataSet();

And then specific sheet:

DataTable specificWorkSheet = reader.AsDataSet().Tables[yourValue];

Enumerating rows:

foreach (var row in specificWorkSheet.Rows)
     Console.WriteLine(((DataRow)row)[0]); // column identifier in square brackets


问:
Php gettext is not displaying the translated text (after generationg the .pot and .mo files with poEdit)
I followed the folling tutorial: http://mel.melaxis.com/devblog/2005/08/06/localizing-php-web-sites-using-gettext/

about Php gettext extension (I unchecked the comment in the php.ini)

The gettext is activated but it doesn't show up the translation (German).

Here are the files:

C:\wamp\www\php-test\test.php:

```<code><?php
require_once("localization.php");
echo _("Hello World!");
?>
</code>```

C:\wamp\www\php-test\localization.php:

```<code><?php
$locale = "de_DE";
if (isSet($_GET["locale"])) $locale = $_GET["locale"];
putenv("LC_ALL=$locale");
setlocale(LC_ALL, $locale);
bindtextdomain("messages", "./locale");
textdomain("messages");
?>
</code>```

C:\wamp\www\php-test\locale\de_DE\LC_MESSAGES\messages.po:

```<code>msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2010-02-14 00:35+0800\n"
"PO-Revision-Date: 2010-02-14 00:37+0800\n"
"Last-Translator: Jano Chen <weedcl@hotmail.com>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Poedit-KeywordsList: _;gettext;gettext_noop\n"
"X-Poedit-Basepath: C:\\wamp\\www\\php-test\n"
"X-Poedit-Language: German\n"
"X-Poedit-Country: GERMANY\n"
"X-Poedit-SourceCharset: iso-8859-1\n"
"X-Poedit-SearchPath-0: .\n"

#: test.php:2
msgid "Hello World!"
msgstr "Hallo Welt!"
</code>```

C:\wamp\www\php-test\locale\de_DE\LC_MESSAGES\messages.mo

(sorry from some reason I can't copy the text of this file)

When I open it should display "Hallo Welt" (Hello World in German) but instead it displays it in English (Hello World).

Any suggestions?

PS: I'm using Windows XP SP2

答: A bit basic, I know, but did you try to restart the web server? I have to do it everytime I update my .mo files.

ContentLicense: CC BY-SA 4.0

Body:
I followed the folling tutorial: http://mel.melaxis.com/devblog/2005/08/06/localizing-php-web-sites-using-gettext/

about Php gettext extension (I unchecked the comment in the php.ini)

The gettext is activated but it doesn't show up the translation (German).

Here are the files:

C:\wamp\www\php-test\test.php:

<?php
require_once("localization.php");
echo _("Hello World!");
?>

C:\wamp\www\php-test\localization.php:

<?php
$locale = "de_DE";
if (isSet($_GET["locale"])) $locale = $_GET["locale"];
putenv("LC_ALL=$locale");
setlocale(LC_ALL, $locale);
bindtextdomain("messages", "./locale");
textdomain("messages");
?>

C:\wamp\www\php-test\locale\de_DE\LC_MESSAGES\messages.po:

msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2010-02-14 00:35+0800\n"
"PO-Revision-Date: 2010-02-14 00:37+0800\n"
"Last-Translator: Jano Chen <weedcl@hotmail.com>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Poedit-KeywordsList: _;gettext;gettext_noop\n"
"X-Poedit-Basepath: C:\\wamp\\www\\php-test\n"
"X-Poedit-Language: German\n"
"X-Poedit-Country: GERMANY\n"
"X-Poedit-SourceCharset: iso-8859-1\n"
"X-Poedit-SearchPath-0: .\n"

#: test.php:2
msgid "Hello World!"
msgstr "Hallo Welt!"

C:\wamp\www\php-test\locale\de_DE\LC_MESSAGES\messages.mo

(sorry from some reason I can't copy the text of this file)

When I open it should display "Hallo Welt" (Hello World in German) but instead it displays it in English (Hello World).

Any suggestions?

PS: I'm using Windows XP SP2

ContentLicense: CC BY-SA 2.5


问:
in query in Ember JS DS.store model
I have tried below both queries :

```<code>    this.store.query('estimate', { 'vendorUids' : supplierData.getEach('vendorUid') } ).then((estimatesData)=>{

});

this.store.query('estimate', { filter : { 'vendorUids' : supplierData.getEach('vendorUid') } }).then((estimatesData)=>{

});
</code>```

But it is creating queries as below :

```<code>https://localhost:8080/v1/estimates?vendorUids[]=344&vendorUids[]=5&vendorUids[]=1&vendorUids[]=2&vendorUids[]=3&vendorUids[]=4

https://localhost:8080/v1/estimates?filter[vendorUid][]=344&filter[vendorUid][]=344&filter[vendorUid][]=344
</code>```

I want query to be generated as below like in query :

```<code>https://localhost:8080/v1/estimates?vendorUids=[1,2,3,4,5]
</code>```

Thanks in Advance.

答:
Below code worked for me :</p>

```<code>supplierData.getEach('vendorUid').toString();
</code>```

Title: in query in Ember JS DS.store model

Body:
I have tried below both queries :

    this.store.query('estimate', { 'vendorUids' : supplierData.getEach('vendorUid') } ).then((estimatesData)=>{

});

this.store.query('estimate', { filter : { 'vendorUids' : supplierData.getEach('vendorUid') } }).then((estimatesData)=>{

});

But it is creating queries as below :

https://localhost:8080/v1/estimates?vendorUids[]=344&vendorUids[]=5&vendorUids[]=1&vendorUids[]=2&vendorUids[]=3&vendorUids[]=4

https://localhost:8080/v1/estimates?filter[vendorUid][]=344&filter[vendorUid][]=344&filter[vendorUid][]=344

I want query to be generated as below like in query :

https://localhost:8080/v1/estimates?vendorUids=[1,2,3,4,5]

Thanks in Advance.

Body:
Below code worked for me :

supplierData.getEach('vendorUid').toString();


问:
Reversi Algorithm Check
I am currently building a Reversi game where the board is a 8x8 series of integers (0 for empty space, 1 for white, and 2 for black). I have figured out how to get the vertical and horizontal to check the move and make the move, but cannot figure out how to get the diagonals working.</p>

```<code>package OthelloTesting;

public class OthelloGameHandler {
    private int[][] gameBoard = new int[8][8];

    public OthelloGameHandler() {

    }

    public void setBoard(int[][] newBoard) {
        gameBoard = newBoard;
    }

    public int[][] getBoard() {
        return gameBoard;
    }

    private final boolean inBounds(int row, int col) {
        return row >= 0 && col >= 0 && row < gameBoard.length && col < gameBoard.length;
    }

    /*
     * Color is: 0 - Empty | 1 - White | 2 - Black Return Messages: 0 - Okay | 1
     * - Piece in Spot | 2 - Not Valid Placement
     */
    public int move(int color, int row, int col) {
        // Check if spot is full
        int oppColor = (color == 1) ? 2 : 1;
        int returnCode = 2;
        if (gameBoard[row][col] != 0) {
            returnCode = 1;
        }
        if (!inBounds(row, col)) {
            returnCode = 2;
        }
        // Check if move is Valid...

        // Check Right Horizontal
        if (col < 6 && gameBoard[row][col + 1] != 0 &&
            gameBoard[row][col + 1] == oppColor) {
            for (int pos = col + 2; pos < 8; pos++) {
                if (gameBoard[row][pos] == 0) {
                    break;
                }
                if (gameBoard[row][pos] == color) {
                    fill(color, row, col, row, pos);
                    returnCode = 0;
                }
            }
        }

        // Check Left Horizontal
        if (col > 1 && gameBoard[row][col - 1] != 0 &&
            gameBoard[row][col - 1] == oppColor) {
            for (int pos = col - 2; pos > -1; pos--) {
                if (gameBoard[row][pos] == 0) {
                    break;
                }
                if (gameBoard[row][pos] == color) {
                    fill(color, row, pos, row, col);
                    returnCode = 0;
                }
            }
        }

        // Check Bottom Vertical
        if (row < 6 && gameBoard[row + 1][col] != 0 && gameBoard[row + 1][col] == oppColor) {
            for (int pos = row + 2; pos < 8; pos++) {
                System.out.println("did");
                if (gameBoard[pos][col] == 0) {
                    break;
                }
                if (gameBoard[pos][col] == color) {
                    fill(color, row, col, pos, col);
                    returnCode = 0;
                }
            }
        }

        // Check Top Vertical
        if (row > 1 && gameBoard[row - 1][col] != 0 && gameBoard[row - 1][col] == oppColor) {
            for (int pos = row - 2; pos > -1; pos++) {
                System.out.println("did");
                if (gameBoard[pos][col] == 0) {
                    break;
                }
                if (gameBoard[pos][col] == color) {
                    fill(color, pos, col, row, col);
                    returnCode = 0;
                }
            }
        }

        // Check Upper Right Diagonal

        // Check Upper Left Diagonal

        // Check Lower Left Diagonal

        // Check Lower Right Diagonal

        return returnCode;
    }

    private void fill(int color, int r1, int c1, int r2, int c2) {

        // Horizontal Filling
        if (r1 == r2) {
            for (int pos = c1; pos <= c2; pos++) {
                gameBoard[r1][pos] = color;
            }
        }
        if (c1 == c2) {
            for (int pos = r1; pos <= r2; pos++) {
                gameBoard[pos][c1] = color;
            }
        }

    }
}
</code>```

答:
I know this is C++ code and you are doing Java. But I think you can extract the main idea.

```<code>// flips discs in one direction
uint64_t flip_dir(const uint64_t P, const uint64_t O, const uint8_t move, const int dX, const int dY)
{
    uint64_t flips = 0;
    int i = (move % 8) + dX; // Starting index in x direction
    int j = (move / 8) + dY; // Starting index in y direction

    while ((i >= 0) && (i < 8) && (j >= 0) && (j < 8)) // In between boundaries
    {
        const uint64_t bit = 1ULL << (j * 8 + i); // The bit to look at
        if (O & bit) // The bit belongs to the opponent
            flips |= bit; // Add to possible flips
        else if (P & bit) // The bit belongs to the player
            return flips; // All possible flips become real flips
        else // The bit belongs to no player
            return 0; // There are no possible flips
        i += dX; // Advance in direction
        j += dY; // Advance in direction
    }
    return 0;
}

uint64_t flip(const uint64_t P, const uint64_t O, const uint8_t move)
{
    return move == 64 ? 0ULL :
           flip_dir(P, O, move, -1, -1)
         | flip_dir(P, O, move, -1,  0)
         | flip_dir(P, O, move, -1, +1)
         | flip_dir(P, O, move,  0, -1)
         | flip_dir(P, O, move,  0, +1)
         | flip_dir(P, O, move, +1, -1)
         | flip_dir(P, O, move, +1,  0)
         | flip_dir(P, O, move, +1, +1);
}
</code>```

Happy disc flipping ;-)

Title: Reversi Algorithm Check

Body:
I am currently building a Reversi game where the board is a 8x8 series of integers (0 for empty space, 1 for white, and 2 for black). I have figured out how to get the vertical and horizontal to check the move and make the move, but cannot figure out how to get the diagonals working.

package OthelloTesting;

public class OthelloGameHandler {
    private int[][] gameBoard = new int[8][8];

    public OthelloGameHandler() {

    }

    public void setBoard(int[][] newBoard) {
        gameBoard = newBoard;
    }

    public int[][] getBoard() {
        return gameBoard;
    }

    private final boolean inBounds(int row, int col) {
        return row >= 0 && col >= 0 && row < gameBoard.length && col < gameBoard.length;
    }

    /*
     * Color is: 0 - Empty | 1 - White | 2 - Black Return Messages: 0 - Okay | 1
     * - Piece in Spot | 2 - Not Valid Placement
     */
    public int move(int color, int row, int col) {
        // Check if spot is full
        int oppColor = (color == 1) ? 2 : 1;
        int returnCode = 2;
        if (gameBoard[row][col] != 0) {
            returnCode = 1;
        }
        if (!inBounds(row, col)) {
            returnCode = 2;
        }
        // Check if move is Valid...

        // Check Right Horizontal
        if (col < 6 && gameBoard[row][col + 1] != 0 &&
            gameBoard[row][col + 1] == oppColor) {
            for (int pos = col + 2; pos < 8; pos++) {
                if (gameBoard[row][pos] == 0) {
                    break;
                }
                if (gameBoard[row][pos] == color) {
                    fill(color, row, col, row, pos);
                    returnCode = 0;
                }
            }
        }

        // Check Left Horizontal
        if (col > 1 && gameBoard[row][col - 1] != 0 &&
            gameBoard[row][col - 1] == oppColor) {
            for (int pos = col - 2; pos > -1; pos--) {
                if (gameBoard[row][pos] == 0) {
                    break;
                }
                if (gameBoard[row][pos] == color) {
                    fill(color, row, pos, row, col);
                    returnCode = 0;
                }
            }
        }

        // Check Bottom Vertical
        if (row < 6 && gameBoard[row + 1][col] != 0 && gameBoard[row + 1][col] == oppColor) {
            for (int pos = row + 2; pos < 8; pos++) {
                System.out.println("did");
                if (gameBoard[pos][col] == 0) {
                    break;
                }
                if (gameBoard[pos][col] == color) {
                    fill(color, row, col, pos, col);
                    returnCode = 0;
                }
            }
        }

        // Check Top Vertical
        if (row > 1 && gameBoard[row - 1][col] != 0 && gameBoard[row - 1][col] == oppColor) {
            for (int pos = row - 2; pos > -1; pos++) {
                System.out.println("did");
                if (gameBoard[pos][col] == 0) {
                    break;
                }
                if (gameBoard[pos][col] == color) {
                    fill(color, pos, col, row, col);
                    returnCode = 0;
                }
            }
        }

        // Check Upper Right Diagonal

        // Check Upper Left Diagonal

        // Check Lower Left Diagonal

        // Check Lower Right Diagonal

        return returnCode;
    }

    private void fill(int color, int r1, int c1, int r2, int c2) {

        // Horizontal Filling
        if (r1 == r2) {
            for (int pos = c1; pos <= c2; pos++) {
                gameBoard[r1][pos] = color;
            }
        }
        if (c1 == c2) {
            for (int pos = r1; pos <= r2; pos++) {
                gameBoard[pos][c1] = color;
            }
        }

    }
}

Body:
I know this is C++ code and you are doing Java. But I think you can extract the main idea.

// flips discs in one direction
uint64_t flip_dir(const uint64_t P, const uint64_t O, const uint8_t move, const int dX, const int dY)
{
    uint64_t flips = 0;
    int i = (move % 8) + dX; // Starting index in x direction
    int j = (move / 8) + dY; // Starting index in y direction

    while ((i >= 0) && (i < 8) && (j >= 0) && (j < 8)) // In between boundaries
    {
        const uint64_t bit = 1ULL << (j * 8 + i); // The bit to look at
        if (O & bit) // The bit belongs to the opponent
            flips |= bit; // Add to possible flips
        else if (P & bit) // The bit belongs to the player
            return flips; // All possible flips become real flips
        else // The bit belongs to no player
            return 0; // There are no possible flips
        i += dX; // Advance in direction
        j += dY; // Advance in direction
    }
    return 0;
}

uint64_t flip(const uint64_t P, const uint64_t O, const uint8_t move)
{
    return move == 64 ? 0ULL :
           flip_dir(P, O, move, -1, -1)
         | flip_dir(P, O, move, -1,  0)
         | flip_dir(P, O, move, -1, +1)
         | flip_dir(P, O, move,  0, -1)
         | flip_dir(P, O, move,  0, +1)
         | flip_dir(P, O, move, +1, -1)
         | flip_dir(P, O, move, +1,  0)
         | flip_dir(P, O, move, +1, +1);
}

Happy disc flipping ;-)


问:
c- pointer from integer without cast
I'm trying to create a extended binary tree in a main function with finite number of nodes.

The problem is that compliler keeps showing

error: incopatible types when assigning to type 'struct node' from type 'int'

This is my code:

```<code>#include <stdio.h>
#include <stdlib.h>
#define NULLitem (-1)

typedef struct node * link;
struct node {
    int item;
    link l;
    link r;
}

link NEW (int item, link l, link r)
{
        link x = malloc(sizeof * x);
        x->item = item;
        x->l = l;
        x->r = r;
        return x;
}

void Tprint(link p, int indent)
{
    int i;
    if (p!=NULL){
        Tprint(p->r, indent+4);
        for(i=0; i<indent; i++)
            printf(" ");
        printf("%d\n", p->item);
        Tprint(p->l,indent+4);
    }
}

int main(void)
{
    link T, M, N, z, Root;
    z = NEW(NULLitem,NULL,NULL);
    Root->item = 6;
    T = NEW(5, NULL, NULL);
    Root->l = T;

    M = NEW(7, NULL, NULL);
    Root->r = M;
    M->l= NEW(NULLitem, NULL, NULL);
    M->r= NEW(9,z,z);

    N = NEW(2,z,z);
    T->l = N;
    T->r = NEW(NULLitem,NULL, NULL);

    Tprint(Root,3);
    return 0;
}
</code>```

答:
The error is on line 12 (the compiler says it all), "Pointer from integer without cast" is a warning which will disappear if you correct the error on line 12 of your program.

You actually forgot the semicolon here at:

```<code>struct node {   int item;
                link l;
                link r;
        }
</code>```

Write a semicolon after the braces, your program should be like:

```<code>#include <stdio.h>
#include <stdlib.h>
#define NULLitem (-1)

typedef struct node * link;
struct node {   int item;
                link l;
                link r;
        };

link NEW (int item, link l, link r){
        link x = malloc(sizeof * x);
        x->item = item;
        x->l = l;
        x->r = r;
        return x;
}

void Tprint(link p, int indent){
        int i;
        if (p!=NULL){
                Tprint(p->r, indent+4);
                for(i=0; i<indent; i++)
                        printf(" ");
                printf("%d\n", p->item);
                Tprint(p->l,indent+4);
        }
}

int main(void)
{
   link T, M, N, z, Root;
    z = NEW(NULLitem,NULL,NULL);
    Root->item = 6;
   T = NEW(5, NULL, NULL);
     Root->l = T;

   M = NEW(7, NULL, NULL);
   Root->r = M;
    M->l= NEW(NULLitem, NULL, NULL);
    M->r= NEW(9,z,z);

   N = NEW(2,z,z);
    T->l = N;
    T->r = NEW(NULLitem,NULL, NULL);

    Tprint(Root,3);
    return 0;
}
</code>```

The output would be like:

```<code>           -1
       9
           -1
   7
       -1    6
       -1
   5
           -1
       2
           -1
</code>```

Runs without any errors.

Title: c- pointer from integer without cast

Body:
I'm trying to create a extended binary tree in a main function with finite number of nodes.

The problem is that compliler keeps showing

error: incopatible types when assigning to type 'struct node' from type 'int'

This is my code:

#include <stdio.h>
#include <stdlib.h>
#define NULLitem (-1)

typedef struct node * link;
struct node {
    int item;
    link l;
    link r;
}

link NEW (int item, link l, link r)
{
        link x = malloc(sizeof * x);
        x->item = item;
        x->l = l;
        x->r = r;
        return x;
}

void Tprint(link p, int indent)
{
    int i;
    if (p!=NULL){
        Tprint(p->r, indent+4);
        for(i=0; i<indent; i++)
            printf(" ");
        printf("%d\n", p->item);
        Tprint(p->l,indent+4);
    }
}

int main(void)
{
    link T, M, N, z, Root;
    z = NEW(NULLitem,NULL,NULL);
    Root->item = 6;
    T = NEW(5, NULL, NULL);
    Root->l = T;

    M = NEW(7, NULL, NULL);
    Root->r = M;
    M->l= NEW(NULLitem, NULL, NULL);
    M->r= NEW(9,z,z);

    N = NEW(2,z,z);
    T->l = N;
    T->r = NEW(NULLitem,NULL, NULL);

    Tprint(Root,3);
    return 0;
}

Body:
The error is on line 12 (the compiler says it all), "Pointer from integer without cast" is a warning which will disappear if you correct the error on line 12 of your program.

You actually forgot the semicolon here at:

struct node {   int item;
                link l;
                link r;
        }

Write a semicolon after the braces, your program should be like:

#include <stdio.h>
#include <stdlib.h>
#define NULLitem (-1)

typedef struct node * link;
struct node {   int item;
                link l;
                link r;
        };

link NEW (int item, link l, link r){
        link x = malloc(sizeof * x);
        x->item = item;
        x->l = l;
        x->r = r;
        return x;
}

void Tprint(link p, int indent){
        int i;
        if (p!=NULL){
                Tprint(p->r, indent+4);
                for(i=0; i<indent; i++)
                        printf(" ");
                printf("%d\n", p->item);
                Tprint(p->l,indent+4);
        }
}

int main(void)
{
   link T, M, N, z, Root;
    z = NEW(NULLitem,NULL,NULL);
    Root->item = 6;
   T = NEW(5, NULL, NULL);
     Root->l = T;

   M = NEW(7, NULL, NULL);
   Root->r = M;
    M->l= NEW(NULLitem, NULL, NULL);
    M->r= NEW(9,z,z);

   N = NEW(2,z,z);
    T->l = N;
    T->r = NEW(NULLitem,NULL, NULL);

    Tprint(Root,3);
    return 0;
}

The output would be like:

           -1
       9
           -1
   7
       -1    6
       -1
   5
           -1
       2
           -1

Runs without any errors.


问:
Break statement misplaced in while-loop
I'd like to create a script that asks for the item you want from a list (array), check if the item is on stock, displays the inventory if your type "list" and quit the program (while loop) if you type "quit"

while (true) { // endless loop
  var search = prompt('Type the item you are looking for, type "list" to display the inventory, type "quit" to exit te store.');
  search = search.toLowerCase;
}
if (search = 'quit') {
  break; // if the client types quit, they exit the store, loop ends
} else if search == 'list'{
  write('
We currently have ' + inventory.join(', ') + ' in stock.
');
} else if (inventory.indexOf(search) > - 1) {
  write('
Yes, we have ' + search + ' in our stock.
');
} else {
  write('
Sorry, we don\'t have ' + search + ' in our stock
');
}```

The break statement is out of the loop but I don't really see where it should go ...

Any thoughts?

答:
You have atleast three Errors in your code:

First the if is outside of the Loop.
second you miss brackets arround one if Statement.
Third in the first if Statement you miss the second equals sign

var search='1';
while (true) { // endless loop
  var search = prompt('Type the item you are looking for, type "list" to display the inventory, type "quit" to exit te store.');
  search = search.toLowerCase;

if (search == 'quit') {
  break; // if the client types quit, they exit the store, loop ends
} else if (search == 'list'){
  write('
We currently have ' + inventory.join(', ') + ' in stock.
');
} else if (inventory.indexOf(search) > - 1) {
  write('
Yes, we have ' + search + ' in our stock.
');
} else {
  write('
Sorry, we don\'t have ' + search + ' in our stock
');
}
}```

Title: Break statement misplaced in while-loop

Body:
I'd like to create a script that asks for the item you want from a list (array), check if the item is on stock, displays the inventory if your type "list" and quit the program (while loop) if you type "quit"

while (true) { // endless loop
  var search = prompt('Type the item you are looking for, type "list" to display the inventory, type "quit" to exit te store.');
  search = search.toLowerCase;
}
if (search = 'quit') {
  break; // if the client types quit, they exit the store, loop ends
} else if search == 'list'{
  write('
We currently have ' + inventory.join(', ') + ' in stock.
');
} else if (inventory.indexOf(search) > - 1) {
  write('
Yes, we have ' + search + ' in our stock.
');
} else {
  write('
Sorry, we don\'t have ' + search + ' in our stock
');
}

The break statement is out of the loop but I don't really see where it should go ...

Any thoughts?

Body:
You have atleast three Errors in your code:

First the if is outside of the Loop.
second you miss brackets arround one if Statement.
Third in the first if Statement you miss the second equals sign

var search='1';
while (true) { // endless loop
  var search = prompt('Type the item you are looking for, type "list" to display the inventory, type "quit" to exit te store.');
  search = search.toLowerCase;

if (search == 'quit') {
  break; // if the client types quit, they exit the store, loop ends
} else if (search == 'list'){
  write('<p>We currently have ' + inventory.join(', ') + ' in stock.</p>');
} else if (inventory.indexOf(search) > - 1) {
  write('<p>Yes, we have ' + search + ' in our stock.</p>');
} else {
  write('<p>Sorry, we don\'t have ' + search + ' in our stock</p>');
}
}


问:
How can I tell RestTemplate to POST with UTF-8 encoding?
I'm having problems posting JSON with UTF-8 encoding using RestTemplate. Default encoding for JSON is UTF-8 so the media type shouldn't even contain the charset. I have tried to put charset in the MediaType but it doesn't seem to work anyway.

My code:

```<code>String dataJson = "{\"food\": \"smörrebröd\"}";
HttpHeaders headers = new HttpHeaders();
MediaType mediaType = new MediaType("application", "json", StandardCharsets.UTF_8);
headers.setContentType(mediaType);

HttpEntity<String> entity = new HttpEntity<String>(dataJson, headers);
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<Boolean> formEntity = restTemplate.exchange(postUrl, HttpMethod.POST, entity, Boolean.class);
</code>```

答:
The answer by @mushfek0001 produce two StringHttpMessageConverter which will send two text/plain and */*, such as the debug picture.

Even the Accept header of client will be:

```<code>text/plain, text/plain, */*, */*
</code>```

So the better one is remove the ISO-8859-1 StringHttpMessageConverter and use single UTF-8 StringHttpMessageConverter.

Use this:

```<code>RestTemplate restTemplate = new RestTemplate();
StringHttpMessageConverter stringHttpMessageConverter = new StringHttpMessageConverter(StandardCharsets.UTF_8);
stringHttpMessageConverter.setWriteAcceptCharset(true);
for (int i = 0; i < restTemplate.getMessageConverters().size(); i++) {
    if (restTemplate.getMessageConverters().get(i) instanceof StringHttpMessageConverter) {
        restTemplate.getMessageConverters().remove(i);
        restTemplate.getMessageConverters().add(i, stringHttpMessageConverter);
        break;
    }
}
</code>```

Body:
I'm having problems posting JSON with UTF-8 encoding using RestTemplate. Default encoding for JSON is UTF-8 so the media type shouldn't even contain the charset. I have tried to put charset in the MediaType but it doesn't seem to work anyway.

My code:

String dataJson = "{\"food\": \"smörrebröd\"}";
HttpHeaders headers = new HttpHeaders();
MediaType mediaType = new MediaType("application", "json", StandardCharsets.UTF_8);
headers.setContentType(mediaType);

HttpEntity<String> entity = new HttpEntity<String>(dataJson, headers);
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<Boolean> formEntity = restTemplate.exchange(postUrl, HttpMethod.POST, entity, Boolean.class);

Body:
The answer by @mushfek0001 produce two StringHttpMessageConverter which will send two text/plain and */*, such as the debug picture.

Even the Accept header of client will be:

text/plain, text/plain, */*, */*

So the better one is remove the ISO-8859-1 StringHttpMessageConverter and use single UTF-8 StringHttpMessageConverter.

Use this:

RestTemplate restTemplate = new RestTemplate();
StringHttpMessageConverter stringHttpMessageConverter = new StringHttpMessageConverter(StandardCharsets.UTF_8);
stringHttpMessageConverter.setWriteAcceptCharset(true);
for (int i = 0; i < restTemplate.getMessageConverters().size(); i++) {
    if (restTemplate.getMessageConverters().get(i) instanceof StringHttpMessageConverter) {
        restTemplate.getMessageConverters().remove(i);
        restTemplate.getMessageConverters().add(i, stringHttpMessageConverter);
        break;
    }
}


问:
Listing all the child nodes of document element
I have a very huge XML file and i want to list down all the child nodes for document element.
I am using the below code which is working fine but it is taking very long time to process the file and also it is getting data from the document element which is not required:

```<code>use XML::Simple;
my $xml = XML::Simple->new();
my $d = $xml->XMLin("sample.xml");
my @arr = keys %$d;
print "@arr\n";
</code>```

Example XML:

```<code>    <?xml version="1.0" encoding="ISO-8859-15"?>
<document version="1.0" createdAt="2017-03-31T11:41:34">
   <TITLE>Computer Parts</TITLE>
   <PART001>
      <ITEM>Motherboard</ITEM>
      <MANUFACTURER>ASUS</MANUFACTURER>
      <MODEL>P3B-F</MODEL>
      <COST> 123.00</COST>
   </PART001>
   <PART002>
      <ITEM>Video Card</ITEM>
      <MANUFACTURER>ATI</MANUFACTURER>
      <MODEL>All-in-Wonder Pro</MODEL>
      <COST> 160.00</COST>
   </PART002>
   <PART003>
      <ITEM>Sound Card</ITEM>
      <MANUFACTURER>Creative Labs</MANUFACTURER>
      <MODEL>Sound Blaster Live</MODEL>
      <COST> 80.00</COST>
   </PART003>
   <PART004>
      <ITEM>14 inch Monitor</ITEM>
      <MANUFACTURER>LG Electronics</MANUFACTURER>
      <MODEL> 995E</MODEL>
      <COST> 290.00</COST>
   </PART004>
</document>
</code>```

Expected Output:
TITLE,
PART001,
PART002,
PART003,
PART004

Can anyone please suggest a faster and better way to get the required output?

答:
By using XML::LibXML and XPath.

```<code>use 5.014;
use warnings;
use XML::LibXML;

my $file = 'xml';
my $dom = XML::LibXML->load_xml(location => $file);

for my $child ($dom->findnodes( q{//document/*} )) {
    say $child->nodeName();
}
</code>```

output

```<code>TITLE
PART001
PART002
PART003
PART004
</code>```

or just for the case, if you need only the PARTs

```<code>for my $part ($dom->findnodes( q{//*[contains(name(),'PART')]} )) {
    say $part->nodeName();
}
</code>```

output

```<code>PART001
PART002
PART003
PART004
</code>```

EDIT: Using the pull parser (doesn't loads the whole xml into memory):

```<code>use 5.014;
use warnings;
use XML::LibXML::Reader qw(XML_READER_TYPE_ELEMENT);

my $file="xml";
my $reader = XML::LibXML::Reader->new(location => $file) or die "problem $!";

while($reader->read()) {
        if( $reader->depth == 1 && $reader->nodeType == XML_READER_TYPE_ELEMENT ) {
                say $reader->name;
        }
}

TITLE
PART001
PART002
PART003
PART004
</code>```

EDIT2

```<code>use 5.014;
use warnings;

use XML::LibXML::Reader qw(XML_READER_TYPE_ELEMENT);
my $file="xml";

my $reader = XML::LibXML::Reader->new(location => $file) or die "problem $!";
my $indoc;
while($reader->read()) {
        # sets the flag in youre inside the <document>
        if( $reader->name eq 'document' ) {
                $indoc = $reader->nodeType == XML_READER_TYPE_ELEMENT ? 1 : 0;
        }
        # all nodes with level 1 if they're inside of the <document>
        if( $indoc &&  $reader->depth == 1 && $reader->nodeType == XML_READER_TYPE_ELEMENT ) {
                say $reader->name;
        }
}
</code>```

Body:
I have a very huge XML file and i want to list down all the child nodes for document element.
I am using the below code which is working fine but it is taking very long time to process the file and also it is getting data from the document element which is not required:

use XML::Simple;
my $xml = XML::Simple->new();
my $d = $xml->XMLin("sample.xml");
my @arr = keys %$d;
print "@arr\n";

Example XML:

    <?xml version="1.0" encoding="ISO-8859-15"?>
<document version="1.0" createdAt="2017-03-31T11:41:34">
   <TITLE>Computer Parts</TITLE>
   <PART001>
      <ITEM>Motherboard</ITEM>
      <MANUFACTURER>ASUS</MANUFACTURER>
      <MODEL>P3B-F</MODEL>
      <COST> 123.00</COST>
   </PART001>
   <PART002>
      <ITEM>Video Card</ITEM>
      <MANUFACTURER>ATI</MANUFACTURER>
      <MODEL>All-in-Wonder Pro</MODEL>
      <COST> 160.00</COST>
   </PART002>
   <PART003>
      <ITEM>Sound Card</ITEM>
      <MANUFACTURER>Creative Labs</MANUFACTURER>
      <MODEL>Sound Blaster Live</MODEL>
      <COST> 80.00</COST>
   </PART003>
   <PART004>
      <ITEM>14 inch Monitor</ITEM>
      <MANUFACTURER>LG Electronics</MANUFACTURER>
      <MODEL> 995E</MODEL>
      <COST> 290.00</COST>
   </PART004>
</document>

Expected Output:
TITLE,
PART001,
PART002,
PART003,
PART004

Can anyone please suggest a faster and better way to get the required output?

Body:
By using XML::LibXML and XPath.

use 5.014;
use warnings;
use XML::LibXML;

my $file = 'xml';
my $dom = XML::LibXML->load_xml(location => $file);

for my $child ($dom->findnodes( q{//document/*} )) {
    say $child->nodeName();
}

output

TITLE
PART001
PART002
PART003
PART004

or just for the case, if you need only the PARTs

for my $part ($dom->findnodes( q{//*[contains(name(),'PART')]} )) {
    say $part->nodeName();
}

output

PART001
PART002
PART003
PART004

EDIT: Using the pull parser (doesn't loads the whole xml into memory):

use 5.014;
use warnings;
use XML::LibXML::Reader qw(XML_READER_TYPE_ELEMENT);

my $file="xml";
my $reader = XML::LibXML::Reader->new(location => $file) or die "problem $!";

while($reader->read()) {
        if( $reader->depth == 1 && $reader->nodeType == XML_READER_TYPE_ELEMENT ) {
                say $reader->name;
        }
}

TITLE
PART001
PART002
PART003
PART004

EDIT2

use 5.014;
use warnings;

use XML::LibXML::Reader qw(XML_READER_TYPE_ELEMENT);
my $file="xml";

my $reader = XML::LibXML::Reader->new(location => $file) or die "problem $!";
my $indoc;
while($reader->read()) {
        # sets the flag in youre inside the <document>
        if( $reader->name eq 'document' ) {
                $indoc = $reader->nodeType == XML_READER_TYPE_ELEMENT ? 1 : 0;
        }
        # all nodes with level 1 if they're inside of the <document>
        if( $indoc &&  $reader->depth == 1 && $reader->nodeType == XML_READER_TYPE_ELEMENT ) {
                say $reader->name;
        }
}


问:
Glitch in Safari when using backdrop filters
I'm experiencing a strange collection of glitches when using backdrop filters on a pseudo element. I'm using the blur and saturate filters.

I know that this is relatively new CSS and is only supported by Safari as far as I've read, but I'm wondering if anyone has had similar problems and if there's a workaround for this?

I have a hover menu on my website in which the submenu has a little arrow at the top. I've made this using border-left, border-right and border-bottom. I've tried to apply the same backdrop filters to the pseudo element arrow that I've applied to the submenu itself, but this is resulting in glitchy colours appearing every time I hover over the main menu link. Sometimes they work okay, but depending on their positioning over the background image, this problem does consistently occur at various viewport widths.

https://jsfiddle.net/fm1cg4n4/4/

```<code><header class="header">

  <nav class="menu">

    <ul>

      <li>Menu Link 1
        <ul>
          <li>Submenu Link 1</li>
          <li>Submenu Link 2</li>
          <li>Submenu Link 3</li>
          <li>Submenu Link 4</li>
          <li>Submenu Link 5</li>
        </ul>
      </li>

    </ul>

  </nav>

</header>

body {
  background-image: url(http://www.lucieaverillphotography.co.uk/wp-content/uploads/2017/01/15974858_10154941714967990_2444361563480701659_o.jpg);
  background-size:cover;
}

.header {
  position:absolute;
  height:55px;
  width:100%;
}

nav ul {
  display:flex;
  height:55px;
  margin:0;
  padding:0;
}

nav ul li {
  padding:10px;
  list-style:none;
  color:#fff;
}

nav ul ul {
  position:absolute;
  top:100%;
  left:10px;
  z-index:10;
  display:block;
  min-width:185px;
  height:auto;
  padding: 2px 0px;
  background-color:#ffffff;
  opacity:0;
  pointer-events:none;

  background-color: rgba(255, 255, 255, 0.5);
  -webkit-backdrop-filter: blur(7px) saturate(200%);
    backdrop-filter: blur(7px) saturate(200%);
  border-style:none;

  transition: opacity 0.5s ease 0s;
}

nav ul li:hover ul {
  pointer-events:auto;
  opacity:1;
}

nav ul ul:before {
  content: "";
  position: absolute;
  z-index: 1;
  bottom: 100%;
  left: 26px;
  margin-top: -2px;

  border-left: 10px solid transparent;
  border-right: 10px solid transparent;
  border-bottom: 10px solid rgba(255, 255, 255, 0.5);
  -webkit-backdrop-filter: blur(7px) saturate(200%);
  backdrop-filter: blur(7px) saturate(200%);
}

nav ul ul li {
  color:#444;
}
</code>```

答:
In pseudo 'nav ul ul:before' remove filters. Update your css to the following:

```<code>nav ul ul:before {
  content: "";
  position: absolute;
  z-index: 1;
  bottom: 100%;
  left: 26px;
  margin-top: -2px;

  border-left: 10px solid transparent;
  border-right: 10px solid transparent;
  border-bottom: 10px solid rgba(255, 255, 255, 0.5);
}
</code>```

Remove:

-webkit-backdrop-filter: blur(7px) saturate(200%);

backdrop-filter: blur(7px) saturate(200%);

Check https://jsfiddle.net/codeMonk/fm1cg4n4/5/ in safari.

This should do the job.

Body:
I'm experiencing a strange collection of glitches when using backdrop filters on a pseudo element. I'm using the blur and saturate filters.

I know that this is relatively new CSS and is only supported by Safari as far as I've read, but I'm wondering if anyone has had similar problems and if there's a workaround for this?

I have a hover menu on my website in which the submenu has a little arrow at the top. I've made this using border-left, border-right and border-bottom. I've tried to apply the same backdrop filters to the pseudo element arrow that I've applied to the submenu itself, but this is resulting in glitchy colours appearing every time I hover over the main menu link. Sometimes they work okay, but depending on their positioning over the background image, this problem does consistently occur at various viewport widths.

https://jsfiddle.net/fm1cg4n4/4/

Menu Link 1

Submenu Link 1

Submenu Link 2

Submenu Link 3

Submenu Link 4

Submenu Link 5

body {
  background-image: url(http://www.lucieaverillphotography.co.uk/wp-content/uploads/2017/01/15974858_10154941714967990_2444361563480701659_o.jpg);
  background-size:cover;
}

.header {
  position:absolute;
  height:55px;
  width:100%;
}

nav ul {
  display:flex;
  height:55px;
  margin:0;
  padding:0;
}

nav ul li {
  padding:10px;
  list-style:none;
  color:#fff;
}

nav ul ul {
  position:absolute;
  top:100%;
  left:10px;
  z-index:10;
  display:block;
  min-width:185px;
  height:auto;
  padding: 2px 0px;
  background-color:#ffffff;
  opacity:0;
  pointer-events:none;

  background-color: rgba(255, 255, 255, 0.5);
  -webkit-backdrop-filter: blur(7px) saturate(200%);
    backdrop-filter: blur(7px) saturate(200%);
  border-style:none;

  transition: opacity 0.5s ease 0s;
}

nav ul li:hover ul {
  pointer-events:auto;
  opacity:1;
}

nav ul ul:before {
  content: "";
  position: absolute;
  z-index: 1;
  bottom: 100%;
  left: 26px;
  margin-top: -2px;

  border-left: 10px solid transparent;
  border-right: 10px solid transparent;
  border-bottom: 10px solid rgba(255, 255, 255, 0.5);
  -webkit-backdrop-filter: blur(7px) saturate(200%);
  backdrop-filter: blur(7px) saturate(200%);
}

nav ul ul li {
  color:#444;
}

Body:
In pseudo 'nav ul ul:before' remove filters. Update your css to the following:

nav ul ul:before {
  content: "";
  position: absolute;
  z-index: 1;
  bottom: 100%;
  left: 26px;
  margin-top: -2px;

  border-left: 10px solid transparent;
  border-right: 10px solid transparent;
  border-bottom: 10px solid rgba(255, 255, 255, 0.5);
}

Remove:

-webkit-backdrop-filter: blur(7px) saturate(200%);

backdrop-filter: blur(7px) saturate(200%);

Check https://jsfiddle.net/codeMonk/fm1cg4n4/5/ in safari.

This should do the job.


答:
Try this. You had misplaced bracket and also missed == in the if statement;

while (true) { // endless loop
  var search = prompt('Type the item you are looking for, type "list" to display the inventory, type "quit" to exit te store.');
  search = search.toLowerCase;

if (search == 'quit') {
  break; // if the client types quit, they exit the store, loop ends
} else if search == 'list'{
  write('
We currently have ' + inventory.join(', ') + ' in stock.
');
} else if (inventory.indexOf(search) > - 1) {
  write('
Yes, we have ' + search + ' in our stock.
');
} else {
  write('
Sorry, we don\'t have ' + search + ' in our stock
');
}
}```

Title: Break statement misplaced in while-loop

Body:
Try this. You had misplaced bracket and also missed == in the if statement;

while (true) { // endless loop
  var search = prompt('Type the item you are looking for, type "list" to display the inventory, type "quit" to exit te store.');
  search = search.toLowerCase;

if (search == 'quit') {
  break; // if the client types quit, they exit the store, loop ends
} else if search == 'list'{
  write('<p>We currently have ' + inventory.join(', ') + ' in stock.</p>');
} else if (inventory.indexOf(search) > - 1) {
  write('<p>Yes, we have ' + search + ' in our stock.</p>');
} else {
  write('<p>Sorry, we don\'t have ' + search + ' in our stock</p>');
}
}


问:
Struts 2 extension changed, redirect when external link .action
Using below struts.xml setting, changing action extension from .action to .html was a success.

<constant name="struts.action.extension" value="html"/>

However, the old links from Google search results or other external links are still pointed to .action url, it always redirect to no page found error when clicked.
Is there anyway I can redirect those .action url to latest .html links?

答:
Here is the code for the interceptor that replaces .action url to .html.
Don't forget to declare the added interceptor in struts.xml.
I hope it will be helpful to others looking for it. ;)</p>

```<code>@Override
public String intercept(ActionInvocation actioninvocation) throws Exception {
    HttpServletRequest request = ServletActionContext.getRequest();
    HttpServletResponse response = ServletActionContext.getResponse();
    StringBuffer url = request.getRequestURL();
    if(url != null && url.indexOf(".action") > 0) {
        String fullUrl = url.toString().replace(".action", ".html");
        String queryString = request.getQueryString();
        fullUrl += (queryString == null ? "" : ("?" + queryString));
        // return new url with .html
        response.sendRedirect(fullUrl);
    }
    return actioninvocation.invoke();
}
</code>```

Body:
Here is the code for the interceptor that replaces .action url to .html.
Don't forget to declare the added interceptor in struts.xml.
I hope it will be helpful to others looking for it. ;)

@Override
public String intercept(ActionInvocation actioninvocation) throws Exception {
    HttpServletRequest request = ServletActionContext.getRequest();
    HttpServletResponse response = ServletActionContext.getResponse();
    StringBuffer url = request.getRequestURL();
    if(url != null && url.indexOf(".action") > 0) {
        String fullUrl = url.toString().replace(".action", ".html");
        String queryString = request.getQueryString();
        fullUrl += (queryString == null ? "" : ("?" + queryString));
        // return new url with .html
        response.sendRedirect(fullUrl);
    }
    return actioninvocation.invoke();
}


问:
PostgreSQL, Hibernate : Default increase sequence length by 1
I am working on a Spring-MVC project in which we are using Hibernate as our ORM and PostgreSQL as the database. We have a Students class, whose ID we are using in one of the PDF form generated, and for business reasons we require that the number be incremented by 1 always. I checked that the allocation-size parameter can be changed for Hibernate, but does it also effect the underlying sequence in PostgreSQL or do I have to create a new one?

If the underlying sequence is not altered by Hibernate, how can I change the sequence so that it's auto-incremented by 1 in PostgreSQL. Thank you.

Code :

```<code>  @Id
    @Column(name="studentid")
    @GeneratedValue(strategy = GenerationType.SEQUENCE,generator = "student_gen")
    @SequenceGenerator(name = "student_gen",sequenceName = "student_seq",allocationSize = 1)
    private int studentid;
</code>```

答:
No, the sequence in Postgres won't be changed just by modifying the Hibernate annotation.

You can use ALTER SEQUENCE student_seq INCREMENT BY 1 to modify the sequence.

Body:
I am working on a Spring-MVC project in which we are using Hibernate as our ORM and PostgreSQL as the database. We have a Students class, whose ID we are using in one of the PDF form generated, and for business reasons we require that the number be incremented by 1 always. I checked that the allocation-size parameter can be changed for Hibernate, but does it also effect the underlying sequence in PostgreSQL or do I have to create a new one?

If the underlying sequence is not altered by Hibernate, how can I change the sequence so that it's auto-incremented by 1 in PostgreSQL. Thank you.

Code :

  @Id
    @Column(name="studentid")
    @GeneratedValue(strategy = GenerationType.SEQUENCE,generator = "student_gen")
    @SequenceGenerator(name = "student_gen",sequenceName = "student_seq",allocationSize = 1)
    private int studentid;


问:
Show/Hiding a UIBarButtonItem, located in the middle of a UIToolbar
I've read a couple similar questions regarding this topic on StackOverflow, but none of them apply to my case.

I have a UIToolbar on my application.  The ToolBar has a layout like the following.

```<code>(Button #1) (Button #2) (Button #3) <--- Flex Controller ---> (Button #4)
</code>```

What is the most efficient way to Show/Hide the Button #3 UIBarButtonItem since it is in the middle of the UIToolbar?

FOLLOW-UP

I am aware of the setItems:Animated method, but this seems like it could be problematic because all of my buttons are wired through IB and they have associated IBActions.

Does this mean that I, therefore, need to find a way to retain my Button #3 when it is hidden (since I am using ARC?)  I'm looking for the most optimal/efficient method for adding and removing these objects.  If I must recreate this list each time I have to show/hide my #3 button, that's what I will do.

It just seems so inefficient.

答:
With existing references to toolbar items item1, item2 and item3, the most straightforward way is to remove all items and then re-add each item in the order you want it. This code is written from the perspective of being within a UIToolbar subclass:

```<code>let flexSpace: UIBarButtonItem = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.flexibleSpace, target: nil, action: nil)
let fixedSpace: UIBarButtonItem = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.fixedSpace, target: nil, action: nil)

self.items?.removeAll()
self.items?.append(flexSpace)
self.items?.append(item1)
self.items?.append(fixedSpace)
self.items?.append(item3)
self.items?.append(fixedSpace)
self.items?.append(item2)
</code>```

These item references can be from IBOutlets. Change these references to be strong rather than the IB-inserted-default weak references, so that the UIToolbar will maintain references to these items even when they have been removed, thus maintaining the relevant IBAction function relationships.

To remove a specific item from your UIToolbar from within a UIToolbar subclass, without having to re-set all items:

```<code>if let index = self.items?.index(of: buttonToRemove) {
    self.items?.remove(at: index)
}
</code>```

If not within a UIToolbar subclass, simply replace self with a reference to the UIToolbar throughout.

Body:
I've read a couple similar questions regarding this topic on StackOverflow, but none of them apply to my case.

I have a UIToolbar on my application.  The ToolBar has a layout like the following.

(Button #1) (Button #2) (Button #3) <--- Flex Controller ---> (Button #4)

What is the most efficient way to Show/Hide the Button #3 UIBarButtonItem since it is in the middle of the UIToolbar?

FOLLOW-UP

I am aware of the setItems:Animated method, but this seems like it could be problematic because all of my buttons are wired through IB and they have associated IBActions.

Does this mean that I, therefore, need to find a way to retain my Button #3 when it is hidden (since I am using ARC?)  I'm looking for the most optimal/efficient method for adding and removing these objects.  If I must recreate this list each time I have to show/hide my #3 button, that's what I will do.

It just seems so inefficient.

Body:
With existing references to toolbar items item1, item2 and item3, the most straightforward way is to remove all items and then re-add each item in the order you want it. This code is written from the perspective of being within a UIToolbar subclass:

let flexSpace: UIBarButtonItem = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.flexibleSpace, target: nil, action: nil)
let fixedSpace: UIBarButtonItem = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.fixedSpace, target: nil, action: nil)

self.items?.removeAll()
self.items?.append(flexSpace)
self.items?.append(item1)
self.items?.append(fixedSpace)
self.items?.append(item3)
self.items?.append(fixedSpace)
self.items?.append(item2)

These item references can be from IBOutlets. Change these references to be strong rather than the IB-inserted-default weak references, so that the UIToolbar will maintain references to these items even when they have been removed, thus maintaining the relevant IBAction function relationships.

To remove a specific item from your UIToolbar from within a UIToolbar subclass, without having to re-set all items:

if let index = self.items?.index(of: buttonToRemove) {
    self.items?.remove(at: index)
}

If not within a UIToolbar subclass, simply replace self with a reference to the UIToolbar throughout.


问:
Configure maven cargo plugin jetty container for static content
I need to configure jetty running from the maven cargo plugin to point it at static content, Ive looked through the jetty documentation and I cant see how to apply the configuration to jetty when it is running as part of cargo. I want to configure the webApp section and set the resource base as my angular app built as a module of this build:

```<code> <execution>
                  <id>start jetty - angular webapp</id>
                  <phase>pre-integration-test</phase>
                  <goals>
                    <goal>start</goal>
                  </goals>
                  <configuration>
                        <container>
                            <containerId>jetty7x</containerId>
                            <type>embedded</type>
                        </container>
                        <webApp>
                            <resourceBases>
                                <contextPath>/</contextPath>
                                <resourceBase>../calculator-web/dist</resourceBase>
                            </resourceBases>
                        </webApp>
                        <configuration>
                            <properties>
                                <cargo.servlet.port>11000</cargo.servlet.port>
                            </properties>
                        </configuration>
                    </configuration>
                </execution>
</code>```

Jetty starts but it seems to ignore this configuration and I just get a 404 for my index.html file.

Can somebody point me in the right direction please?

答:
Although cargo does not seem to support Jetty's reload or automatic hot redeploy feature directly, at least you can serve your 'unfinished' static content and immediately pick up changes, e.g. during development while running an embedded container.

My current solution is to reconfigure Jetty's DefaultServlet, pointing the resourceBase to the project's 'live' source directory (e.g. ${basedir}/src/main/webapp) rather than the deployable's default (build) <location/> (e.g. ${project.build.directory}/${project.build.finalName}), and (just to be sure) disabling useFileMappedBuffer to avoid file locking in Windows:

Copy Jetty's webdefault.xml (from e.g. target/cargo/configurations/jetty.../etc/ when running the cargo container as standalone) to, for instance, src/main/jetty/my-webdefault.xml

Modify its DefaultServlet initialization parameters:

```<code><web-app ...> <!-- src/main/jetty/my-webdefault.xml -->
  :
  <servlet>
    <servlet-name>default</servlet-name>
    <servlet-class>org.eclipse.jetty.servlet.DefaultServlet</servlet-class>
    :
    <init-param> <!-- relative to pom.xml, or wherever cargo runs -->
      <param-name>resourceBase</param-name>
      <param-value>./src/main/webapp</param-value>
    </init-param>
    <init-param> <!-- to avoid file locking in Windows, use: false -->
      <param-name>useFileMappedBuffer</param-name>
      <param-value>false</param-value>
    </init-param>
  </servlet>
</web-app>
</code>```

Have the cargo-maven2-plugin copy the new config file my-webdefault.xml into the (Jetty) container's etc/ directory:

```<code><project ...> <!-- pom.xml -->
  :
  <build>
    :
    <plugins>
      :
      <plugin>
        <groupId>org.codehaus.cargo</groupId>
        <artifactId>cargo-maven2-plugin</artifactId>
        <version>...</version>
        <configuration>
          <container>...</container>
          <configuration>
            <configfiles>
              <configfile>
                <file>${basedir}/src/main/jetty/my-webdefault.xml</file>
                <tofile>etc/webdefault.xml</tofile>
              </configfile>
            </configfiles>
            <properties>...</properties>
          </configuration>
          <deployables>...</deployables>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>
</code>```

Run with mvn clean verify cargo:run

PS. My attempts with a scratch.xml to trigger a simple static content ResourceHandler in a separate context (e.g. /static) were without success.

Body:
I need to configure jetty running from the maven cargo plugin to point it at static content, Ive looked through the jetty documentation and I cant see how to apply the configuration to jetty when it is running as part of cargo. I want to configure the webApp section and set the resource base as my angular app built as a module of this build:

 <execution>
                  <id>start jetty - angular webapp</id>
                  <phase>pre-integration-test</phase>
                  <goals>
                    <goal>start</goal>
                  </goals>
                  <configuration>
                        <container>
                            <containerId>jetty7x</containerId>
                            <type>embedded</type>
                        </container>
                        <webApp>
                            <resourceBases>
                                <contextPath>/</contextPath>
                                <resourceBase>../calculator-web/dist</resourceBase>
                            </resourceBases>
                        </webApp>
                        <configuration>
                            <properties>
                                <cargo.servlet.port>11000</cargo.servlet.port>
                            </properties>
                        </configuration>
                    </configuration>
                </execution>

Jetty starts but it seems to ignore this configuration and I just get a 404 for my index.html file.

Can somebody point me in the right direction please?

Body:
Although cargo does not seem to support Jetty's reload or automatic hot redeploy feature directly, at least you can serve your 'unfinished' static content and immediately pick up changes, e.g. during development while running an embedded container.

My current solution is to reconfigure Jetty's DefaultServlet, pointing the resourceBase to the project's 'live' source directory (e.g. ${basedir}/src/main/webapp) rather than the deployable's default (build) <location/> (e.g. ${project.build.directory}/${project.build.finalName}), and (just to be sure) disabling useFileMappedBuffer to avoid file locking in Windows:

Copy Jetty's webdefault.xml (from e.g. target/cargo/configurations/jetty.../etc/ when running the cargo container as standalone) to, for instance, src/main/jetty/my-webdefault.xml

Modify its DefaultServlet initialization parameters:

<web-app ...> <!-- src/main/jetty/my-webdefault.xml -->
  :
  <servlet>
    <servlet-name>default</servlet-name>
    <servlet-class>org.eclipse.jetty.servlet.DefaultServlet</servlet-class>
    :
    <init-param> <!-- relative to pom.xml, or wherever cargo runs -->
      <param-name>resourceBase</param-name>
      <param-value>./src/main/webapp</param-value>
    </init-param>
    <init-param> <!-- to avoid file locking in Windows, use: false -->
      <param-name>useFileMappedBuffer</param-name>
      <param-value>false</param-value>
    </init-param>
  </servlet>
</web-app>

Have the cargo-maven2-plugin copy the new config file my-webdefault.xml into the (Jetty) container's etc/ directory:

<project ...> <!-- pom.xml -->
  :
  <build>
    :
    <plugins>
      :
      <plugin>
        <groupId>org.codehaus.cargo</groupId>
        <artifactId>cargo-maven2-plugin</artifactId>
        <version>...</version>
        <configuration>
          <container>...</container>
          <configuration>
            <configfiles>
              <configfile>
                <file>${basedir}/src/main/jetty/my-webdefault.xml</file>
                <tofile>etc/webdefault.xml</tofile>
              </configfile>
            </configfiles>
            <properties>...</properties>
          </configuration>
          <deployables>...</deployables>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>

Run with mvn clean verify cargo:run

PS. My attempts with a scratch.xml to trigger a simple static content ResourceHandler in a separate context (e.g. /static) were without success.


问:
Forwarding message with TLSharp library (C#)
I'm connecting to Telegram API with this C# library: TLSharp

The resources for this library is not enough, I'm trying to Forward a message to channel .

I'm not quiet sure how to get channel post peer id (for forward function input parameters)

```<code>var store = new FileSessionStore();
            var client = new TelegramClient(Properties.Settings.Default.apiID, Properties.Settings.Default.apiHash, store, "session");
            await client.ConnectAsync();
            var dialogs = (TLDialogs)await client.GetUserDialogsAsync();
            var chat = dialogs.chats.lists
                .OfType<TLChannel>()
                .SingleOrDefault(a=>a.title=="test");
            await client.SendRequestAsync<TLAbsUpdates>(
                               new TLRequestForwardMessage()
                               {
                                   id = 2,
                                   peer = new TLInputPeerChannel() { channel_id = chat.id, access_hash = chat.access_hash.Value },
                                   random_id = Helpers.GenerateRandomLong()
                               });
</code>```

I get this error message :

{"PEER_ID_INVALID"}

Please help me, what is that peer id and how can i access and use that for forwarding a message using TLSharp. Thanks.

答:
This code can be used for forward

**

```<code>await client.SendRequestAsync<TLAbsUpdates>( new TLRequestForwardMessage() { id = item2.Id, peer = new TLInputPeerChat() { chat_id = item.id }, random_id = Helpers.GenerateRandomLong(), });
---------------------------------------
</code>```

**---------------------------------

Body:
I'm connecting to Telegram API with this C# library: TLSharp

The resources for this library is not enough, I'm trying to Forward a message to channel .

I'm not quiet sure how to get channel post peer id (for forward function input parameters)

var store = new FileSessionStore();
            var client = new TelegramClient(Properties.Settings.Default.apiID, Properties.Settings.Default.apiHash, store, "session");
            await client.ConnectAsync();
            var dialogs = (TLDialogs)await client.GetUserDialogsAsync();
            var chat = dialogs.chats.lists
                .OfType<TLChannel>()
                .SingleOrDefault(a=>a.title=="test");
            await client.SendRequestAsync<TLAbsUpdates>(
                               new TLRequestForwardMessage()
                               {
                                   id = 2,
                                   peer = new TLInputPeerChannel() { channel_id = chat.id, access_hash = chat.access_hash.Value },
                                   random_id = Helpers.GenerateRandomLong()
                               });

I get this error message :

{"PEER_ID_INVALID"}

Please help me, what is that peer id and how can i access and use that for forwarding a message using TLSharp. Thanks.

Body:
This code can be used for forward

**

await client.SendRequestAsync<TLAbsUpdates>( new TLRequestForwardMessage() { id = item2.Id, peer = new TLInputPeerChat() { chat_id = item.id }, random_id = Helpers.GenerateRandomLong(), });
---------------------------------------

**---------------------------------


问:
Regarding an usage of Chain of Responsibility
In the book Design Patterns : Elements of reusable object oriented software it is mentioned that Chain of Responsibility pattern can be used to let components access global properties through their parents. Can someone please enlighten me on this usage of the pattern?</p>

答: The Chain of Responsibility allows an object to send a command without knowing which object will receive and handle it. The request is sent from one object to another making them parts of a chain and each object in this chain can handle the command, pass it on or do both.</p>


问:
Is there a way to find out who is remote debugging on Glassfish?
In our team someone is using the remote debugging on Glassfish.
Can I figure out which ip it is?</p>

答:
Thanks Thorbjørn :) We now use the command

```<code>netstat -pnl | grep 9009
</code>```

to figure out if Glassfish is listening for remote debugging
and netstat -pn | grep 9009 to figure out who is currently using remote debugging

Body:
Thanks Thorbjørn :) We now use the command

netstat -pnl | grep 9009

to figure out if Glassfish is listening for remote debugging
and netstat -pn | grep 9009 to figure out who is currently using remote debugging


问:
How to shallow clone a specific commit with depth 1?
Is it possible to shallow clone a specific commit in a repository, i.e. with depth 1? Something like

```<code>git clone http://myrepo.git 728a4d --depth 1
</code>```

to get the repository state as it is at the commit with SHA 728a4d...?

The motivation is to avoid having to clone the whole repository, then check out that specific commit, when we're only interested in the state of the repository at that specific commit.

答:
Starting with Git 2.5.0 (which needs to be available at both the client and server side) you can set uploadpack.allowReachableSHA1InWant=true on the server side to enable fetching of specific SHA1s (must be the full SHA1, not an abbreviation):

```<code>git init
git remote add origin <url>
git fetch --depth 1 origin <sha1>
git checkout FETCH_HEAD
</code>```

Note that I did not find a syntax to do this with git clone directly.

Body:
Is it possible to shallow clone a specific commit in a repository, i.e. with depth 1? Something like

git clone http://myrepo.git 728a4d --depth 1

to get the repository state as it is at the commit with SHA 728a4d...?

The motivation is to avoid having to clone the whole repository, then check out that specific commit, when we're only interested in the state of the repository at that specific commit.

Body:
Starting with Git 2.5.0 (which needs to be available at both the client and server side) you can set uploadpack.allowReachableSHA1InWant=true on the server side to enable fetching of specific SHA1s (must be the full SHA1, not an abbreviation):

git init
git remote add origin <url>
git fetch --depth 1 origin <sha1>
git checkout FETCH_HEAD

Note that I did not find a syntax to do this with git clone directly.


问:
Qt Creator: start programm with processor affinity
I need to debug an application for an embedded device. A problem with this application might be timing related so I try to decrease the speed of execution on my development machine.

I have a setup which is quite useful but needs a little tweaking for convenience, basically I followed the advice given here:

https://blogs.msdn.microsoft.com/vijaysk/2012/10/26/tools-to-simulate-cpu-memory-disk-load/

Linked in the article there is the tool "CPUSTRES.exe" which generates high CPU usage. To prevent the tool to eat up all my CPU I start it like so (the tool will only run on the 8th core):

```<code>START "Stress" /affinity 0x80 /HIGH CPUSTRES.EXE
</code>```

Then I start the debugging session in the Qt Creator (version 4.1.0). Using the windows task manager I can set the same processor affinity for the application as the stress tool has. Doing so gives me an app that more or less sluggish like on the embedded device but the debugger and all other apps behave nicely.

I find it a little inconvenient to set the affinity in the task manager manually. I want this application always only on the same single core. This is only for debugging purposes, so would not like to change this in code. How can I achieve that?

答:
While I managed to start the application under test with the desired processor affinity I would not recomment it. It does not make my life easier. Instead I would recommend to set the affinity in code as commented by @ni1ight.

The easy way (that was not asked for):

```<code>#include <windows.h>
int main(int argc, char* argv[]) {
#ifdef _DEBUG
    DWORD_PTR processAffinityMask = 1 << 7;
    HANDLE process = GetCurrentProcess();
    SetProcessAffinityMask(process, processAffinityMask);
#endif
    [...]
</code>```

The other way to do it (that is not reasonable):

View your project's settings

add a new run configuration and choose 'custom executeable'

As the executeable choose a new 'cmd' file with the command as it is in the question (START "" /affinity 0x80 AppUnderTest.EXE). It should be possible to provide the application path as an argument to the cmd but I did not try this.

Then it is possible to start the application from the creator but debugging is not possible.

Attach the debugger to the running process to debug the application.

Body:
I need to debug an application for an embedded device. A problem with this application might be timing related so I try to decrease the speed of execution on my development machine.

I have a setup which is quite useful but needs a little tweaking for convenience, basically I followed the advice given here:

https://blogs.msdn.microsoft.com/vijaysk/2012/10/26/tools-to-simulate-cpu-memory-disk-load/

Linked in the article there is the tool "CPUSTRES.exe" which generates high CPU usage. To prevent the tool to eat up all my CPU I start it like so (the tool will only run on the 8th core):

START "Stress" /affinity 0x80 /HIGH CPUSTRES.EXE

Then I start the debugging session in the Qt Creator (version 4.1.0). Using the windows task manager I can set the same processor affinity for the application as the stress tool has. Doing so gives me an app that more or less sluggish like on the embedded device but the debugger and all other apps behave nicely.

I find it a little inconvenient to set the affinity in the task manager manually. I want this application always only on the same single core. This is only for debugging purposes, so would not like to change this in code. How can I achieve that?

Body:
While I managed to start the application under test with the desired processor affinity I would not recomment it. It does not make my life easier. Instead I would recommend to set the affinity in code as commented by @ni1ight.

The easy way (that was not asked for):

#include <windows.h>
int main(int argc, char* argv[]) {
#ifdef _DEBUG
    DWORD_PTR processAffinityMask = 1 << 7;
    HANDLE process = GetCurrentProcess();
    SetProcessAffinityMask(process, processAffinityMask);
#endif
    [...]

The other way to do it (that is not reasonable):

View your project's settings

add a new run configuration and choose 'custom executeable'

As the executeable choose a new 'cmd' file with the command as it is in the question (START "" /affinity 0x80 AppUnderTest.EXE). It should be possible to provide the application path as an argument to the cmd but I did not try this.

Then it is possible to start the application from the creator but debugging is not possible.

Attach the debugger to the running process to debug the application.