j2me midlet chinese character display message garbled - utf-8

My J2ME midlet could retrieves message in Chinese character from a PHP server but it's garbled. The server basically returns the response string and by detecting the first 2 characters. AA = good, anything else indicates error of which the message is to be passed to the calling function for display
InputStream is = null;
StringBuffer sb = null;
String str = "";
HttpConnection http = null;
DataOutputStream dos = null;
try
{
URL = login.getURL();
URL += ctlFunction + "/" + uriStr;
URL = EncodeURL(URL);
//System.out.println(URL);
if(!ctlFunction.equals("login"))
{
msg += "&user=" + login.getUsername();
msg += "&token=" + login.getToken();
}
msg += "&lang=" + System.getProperty("microedition.locale");
// establish the connection
http = (HttpConnection) Connector.open(URL);
http.setRequestMethod(HttpConnection.POST);
http.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
http.setRequestProperty("Content-length", ""+EncodeURL(msg).getBytes().length);
dos = http.openDataOutputStream();
byte[] request_body = EncodeURL(msg).getBytes();
for (int i = 0; i < request_body.length; i++)
{
dos.writeByte(request_body[i]);
}
// server response
if (http.getResponseCode() == HttpConnection.HTTP_OK)
{
is = http.openDataInputStream();
int length = (int) http.getLength();
if (length != -1)
{
// Read data in one chunk
byte serverData[] = new byte[length];
is.read(serverData);
str = new String(serverData);
}
else // Length not available...
{
ByteArrayOutputStream bStrm = new ByteArrayOutputStream();
int ch;
while ((ch = is.read()) != -1)
bStrm.write(ch);
str = new String(bStrm.toByteArray());
bStrm.close();
}
}
else
{
networkError();
}
}
catch (Exception e)
{
System.err.println("Error3: " + e.toString());
networkError(e.toString());
}
finally
{
if (is != null)
is.close();
if (!str.equals(""))
post = str;
else
networkError();
if (http != null)
http.close();
}
if (post != null)
{
String fate = post.substring(0, 2);
if(fate.equals("AA"))
{
if(ctlFunction.equals("login"))
{
String rawPost = post.substring(2);
Vector v = new Vector();
int index = 0;
//find the first occurrence of the SPLITTER
int endIndex = rawPost.indexOf(SPLITTER, index);
String item = "";
//extract the items until the end of the last SPLITTER found in the rawPost string
while(endIndex != -1)
{
item = rawPost.substring(index, endIndex);
index = endIndex + 1;
endIndex = rawPost.indexOf(SPLITTER, index);
v.addElement(item);
}
//extract the rest of the rawPost (the text item)
item = rawPost.substring(index);
v.addElement(item);
String[] ret = new String[v.size()];
v.copyInto(ret);
login.setToken(ret[0]);
login.setToday(ret[1]);
login.setNextDrawDay(ret[2]);
}
midlet.returnResults(post.substring(2), getCurrentDisplay(), ctlFunction);
}
else
{
String errmessage = post.substring(2);
System.out.println(post);
midlet.showInfo(post, getCurrentDisplay());
}
}
else
{
networkError();
}
On the PHP server, I have set the header to UTF-8 encoding
<?php header("Content-Type:text/plain; charset=utf-8"); ?>
What could possibly be wrong?

I found that this user has the same problem and it's been answered
Reading UTF8 strings from a server through http using MIDP. Kudos to the answer.
I basically edited my MIDP code from
// is = http.openDataInputStream();
// int length = (int) http.getLength();
// if (length != -1)
// {
// // Read data in one chunk
// byte serverData[] = new byte[length];
// is.read(serverData);
// str = new String(serverData);
// }
// else // Length not available...
// {
// ByteArrayOutputStream bStrm = new ByteArrayOutputStream();
// int ch;
// while ((ch = is.read()) != -1)
// bStrm.write(ch);
//
// str = new String(bStrm.toByteArray());
// bStrm.close();
// }
to
Reader r = new InputStreamReader(http.openInputStream(), "UTF-8");
int ch;
while((ch = r.read()) != -1)
str = str + (char)ch;
just wondering though why does reading bytes messes up the UTF-8 characters?

Related

how to print image to thermal printer in kotlin

i already able to print text using kotlin to thermal printer, but im still dont know how to print image to thermal printer in kotlin. please give me sample printing image to thermal printer in kotlin.i already search for the topics, but it written in java, i doesnt know java very much thanks for the help
private fun p1() {
val namaToko = "Rose Medical"
val alamatToko = "Pramuka raya no.1 Jakarta Timur"
val telp = "021-85901642"
val enter = "\n"
val strip = "-"
val rp ="Rp."
val ex = " X "
val textTotal = "Total Rp:"
val ppnTv = "PPN :Rp."
val chargeTv ="Charge :Rp."
val totalTv = "Total Belanja :Rp."
val scope = CoroutineScope(Dispatchers.IO)
scope.launch {
// chunks1
try{
writeWithFormat(namaToko.toByteArray(),Formatter().get(),Formatter.centerAlign())
writeWithFormat(enter.toByteArray(),Formatter().get(),Formatter.leftAlign())
writeWithFormat(alamatToko.toByteArray(),Formatter().get(),Formatter.centerAlign())
writeWithFormat(enter.toByteArray(),Formatter().get(),Formatter.leftAlign())
writeWithFormat(telp.toByteArray(),Formatter().get(),Formatter.centerAlign())
writeWithFormat(enter.toByteArray(),Formatter().get(),Formatter.leftAlign())
writeWithFormat(enter.toByteArray(),Formatter().get(),Formatter.rightAlign())
}catch (e: Exception) {
Log.e("PrintActivity", "Exe ", e)
}
// chunks2
for(pointer in salesBody.indices){
try {
val merk = salesBody[pointer].merk
writeWithFormat(merk!!.toByteArray(),Formatter().get(),Formatter.leftAlign())
writeWithFormat(strip.toByteArray(),Formatter().get(),Formatter.leftAlign())
val barang = salesBody[pointer].namaBrg
writeWithFormat(barang!!.toByteArray(),Formatter().get(),Formatter.leftAlign())
writeWithFormat(enter.toByteArray(),Formatter().get(),Formatter.leftAlign())
val varian = salesBody[pointer].varian
writeWithFormat(varian!!.toByteArray(),Formatter().get(),Formatter.leftAlign())
writeWithFormat(enter.toByteArray(),Formatter().get(),Formatter.leftAlign())
writeWithFormat(rp.toByteArray(),Formatter().get(),Formatter.leftAlign())
val harga = ValidNumber().deciformat(salesBody[pointer].hargaJual.toString())
writeWithFormat(harga.toByteArray(),Formatter().get(),Formatter.leftAlign())
writeWithFormat(ex.toByteArray(),Formatter().get(),Formatter.leftAlign())
val jumlah = ValidNumber().deciformat(salesBody[pointer].qty.toString())
writeWithFormat(jumlah.toByteArray(),Formatter().get(),Formatter.leftAlign())
val satuan = salesBody[pointer].unit
writeWithFormat(satuan!!.toByteArray(),Formatter().get(),Formatter.leftAlign())
writeWithFormat(enter.toByteArray(),Formatter().get(),Formatter.leftAlign())
writeWithFormat(textTotal.toByteArray(),Formatter().get(),Formatter.rightAlign())
val total = ValidNumber().deciformat(salesBody[pointer].total.toString())
writeWithFormat(total.toByteArray(),Formatter().get(),Formatter.leftAlign())
writeWithFormat(enter.toByteArray(),Formatter().get(),Formatter.leftAlign())
}catch (e: Exception) {
Log.e("PrintActivity", "Exe ", e)
}
}
// chunks3
try{
writeWithFormat(enter.toByteArray(),Formatter().get(),Formatter.leftAlign())
val tanggal = salesHeader[0].tanggal
writeWithFormat(tanggal!!.toByteArray(),Formatter().get(),Formatter.leftAlign())
writeWithFormat(strip.toByteArray(),Formatter().get(),Formatter.leftAlign())
val jam = salesHeader[0].jam
writeWithFormat(jam!!.toByteArray(),Formatter().get(),Formatter.leftAlign())
writeWithFormat(strip.toByteArray(),Formatter().get(),Formatter.leftAlign())
val idTag= salesHeader[0].idTag
writeWithFormat(idTag!!.toByteArray(),Formatter().get(),Formatter.leftAlign())
writeWithFormat(enter.toByteArray(),Formatter().get(),Formatter.leftAlign())
val payment= salesHeader[0].payment
writeWithFormat(payment!!.toByteArray(),Formatter().get(),Formatter.leftAlign())
writeWithFormat(enter.toByteArray(),Formatter().get(),Formatter.leftAlign())
writeWithFormat(ppnTv.toByteArray(),Formatter().get(),Formatter.rightAlign())
val ppnValue = ValidNumber().deciformat(salesHeader[0].ppn.toString())
writeWithFormat(ppnValue.toByteArray(),Formatter().get(),Formatter.rightAlign())
writeWithFormat(enter.toByteArray(),Formatter().get(),Formatter.rightAlign())
writeWithFormat(chargeTv.toByteArray(),Formatter().get(),Formatter.rightAlign())
val chargeValue = ValidNumber().deciformat(salesHeader[0].charge.toString())
writeWithFormat(chargeValue.toByteArray(),Formatter().get(),Formatter.rightAlign())
writeWithFormat(enter.toByteArray(),Formatter().get(),Formatter.rightAlign())
writeWithFormat(totalTv.toByteArray(),Formatter().get(),Formatter.rightAlign())
var totalValue = ValidNumber().deciformat(salesHeader[0].allTotal.toString())
writeWithFormat(totalValue.toByteArray(),Formatter().get(),Formatter.rightAlign())
writeWithFormat(enter.toByteArray(),Formatter().get(),Formatter.rightAlign())
writeWithFormat(enter.toByteArray(),Formatter().get(),Formatter.rightAlign())
writeWithFormat(enter.toByteArray(),Formatter().get(),Formatter.rightAlign())
writeWithFormat(enter.toByteArray(),Formatter().get(),Formatter.rightAlign())
writeWithFormat(enter.toByteArray(),Formatter().get(),Formatter.rightAlign())
writeWithFormat(enter.toByteArray(),Formatter().get(),Formatter.rightAlign())
}catch (e: Exception) {
Log.e("PrintActivity", "Exe ", e)
}
}
}
//print code
class Formatter {
/** The format that is being build on */
private val mFormat: ByteArray
init {
// Default:
mFormat = byteArrayOf(27, 33, 0)
}
/**
* Method to get the Build result
*
* #return the format
*/
fun get(): ByteArray {
return mFormat
}
fun bold(): Formatter {
// Apply bold:
mFormat[2] = (0x8 or mFormat[2].toInt()).toByte()
return this
}
fun small(): Formatter {
mFormat[2] = (0x1 or mFormat[2].toInt()).toByte()
return this
}
fun height(): Formatter {
mFormat[2] = (0x10 or mFormat[2].toInt()).toByte()
return this
}
fun width(): Formatter {
mFormat[2] = (0x20 or mFormat[2].toInt()).toByte()
return this
}
fun underlined(): Formatter {
mFormat[2] = (0x80 or mFormat[2].toInt()).toByte()
return this
}
companion object {
fun rightAlign(): ByteArray {
return byteArrayOf(0x1B, 'a'.code.toByte(), 0x02)
}
fun leftAlign(): ByteArray {
return byteArrayOf(0x1B, 'a'.code.toByte(), 0x00)
}
fun centerAlign(): ByteArray {
return byteArrayOf(0x1B, 'a'.code.toByte(), 0x01)
}
}
}//last
fun writeWithFormat(buffer: ByteArray, pFormat: ByteArray?, pAlignment: ByteArray?): Boolean {
val mmOutStream: OutputStream = mBluetoothSocket.outputStream
return try {
// Notify printer it should be printed with given alignment:
mmOutStream.write(pAlignment)
// Notify printer it should be printed in the given format:
mmOutStream.write(pFormat)
// Write the actual data:
mmOutStream.write(buffer, 0, buffer.size)
// Share the sent message back to the UI Activity
//App.getInstance().getHandler().obtainMessage(MESSAGE_WRITE, buffer.size, -1, buffer).sendToTarget()
true
} catch (e: IOException) {
Log.e(TAG, "Exception during write", e)
false
}
}
//print code close
Using Thermal Printer repo references, I managed to print image to Bluetooth thermal printer. Make sure to use a proper black and white image to print.
Here is the piece of code I used to make a java class
--BitmapHelper.java.
public class BitmapHelper {
private static String[] binaryArray = { "0000", "0001", "0010", "0011",
"0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011",
"1100", "1101", "1110", "1111" };
public static byte[] decodeBitmap(Bitmap bmp){
//Bitmap bmp = Bitmap.createScaledBitmap(bitmap, 50, 50, false);
int maxWidth = 350;
int bmpWidth = bmp.getWidth();
int bmpHeight = bmp.getHeight();
if(bmpWidth > maxWidth){
float aspectRatio = bmp.getWidth() /
(float) bmp.getHeight();
bmpWidth = maxWidth;
bmpHeight = Math.round(bmpWidth / aspectRatio);
bmp = Bitmap.createScaledBitmap(bmp, bmpWidth, bmpHeight, false);
}
List<String> list = new ArrayList<>(); //binaryString list
StringBuffer sb;
int zeroCount = bmpWidth % 8;
StringBuilder zeroStr = new StringBuilder();
if (zeroCount > 0) {
for (int i = 0; i < (8 - zeroCount); i++) {
zeroStr.append("0");
}
}
for (int i = 0; i < bmpHeight; i++) {
sb = new StringBuffer();
for (int j = 0; j < bmpWidth; j++) {
int color = bmp.getPixel(j, i);
int r = (color >> 16) & 0xff;
int g = (color >> 8) & 0xff;
int b = color & 0xff;
// if color close to white,bit='0', else bit='1'
if (r > 160 && g > 160 && b > 160)
sb.append("0");
else
sb.append("1");
}
if (zeroCount > 0) {
sb.append(zeroStr);
}
list.add(sb.toString());
}
List<String> bmpHexList = binaryListToHexStringList(list);
String commandHexString = "1D763000";
String widthHexString = Integer
.toHexString(bmpWidth % 8 == 0 ? bmpWidth / 8
: (bmpWidth / 8 + 1));
if (widthHexString.length() > 2) {
Log.e("decodeBitmap error", " width is too large");
return null;
} else if (widthHexString.length() == 1) {
widthHexString = "0" + widthHexString;
}
widthHexString = widthHexString + "00";
String heightHexString = Integer.toHexString(bmpHeight);
if (heightHexString.length() > 2) {
Log.e("decodeBitmap error", " height is too large");
return null;
} else if (heightHexString.length() == 1) {
heightHexString = "0" + heightHexString;
}
heightHexString = heightHexString + "00";
List<String> commandList = new ArrayList<>();
commandList.add(commandHexString+widthHexString+heightHexString);
commandList.addAll(bmpHexList);
return hexList2Byte(commandList);
}
private static List<String> binaryListToHexStringList(List<String> list) {
List<String> hexList = new ArrayList<String>();
for (String binaryStr : list) {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < binaryStr.length(); i += 8) {
String str = binaryStr.substring(i, i + 8);
String hexString = myBinaryStrToHexString(str);
sb.append(hexString);
}
hexList.add(sb.toString());
}
return hexList;
}
private static String myBinaryStrToHexString(String binaryStr) {
StringBuilder hex = new StringBuilder();
String f4 = binaryStr.substring(0, 4);
String b4 = binaryStr.substring(4, 8);
String hexStr = "0123456789ABCDEF";
for (int i = 0; i < binaryArray.length; i++) {
if (f4.equals(binaryArray[i]))
hex.append(hexStr.substring(i, i + 1));
}
for (int i = 0; i < binaryArray.length; i++) {
if (b4.equals(binaryArray[i]))
hex.append(hexStr.substring(i, i + 1));
}
return hex.toString();
}
private static byte[] hexList2Byte(List<String> list) {
List<byte[]> commandList = new ArrayList<byte[]>();
for (String hexStr : list) {
commandList.add(hexStringToBytes(hexStr));
}
return sysCopy(commandList);
}
private static byte[] hexStringToBytes(String hexString) {
if (hexString == null || hexString.equals("")) {
return null;
}
hexString = hexString.toUpperCase();
int length = hexString.length() / 2;
char[] hexChars = hexString.toCharArray();
byte[] d = new byte[length];
for (int i = 0; i < length; i++) {
int pos = i * 2;
d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
}
return d;
}
private static byte[] sysCopy(List<byte[]> srcArrays) {
int len = 0;
for (byte[] srcArray : srcArrays) {
len += srcArray.length;
}
byte[] destArray = new byte[len];
int destLen = 0;
for (byte[] srcArray : srcArrays) {
System.arraycopy(srcArray, 0, destArray, destLen, srcArray.length);
destLen += srcArray.length;
}
return destArray;
}
private static byte charToByte(char c) {
return (byte) "0123456789ABCDEF".indexOf(c);
}
}
Then I use it in the print activity:
private fun p2(){
val convertBmp : Bitmap
convertBmp = BitmapFactory.decodeResource(getResources(),com.example.ronibluetooth.R.drawable.poly)
val decodeBmp = BitmapHelper.decodeBitmap(convertBmp)
val scope = CoroutineScope(Dispatchers.IO)
scope.launch {
try {
val os =mBluetoothSocket.outputStream
os.write(decodeBmp,0,decodeBmp.size)
}
catch (e: Exception) {
Log.e("PrintActivity", "Exe ", e)
}
}
}
image to print
result print

While Mail body being received, how to fetch the Image from multipart body

My application actually has mail send / receive functionalities to handle.
While receiving the mail, i am unable to view the image which is an inline image being sent from outlook.
Can some one help me how can i catch the image and make available always.
I have java code like below,
try (InputStream stream = new ByteArrayInputStream(Base64
.getMimeDecoder().decode(mail))) {
MimeMessage message = new MimeMessage(null, stream);
Object messageContent = message.getContent();
if (messageContent instanceof String) {
body = (String) messageContent;
} else if (messageContent instanceof MimeMultipart) {
content = (MimeMultipart) messageContent;
for (int i = 0; i < content.getCount(); i++) {
BodyPart bodyPart = content.getBodyPart(i);
String disposition = bodyPart.getDisposition();
if (disposition == null
|| disposition
.equalsIgnoreCase(Part.INLINE)) {
Object object = bodyPart.getContent();
if (object instanceof String) {
body = object.toString();
} else if (object instanceof MimeMultipart) {
MimeMultipart mimeMultipart = (MimeMultipart) object;
String plainBody = null;
String htmlBody = null;
for (int j = 0; j < mimeMultipart.getCount(); j++) {
BodyPart multipartBodyPart = mimeMultipart
.getBodyPart(j);
String multipartDisposition = multipartBodyPart
.getDisposition();
String multipartContentType = multipartBodyPart
.getContentType();
if (multipartDisposition == null
&& multipartContentType != null) {
if (multipartContentType
.contains(MediaType.TEXT_HTML)) {
htmlBody = multipartBodyPart
.getContent().toString();
} else if (multipartContentType
.contains(MediaType.TEXT_PLAIN)) {
plainBody = multipartBodyPart
.getContent().toString();
}
}
}
if (htmlBody != null) {
body = htmlBody;
} else {
body = plainBody;
}
}
}
}
}
Client side i am using CKEditor to handle email body data.
Thanks a lot.
i got a solution from the example shared below
https://www.tutorialspoint.com/javamail_api/javamail_api_fetching_emails.htm
But, this example explains, how to find the image in body and store.
I have also done below to replace src
`
Pattern htmltag = Pattern.compile("]src=\"[^>]>(.?)");
Pattern link = Pattern.compile("src=\"[^>]\">");
String s1 = "";
Matcher tagmatch = htmltag.matcher(s1);
List<String> links = new ArrayList<String>();
while (tagmatch.find()) {
Matcher matcher = link.matcher(tagmatch.group());
matcher.find();
String link1 = matcher.group().replaceFirst("src=\"", "")
.replaceFirst("\">", "")
.replaceFirst("\"[\\s]?target=\"[a-zA-Z_0-9]*", "");
links.add(link1);
s1 = s1.replaceAll(link1, "C:\\//Initiatives_KM\\//image.jpg");
}
`
And on top of this, i gonna do Base64 encoding so that i dont require store in file system.
encodedfileString = Base64.getEncoder().encodeToString(bArray);
With all these i can conclude to say, i got solution for my issue. Thank you.

Can't find way to debug Internal Server Error (500) caused by new class

I've read a lot of the postings about 500 errors because of the channel emulator, but this is not the case here. I took the standard bot template, which works just fine with the emulator, and replaced it with
ConnectorClient connector = new ConnectorClient(new
Uri(activity.ServiceUrl));
// calculate something for us to return
// int length = (activity.Text ?? string.Empty).Length;
string responseText=
***Bot_Application2.SilviaRestClass.GetRestResult(activity.Text);***
So the issue is in executing the GetRestResult method in the SilivaRestClass.
The code itself works, I'm using it in lots of other places, as it basically sets up a simple 1)get an input utterance in text, 2)send to my SILVIA AI server, and 3)get an utterance back routine. I have a feeling it has something to do with either private vs public methods, and/or [Serializable], based on what I have read so far. The code (minus the credentials) is below. Many thanks, in advance, for any suggestions to try.
`
bool exit = false;
restResponse = "Hello";
bool sessionNew = true;
string viewMessage = null;
string SILVIAUri = "";
string SILVIACore = "/Core/Create/unique/silName";
string SILVIASubmit = "/IO/SetInputManaged/unique/hello";
string SILVIARead = "/IO/GetAll/unique";
string SILVIARelease = "/Core/Release/{unique}";
string SILVIASubKey = "";
string silName = "";
string returnMessage = null;
string holdit = null;
string holdit2 = null;
int forHold = 0;
string responseFromServer = null;
string isfalse = "false";
string myURI = null;
string unique = null;
//CREATE CORE from SILVIA SERVER
myURI = SILVIAUri + SILVIACore;
myURI = myURI.Replace("silName", silName);
myURI = myURI.Replace("unique", unique);
System.Net.WebRequest request = WebRequest.Create(myURI);
request.Headers["Ocp-Apim-Subscription-Key"] = SILVIASubKey;
if (sessionNew)
{
Random rnd1 = new Random();
unique = rnd1.Next().ToString() + "askgracie";
sessionNew = false;
WebResponse wResponse = request.GetResponse();
Stream dataStream = wResponse.GetResponseStream();
StreamReader reader = new StreamReader(dataStream);
responseFromServer = reader.ReadToEnd();
// Clean up the streams and the response.
reader.Close();
wResponse.Close();
}
//SEND UTTERANCE to SILVIA
holdit = null;
myURI = null;
myURI = SILVIAUri + SILVIASubmit;
holdit = restResponse;
// holdit = HttpUtility.UrlEncode(holdit);
myURI = myURI.Replace("hello", holdit);
myURI = myURI.Replace("unique", unique);
if (holdit == "exit")
{
exit = true;
myURI = SILVIAUri + SILVIARelease;
}
System.Net.WebRequest sendRequest = WebRequest.Create(myURI);
sendRequest.Headers["Ocp-Apim-Subscription-Key"] = SILVIASubKey;
WebResponse sendResponse = sendRequest.GetResponse();
Stream sendStream = sendResponse.GetResponseStream();
StreamReader sendReader = new StreamReader(sendStream);
string send_ResponseFromServer = sendReader.ReadToEnd();
// Clean up the streams and the response.
sendReader.Close();
sendResponse.Close();
holdit = send_ResponseFromServer;
forHold = holdit.IndexOf("success");
holdit2 = holdit.Substring(forHold + 9, 5);
if (holdit2 == isfalse)
{
var simpleUtterResponse = "The bot failed to send the
utterance to SILVIA";
}
//GETRESPONSES FROM SILVIA
returnMessage = null;
holdit = null;
responseFromServer = null;
myURI = SILVIAUri + SILVIARead;
myURI = myURI.Replace("unique", unique);
System.Net.WebRequest readRequest = WebRequest.Create(myURI);
readRequest.Headers["Ocp-Apim-Subscription-Key"] = SILVIASubKey;
WebResponse readResponse = readRequest.GetResponse();
Stream readStream = readResponse.GetResponseStream();
StreamReader readReader = new StreamReader(readStream);
string read_ResponseFromServer = readReader.ReadToEnd();
viewMessage = read_ResponseFromServer;
string lastRead = "ID ";
List<string> myArray = new List<string>(viewMessage.Split(new
string[] { "\r\n" }, StringSplitOptions.None));
foreach (string s in myArray)
{
if (lastRead == "type: voice")
{
returnMessage = returnMessage + " " + s.Substring(8);
}
if (s.Length < 11)
{ lastRead = s;
}
else
{ lastRead = s.Substring(0, 11);
}
if (s.Length < 11)
{ lastRead = s;
}
else
{ lastRead = s.Substring(0, 11);
}
}
// Clean up the streams and the response.
//readReader.Close();
//readResponse.Close();
if (exit)
{
myURI = SILVIAUri + SILVIARelease;
myURI = myURI.Replace("unique", unique);
System.Net.WebRequest closeRequest =
WebRequest.Create(myURI);
closeRequest.Headers["Ocp-Apim-Subscription-Key"] =
SILVIASubKey;
WebResponse closeResponse = closeRequest.GetResponse();
}
return returnMessage;
}
}
}`
I ended up resolving this by cut/paste the class inside the same namespace and physical .cs file. – Brian Garr just now edit

How to stream a video or a file considering request and response range headers?

I am now using FileStreamResult and it works to stream a video, but can't seek it. It always starts again from the beginning.
I was using ByteRangeStreamContent but it seems that it is not available anymore with dnxcore50.
So how to proceed ?
Do i need to manually parse the request range headers and write a custom FileResult that sets the response Content-Range and the rest of the headers and writes the buffer range to the response body or is there something already implemented and i'm missing it ?
Here is a naive implementation of a VideoStreamResult. I am using at the moment (the multipart content part is not tested):
public class VideoStreamResult : FileStreamResult
{
// default buffer size as defined in BufferedStream type
private const int BufferSize = 0x1000;
private string MultipartBoundary = "<qwe123>";
public VideoStreamResult(Stream fileStream, string contentType)
: base(fileStream, contentType)
{
}
public VideoStreamResult(Stream fileStream, MediaTypeHeaderValue contentType)
: base(fileStream, contentType)
{
}
private bool IsMultipartRequest(RangeHeaderValue range)
{
return range != null && range.Ranges != null && range.Ranges.Count > 1;
}
private bool IsRangeRequest(RangeHeaderValue range)
{
return range != null && range.Ranges != null && range.Ranges.Count > 0;
}
protected async Task WriteVideoAsync(HttpResponse response)
{
var bufferingFeature = response.HttpContext.Features.Get<IHttpBufferingFeature>();
bufferingFeature?.DisableResponseBuffering();
var length = FileStream.Length;
var range = response.HttpContext.GetRanges(length);
if (IsMultipartRequest(range))
{
response.ContentType = $"multipart/byteranges; boundary={MultipartBoundary}";
}
else
{
response.ContentType = ContentType.ToString();
}
response.Headers.Add("Accept-Ranges", "bytes");
if (IsRangeRequest(range))
{
response.StatusCode = (int)HttpStatusCode.PartialContent;
if (!IsMultipartRequest(range))
{
response.Headers.Add("Content-Range", $"bytes {range.Ranges.First().From}-{range.Ranges.First().To}/{length}");
}
foreach (var rangeValue in range.Ranges)
{
if (IsMultipartRequest(range)) // I don't know if multipart works
{
await response.WriteAsync($"--{MultipartBoundary}");
await response.WriteAsync(Environment.NewLine);
await response.WriteAsync($"Content-type: {ContentType}");
await response.WriteAsync(Environment.NewLine);
await response.WriteAsync($"Content-Range: bytes {range.Ranges.First().From}-{range.Ranges.First().To}/{length}");
await response.WriteAsync(Environment.NewLine);
}
await WriteDataToResponseBody(rangeValue, response);
if (IsMultipartRequest(range))
{
await response.WriteAsync(Environment.NewLine);
}
}
if (IsMultipartRequest(range))
{
await response.WriteAsync($"--{MultipartBoundary}--");
await response.WriteAsync(Environment.NewLine);
}
}
else
{
await FileStream.CopyToAsync(response.Body);
}
}
private async Task WriteDataToResponseBody(RangeItemHeaderValue rangeValue, HttpResponse response)
{
var startIndex = rangeValue.From ?? 0;
var endIndex = rangeValue.To ?? 0;
byte[] buffer = new byte[BufferSize];
long totalToSend = endIndex - startIndex;
int count = 0;
long bytesRemaining = totalToSend + 1;
response.ContentLength = bytesRemaining;
FileStream.Seek(startIndex, SeekOrigin.Begin);
while (bytesRemaining > 0)
{
try
{
if (bytesRemaining <= buffer.Length)
count = FileStream.Read(buffer, 0, (int)bytesRemaining);
else
count = FileStream.Read(buffer, 0, buffer.Length);
if (count == 0)
return;
await response.Body.WriteAsync(buffer, 0, count);
bytesRemaining -= count;
}
catch (IndexOutOfRangeException)
{
await response.Body.FlushAsync();
return;
}
finally
{
await response.Body.FlushAsync();
}
}
}
public override async Task ExecuteResultAsync(ActionContext context)
{
await WriteVideoAsync(context.HttpContext.Response);
}
}
And parse request headers range:
public static RangeHeaderValue GetRanges(this HttpContext context, long contentSize)
{
RangeHeaderValue rangesResult = null;
string rangeHeader = context.Request.Headers["Range"];
if (!string.IsNullOrEmpty(rangeHeader))
{
// rangeHeader contains the value of the Range HTTP Header and can have values like:
// Range: bytes=0-1 * Get bytes 0 and 1, inclusive
// Range: bytes=0-500 * Get bytes 0 to 500 (the first 501 bytes), inclusive
// Range: bytes=400-1000 * Get bytes 500 to 1000 (501 bytes in total), inclusive
// Range: bytes=-200 * Get the last 200 bytes
// Range: bytes=500- * Get all bytes from byte 500 to the end
//
// Can also have multiple ranges delimited by commas, as in:
// Range: bytes=0-500,600-1000 * Get bytes 0-500 (the first 501 bytes), inclusive plus bytes 600-1000 (401 bytes) inclusive
// Remove "Ranges" and break up the ranges
string[] ranges = rangeHeader.Replace("bytes=", string.Empty).Split(",".ToCharArray());
rangesResult = new RangeHeaderValue();
for (int i = 0; i < ranges.Length; i++)
{
const int START = 0, END = 1;
long endByte, startByte;
long parsedValue;
string[] currentRange = ranges[i].Split("-".ToCharArray());
if (long.TryParse(currentRange[END], out parsedValue))
endByte = parsedValue;
else
endByte = contentSize - 1;
if (long.TryParse(currentRange[START], out parsedValue))
startByte = parsedValue;
else
{
// No beginning specified, get last n bytes of file
// We already parsed end, so subtract from total and
// make end the actual size of the file
startByte = contentSize - endByte;
endByte = contentSize - 1;
}
rangesResult.Ranges.Add(new RangeItemHeaderValue(startByte, endByte));
}
}
return rangesResult;
}
FYI, built-in support for range requests will be present in .NET Core 2.1
https://github.com/aspnet/Mvc/pull/6895

Issue in reading google text document

I could get the handle to the google text doc i needed. I am now stuck at how to read the contents.
My code looks like:
GoogleOAuthParameters oauthParameters = new GoogleOAuthParameters();
oauthParameters.setOAuthConsumerKey(Constants.CONSUMER_KEY);
oauthParameters.setOAuthConsumerSecret(Constants.CONSUMER_SECRET);
oauthParameters.setOAuthToken(Constants.ACCESS_TOKEN);
oauthParameters.setOAuthTokenSecret(Constants.ACCESS_TOKEN_SECRET);
DocsService client = new DocsService("sakshum-YourAppName-v1");
client.setOAuthCredentials(oauthParameters, new OAuthHmacSha1Signer());
URL feedUrl = new URL("https://docs.google.com/feeds/default/private/full/");
DocumentQuery dquery = new DocumentQuery(feedUrl);
dquery.setTitleQuery("blood_donor_verification_template_dev");
dquery.setTitleExact(true);
dquery.setMaxResults(10);
DocumentListFeed resultFeed = client.getFeed(dquery, DocumentListFeed.class);
System.out.println("feed size:" + resultFeed.getEntries().size());
String emailBody = "";
for (DocumentListEntry entry : resultFeed.getEntries()) {
System.out.println(entry.getPlainTextContent());
emailBody = entry.getPlainTextContent();
}
Plz note that entry.getPlainTextContent() does not work and throws object not TextContent type exception
finally i solved it as:
for (DocumentListEntry entry : resultFeed.getEntries()) {
String docId = entry.getDocId();
String docType = entry.getType();
URL exportUrl =
new URL("https://docs.google.com/feeds/download/" + docType
+ "s/Export?docID=" + docId + "&exportFormat=html");
MediaContent mc = new MediaContent();
mc.setUri(exportUrl.toString());
MediaSource ms = client.getMedia(mc);
InputStream inStream = null;
try {
inStream = ms.getInputStream();
int c;
while ((c = inStream.read()) != -1) {
emailBody.append((char)c);
}
} finally {
if (inStream != null) {
inStream.close();
}
}
}

Resources