4

I have a Star Micronics TSP that supports CodePage 1001 Arabic, how do I convert UTF-8 to that specific code page using C#?

Update: I found out that CodePage 864 is compatible with the printer, I tried sending hex values and I got the correct character,

myPrinter.PrintNormal(PrinterStation.Receipt, "\xFE8D");

I tried the following to convert a string to codePage 864:

Encoding enc = Encoding.GetEncoding(864);
byte[] arr = enc.GetBytes("السلام");

the byte arr values i'm getting after the encoding is {63,63,63,63,63,63} which is wrong in value and even the byte count is wrong because its a double byte character.

Jalal Said
  • 15,906
  • 7
  • 45
  • 68
Abdusalam Ben Haj
  • 5,343
  • 5
  • 31
  • 45
  • can you indicate what set of bytes would be correct for your given input? – Marc Gravell Jul 25 '11 at 05:07
  • 2
    @Absi, code page 864 is an old legacy 8-bit encoding for basic arabic. It's not going to work. 63 is the question mark character, which means the encoder can't convert the characters. Also, can you provide a citation on code page 1001? Are you sure it exists and that you've gotten the number right? – bzlm Jul 25 '11 at 08:47
  • @Marc before I can correctly answer you, I need a way to iterate hex values and send them to the printer to see what each hex produces. a very close byte set to that input would be {x0627,x0646,x0633,x0646,x0627,x0647} – Abdusalam Ben Haj Jul 25 '11 at 16:00
  • @bzlm its the printer configuration utility that says 1001 Arabic and 864 Arabic are supported, so when I set the printer to codePage 864 and send them the hex value above, it does print arabic, but how do I automatically encode these – Abdusalam Ben Haj Jul 25 '11 at 16:14
  • @Absi a "codepage" usually refers to using the 8th bit on top of ASCII; A 2 byte map is unusual at re minimum - at least, in "codepage" terms. Like bzlm I'm struggling to find any reference on 1001 – Marc Gravell Jul 25 '11 at 17:14
  • @Marc, please check this out http://ascii-table.com/codepage.php?864 – Abdusalam Ben Haj Jul 25 '11 at 17:22
  • @Absi and are the characters in your sample listed in that 8x8 grid? – Marc Gravell Jul 25 '11 at 17:52
  • @Marc yes they are listed there – Abdusalam Ben Haj Jul 25 '11 at 18:01
  • by the way, the set of bytes that I typed earlier were produced from this page http://ascii-table.com/keyboard.php/470 – Abdusalam Ben Haj Jul 25 '11 at 18:04

2 Answers2

5

Untested, but:

String s = Encoding.UTF8.GetString(bytes);
Encoding enc = Encoding.GetEncoding(1001);
byte[] arr2 = enc.GetBytes(s);

Of course, skip the first line if you are actually starting with a string, but since you mention UTF-8 I assumed binary.

Obviously for large data volumes you might use a TextReader/TextWriter (each with encoding) instead - but same idea.

bzlm
  • 9,626
  • 6
  • 65
  • 92
Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • I get the following runtime error, "no data is available for encoding 1001" – Abdusalam Ben Haj Jul 24 '11 at 18:29
  • @Asbi if it isn't recognised, you might have o try looking at Encoding.GetEncodings() to see if anything is "close enough" (10004 maybe?). Failing all else, find a spec for 1001 and encode by hand. – Marc Gravell Jul 24 '11 at 18:37
  • @Absi But that is just Unicode. Did you try UTF-16 (there are two; big-endian and little-endian)? – Marc Gravell Jul 25 '11 at 18:10
  • ok I think we are getting too close, when I encode that input, i get 2 bytes for each letter , lets say {06,46} for the second letter .. now how would I change it back to string and send it to the printer as one letter? – Abdusalam Ben Haj Jul 25 '11 at 18:24
  • @Absi - switch endianness; if using `.Unicode` switch to `.BigEndianEnicode` etc. That should give you the 0x0627 etc from earlier. However, this *is* still one character. Character != byte. – Marc Gravell Jul 25 '11 at 21:10
  • sorry for taking much of your time :) after getting that two byte character 0x0627, I need to send it to the printer as a string and not byte array, so my question would be, how do I dynamically achieve this myPrinter.PrintNormal(PrinterStation.Receipt, "\x0627"); – Abdusalam Ben Haj Jul 25 '11 at 21:28
  • @Absi once you have the bytes, use `.ToString("x2")` on each in turn and add the prefix etc. – Marc Gravell Jul 25 '11 at 21:40
  • I reached to a point where I got the hex as string, adding the prefix later is not working, the "\x" is giving me an escape sequence error – Abdusalam Ben Haj Jul 25 '11 at 22:05
  • @Absi - use either `"\\x"` or `@"\x"` – Marc Gravell Jul 25 '11 at 22:07
0

i don't think the original person who asked still needs the answer but this thread seems pretty famous and i don't want anyone to waste his time to find what i found the hard way..so

this answer relies primarily on the application provided with the Star Micronics TSP printer

key points: - reference "Interop.OposPOSPrinter_CCO.dll" - the printer object should be of type oposposprinter.printer and is initialized in a slightly different way (compared to opos.net) - the character codes are sent as a string and there's a variable to tell the printer object to use these decimal numbers as character codes

a sample VB.net project with a simple arabic letter converter can be found at https://bitbucket.org/loody/arabic-1001/overview

note: i don't have time to cover the rest of the letters/numbers