(in-package "SB!IMPL")

(define-unibyte-mapper cp437->code-mapper code->cp437-mapper
  (#x80 #x00C7) ; LATIN CAPITAL LETTER C WITH CEDILLA
  (#x81 #x00FC) ; LATIN SMALL LETTER U WITH DIAERESIS
  (#x82 #x00E9) ; LATIN SMALL LETTER E WITH ACUTE
  (#x83 #x00E2) ; LATIN SMALL LETTER A WITH CIRCUMFLEX
  (#x84 #x00E4) ; LATIN SMALL LETTER A WITH DIAERESIS
  (#x85 #x00E0) ; LATIN SMALL LETTER A WITH GRAVE
  (#x86 #x00E5) ; LATIN SMALL LETTER A WITH RING ABOVE
  (#x87 #x00E7) ; LATIN SMALL LETTER C WITH CEDILLA
  (#x88 #x00EA) ; LATIN SMALL LETTER E WITH CIRCUMFLEX
  (#x89 #x00EB) ; LATIN SMALL LETTER E WITH DIAERESIS
  (#x8A #x00E8) ; LATIN SMALL LETTER E WITH GRAVE
  (#x8B #x00EF) ; LATIN SMALL LETTER I WITH DIAERESIS
  (#x8C #x00EE) ; LATIN SMALL LETTER I WITH CIRCUMFLEX
  (#x8D #x00EC) ; LATIN SMALL LETTER I WITH GRAVE
  (#x8E #x00C4) ; LATIN CAPITAL LETTER A WITH DIAERESIS
  (#x8F #x00C5) ; LATIN CAPITAL LETTER A WITH RING ABOVE
  (#x90 #x00C9) ; LATIN CAPITAL LETTER E WITH ACUTE
  (#x91 #x00E6) ; LATIN SMALL LIGATURE AE
  (#x92 #x00C6) ; LATIN CAPITAL LIGATURE AE
  (#x93 #x00F4) ; LATIN SMALL LETTER O WITH CIRCUMFLEX
  (#x94 #x00F6) ; LATIN SMALL LETTER O WITH DIAERESIS
  (#x95 #x00F2) ; LATIN SMALL LETTER O WITH GRAVE
  (#x96 #x00FB) ; LATIN SMALL LETTER U WITH CIRCUMFLEX
  (#x97 #x00F9) ; LATIN SMALL LETTER U WITH GRAVE
  (#x98 #x00FF) ; LATIN SMALL LETTER Y WITH DIAERESIS
  (#x99 #x00D6) ; LATIN CAPITAL LETTER O WITH DIAERESIS
  (#x9A #x00DC) ; LATIN CAPITAL LETTER U WITH DIAERESIS
  (#x9B #x00A2) ; CENT SIGN
  (#x9C #x00A3) ; POUND SIGN
  (#x9D #x00A5) ; YEN SIGN
  (#x9E #x20A7) ; PESETA SIGN
  (#x9F #x0192) ; LATIN SMALL LETTER F WITH HOOK
  (#xA0 #x00E1) ; LATIN SMALL LETTER A WITH ACUTE
  (#xA1 #x00ED) ; LATIN SMALL LETTER I WITH ACUTE
  (#xA2 #x00F3) ; LATIN SMALL LETTER O WITH ACUTE
  (#xA3 #x00FA) ; LATIN SMALL LETTER U WITH ACUTE
  (#xA4 #x00F1) ; LATIN SMALL LETTER N WITH TILDE
  (#xA5 #x00D1) ; LATIN CAPITAL LETTER N WITH TILDE
  (#xA6 #x00AA) ; FEMININE ORDINAL INDICATOR
  (#xA7 #x00BA) ; MASCULINE ORDINAL INDICATOR
  (#xA8 #x00BF) ; INVERTED QUESTION MARK
  (#xA9 #x2310) ; REVERSED NOT SIGN
  (#xAA #x00AC) ; NOT SIGN
  (#xAB #x00BD) ; VULGAR FRACTION ONE HALF
  (#xAC #x00BC) ; VULGAR FRACTION ONE QUARTER
  (#xAD #x00A1) ; INVERTED EXCLAMATION MARK
  (#xAE #x00AB) ; LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
  (#xAF #x00BB) ; RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
  (#xB0 #x2591) ; LIGHT SHADE
  (#xB1 #x2592) ; MEDIUM SHADE
  (#xB2 #x2593) ; DARK SHADE
  (#xB3 #x2502) ; BOX DRAWINGS LIGHT VERTICAL
  (#xB4 #x2524) ; BOX DRAWINGS LIGHT VERTICAL AND LEFT
  (#xB5 #x2561) ; BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE
  (#xB6 #x2562) ; BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE
  (#xB7 #x2556) ; BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE
  (#xB8 #x2555) ; BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE
  (#xB9 #x2563) ; BOX DRAWINGS DOUBLE VERTICAL AND LEFT
  (#xBA #x2551) ; BOX DRAWINGS DOUBLE VERTICAL
  (#xBB #x2557) ; BOX DRAWINGS DOUBLE DOWN AND LEFT
  (#xBC #x255D) ; BOX DRAWINGS DOUBLE UP AND LEFT
  (#xBD #x255C) ; BOX DRAWINGS UP DOUBLE AND LEFT SINGLE
  (#xBE #x255B) ; BOX DRAWINGS UP SINGLE AND LEFT DOUBLE
  (#xBF #x2510) ; BOX DRAWINGS LIGHT DOWN AND LEFT
  (#xC0 #x2514) ; BOX DRAWINGS LIGHT UP AND RIGHT
  (#xC1 #x2534) ; BOX DRAWINGS LIGHT UP AND HORIZONTAL
  (#xC2 #x252C) ; BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
  (#xC3 #x251C) ; BOX DRAWINGS LIGHT VERTICAL AND RIGHT
  (#xC4 #x2500) ; BOX DRAWINGS LIGHT HORIZONTAL
  (#xC5 #x253C) ; BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
  (#xC6 #x255E) ; BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE
  (#xC7 #x255F) ; BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE
  (#xC8 #x255A) ; BOX DRAWINGS DOUBLE UP AND RIGHT
  (#xC9 #x2554) ; BOX DRAWINGS DOUBLE DOWN AND RIGHT
  (#xCA #x2569) ; BOX DRAWINGS DOUBLE UP AND HORIZONTAL
  (#xCB #x2566) ; BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
  (#xCC #x2560) ; BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
  (#xCD #x2550) ; BOX DRAWINGS DOUBLE HORIZONTAL
  (#xCE #x256C) ; BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
  (#xCF #x2567) ; BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE
  (#xD0 #x2568) ; BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE
  (#xD1 #x2564) ; BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE
  (#xD2 #x2565) ; BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE
  (#xD3 #x2559) ; BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE
  (#xD4 #x2558) ; BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE
  (#xD5 #x2552) ; BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE
  (#xD6 #x2553) ; BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE
  (#xD7 #x256B) ; BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE
  (#xD8 #x256A) ; BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE
  (#xD9 #x2518) ; BOX DRAWINGS LIGHT UP AND LEFT
  (#xDA #x250C) ; BOX DRAWINGS LIGHT DOWN AND RIGHT
  (#xDB #x2588) ; FULL BLOCK
  (#xDC #x2584) ; LOWER HALF BLOCK
  (#xDD #x258C) ; LEFT HALF BLOCK
  (#xDE #x2590) ; RIGHT HALF BLOCK
  (#xDF #x2580) ; UPPER HALF BLOCK
  (#xE0 #x03B1) ; GREEK SMALL LETTER ALPHA
  (#xE1 #x00DF) ; LATIN SMALL LETTER SHARP S
  (#xE2 #x0393) ; GREEK CAPITAL LETTER GAMMA
  (#xE3 #x03C0) ; GREEK SMALL LETTER PI
  (#xE4 #x03A3) ; GREEK CAPITAL LETTER SIGMA
  (#xE5 #x03C3) ; GREEK SMALL LETTER SIGMA
  (#xE6 #x00B5) ; MICRO SIGN
  (#xE7 #x03C4) ; GREEK SMALL LETTER TAU
  (#xE8 #x03A6) ; GREEK CAPITAL LETTER PHI
  (#xE9 #x0398) ; GREEK CAPITAL LETTER THETA
  (#xEA #x03A9) ; GREEK CAPITAL LETTER OMEGA
  (#xEB #x03B4) ; GREEK SMALL LETTER DELTA
  (#xEC #x221E) ; INFINITY
  (#xED #x03C6) ; GREEK SMALL LETTER PHI
  (#xEE #x03B5) ; GREEK SMALL LETTER EPSILON
  (#xEF #x2229) ; INTERSECTION
  (#xF0 #x2261) ; IDENTICAL TO
  (#xF1 #x00B1) ; PLUS-MINUS SIGN
  (#xF2 #x2265) ; GREATER-THAN OR EQUAL TO
  (#xF3 #x2264) ; LESS-THAN OR EQUAL TO
  (#xF4 #x2320) ; TOP HALF INTEGRAL
  (#xF5 #x2321) ; BOTTOM HALF INTEGRAL
  (#xF6 #x00F7) ; DIVISION SIGN
  (#xF7 #x2248) ; ALMOST EQUAL TO
  (#xF8 #x00B0) ; DEGREE SIGN
  (#xF9 #x2219) ; BULLET OPERATOR
  (#xFA #x00B7) ; MIDDLE DOT
  (#xFB #x221A) ; SQUARE ROOT
  (#xFC #x207F) ; SUPERSCRIPT LATIN SMALL LETTER N
  (#xFD #x00B2) ; SUPERSCRIPT TWO
  (#xFE #x25A0) ; BLACK SQUARE
  (#xFF #x00A0) ; NO-BREAK SPACE
)

(declaim (inline get-cp437-bytes))
(defun get-cp437-bytes (string pos)
  (declare (optimize speed (safety 0))
           (type simple-string string)
           (type array-range pos))
  (get-latin-bytes #'code->cp437-mapper :cp437 string pos))

(defun string->cp437 (string sstart send null-padding)
  (declare (optimize speed (safety 0))
           (type simple-string string)
           (type array-range sstart send))
  (values (string->latin% string sstart send #'get-cp437-bytes null-padding)))

(defmacro define-cp437->string* (accessor type)
  (declare (ignore type))
  (let ((name (make-od-name 'cp437->string* accessor)))
    `(progn
      (defun ,name (string sstart send array astart aend)
        (,(make-od-name 'latin->string* accessor) string sstart send array astart aend #'cp437->code-mapper)))))

(instantiate-octets-definition define-cp437->string*)

(defmacro define-cp437->string (accessor type)
  (declare (ignore type))
  `(defun ,(make-od-name 'cp437->string accessor) (array astart aend)
    (,(make-od-name 'latin->string accessor) array astart aend #'cp437->code-mapper)))

(instantiate-octets-definition define-cp437->string)

(add-external-format-funs '(:cp437 :|cp437|)
                          '(cp437->string-aref string->cp437))

(define-external-format (:cp437 :|cp437|)
    1 t
    (let ((cp437-byte (code->cp437-mapper bits)))
      (if cp437-byte
          (setf (sap-ref-8 sap tail) cp437-byte)
          (external-format-encoding-error stream bits)))
    (let ((code (cp437->code-mapper byte)))
      (if code
          (code-char code)
          (external-format-decoding-error stream byte)))) ;; TODO -- error check

(define-unibyte-mapper cp850->code-mapper code->cp850-mapper
  (#x80 #x00C7) ; LATIN CAPITAL LETTER C WITH CEDILLA
  (#x81 #x00FC) ; LATIN SMALL LETTER U WITH DIAERESIS
  (#x82 #x00E9) ; LATIN SMALL LETTER E WITH ACUTE
  (#x83 #x00E2) ; LATIN SMALL LETTER A WITH CIRCUMFLEX
  (#x84 #x00E4) ; LATIN SMALL LETTER A WITH DIAERESIS
  (#x85 #x00E0) ; LATIN SMALL LETTER A WITH GRAVE
  (#x86 #x00E5) ; LATIN SMALL LETTER A WITH RING ABOVE
  (#x87 #x00E7) ; LATIN SMALL LETTER C WITH CEDILLA
  (#x88 #x00EA) ; LATIN SMALL LETTER E WITH CIRCUMFLEX
  (#x89 #x00EB) ; LATIN SMALL LETTER E WITH DIAERESIS
  (#x8A #x00E8) ; LATIN SMALL LETTER E WITH GRAVE
  (#x8B #x00EF) ; LATIN SMALL LETTER I WITH DIAERESIS
  (#x8C #x00EE) ; LATIN SMALL LETTER I WITH CIRCUMFLEX
  (#x8D #x00EC) ; LATIN SMALL LETTER I WITH GRAVE
  (#x8E #x00C4) ; LATIN CAPITAL LETTER A WITH DIAERESIS
  (#x8F #x00C5) ; LATIN CAPITAL LETTER A WITH RING ABOVE
  (#x90 #x00C9) ; LATIN CAPITAL LETTER E WITH ACUTE
  (#x91 #x00E6) ; LATIN SMALL LIGATURE AE
  (#x92 #x00C6) ; LATIN CAPITAL LIGATURE AE
  (#x93 #x00F4) ; LATIN SMALL LETTER O WITH CIRCUMFLEX
  (#x94 #x00F6) ; LATIN SMALL LETTER O WITH DIAERESIS
  (#x95 #x00F2) ; LATIN SMALL LETTER O WITH GRAVE
  (#x96 #x00FB) ; LATIN SMALL LETTER U WITH CIRCUMFLEX
  (#x97 #x00F9) ; LATIN SMALL LETTER U WITH GRAVE
  (#x98 #x00FF) ; LATIN SMALL LETTER Y WITH DIAERESIS
  (#x99 #x00D6) ; LATIN CAPITAL LETTER O WITH DIAERESIS
  (#x9A #x00DC) ; LATIN CAPITAL LETTER U WITH DIAERESIS
  (#x9B #x00F8) ; LATIN SMALL LETTER O WITH STROKE
  (#x9C #x00A3) ; POUND SIGN
  (#x9D #x00D8) ; LATIN CAPITAL LETTER O WITH STROKE
  (#x9E #x00D7) ; MULTIPLICATION SIGN
  (#x9F #x0192) ; LATIN SMALL LETTER F WITH HOOK
  (#xA0 #x00E1) ; LATIN SMALL LETTER A WITH ACUTE
  (#xA1 #x00ED) ; LATIN SMALL LETTER I WITH ACUTE
  (#xA2 #x00F3) ; LATIN SMALL LETTER O WITH ACUTE
  (#xA3 #x00FA) ; LATIN SMALL LETTER U WITH ACUTE
  (#xA4 #x00F1) ; LATIN SMALL LETTER N WITH TILDE
  (#xA5 #x00D1) ; LATIN CAPITAL LETTER N WITH TILDE
  (#xA6 #x00AA) ; FEMININE ORDINAL INDICATOR
  (#xA7 #x00BA) ; MASCULINE ORDINAL INDICATOR
  (#xA8 #x00BF) ; INVERTED QUESTION MARK
  (#xA9 #x00AE) ; REGISTERED SIGN
  (#xAA #x00AC) ; NOT SIGN
  (#xAB #x00BD) ; VULGAR FRACTION ONE HALF
  (#xAC #x00BC) ; VULGAR FRACTION ONE QUARTER
  (#xAD #x00A1) ; INVERTED EXCLAMATION MARK
  (#xAE #x00AB) ; LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
  (#xAF #x00BB) ; RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
  (#xB0 #x2591) ; LIGHT SHADE
  (#xB1 #x2592) ; MEDIUM SHADE
  (#xB2 #x2593) ; DARK SHADE
  (#xB3 #x2502) ; BOX DRAWINGS LIGHT VERTICAL
  (#xB4 #x2524) ; BOX DRAWINGS LIGHT VERTICAL AND LEFT
  (#xB5 #x00C1) ; LATIN CAPITAL LETTER A WITH ACUTE
  (#xB6 #x00C2) ; LATIN CAPITAL LETTER A WITH CIRCUMFLEX
  (#xB7 #x00C0) ; LATIN CAPITAL LETTER A WITH GRAVE
  (#xB8 #x00A9) ; COPYRIGHT SIGN
  (#xB9 #x2563) ; BOX DRAWINGS DOUBLE VERTICAL AND LEFT
  (#xBA #x2551) ; BOX DRAWINGS DOUBLE VERTICAL
  (#xBB #x2557) ; BOX DRAWINGS DOUBLE DOWN AND LEFT
  (#xBC #x255D) ; BOX DRAWINGS DOUBLE UP AND LEFT
  (#xBD #x00A2) ; CENT SIGN
  (#xBE #x00A5) ; YEN SIGN
  (#xBF #x2510) ; BOX DRAWINGS LIGHT DOWN AND LEFT
  (#xC0 #x2514) ; BOX DRAWINGS LIGHT UP AND RIGHT
  (#xC1 #x2534) ; BOX DRAWINGS LIGHT UP AND HORIZONTAL
  (#xC2 #x252C) ; BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
  (#xC3 #x251C) ; BOX DRAWINGS LIGHT VERTICAL AND RIGHT
  (#xC4 #x2500) ; BOX DRAWINGS LIGHT HORIZONTAL
  (#xC5 #x253C) ; BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
  (#xC6 #x00E3) ; LATIN SMALL LETTER A WITH TILDE
  (#xC7 #x00C3) ; LATIN CAPITAL LETTER A WITH TILDE
  (#xC8 #x255A) ; BOX DRAWINGS DOUBLE UP AND RIGHT
  (#xC9 #x2554) ; BOX DRAWINGS DOUBLE DOWN AND RIGHT
  (#xCA #x2569) ; BOX DRAWINGS DOUBLE UP AND HORIZONTAL
  (#xCB #x2566) ; BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
  (#xCC #x2560) ; BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
  (#xCD #x2550) ; BOX DRAWINGS DOUBLE HORIZONTAL
  (#xCE #x256C) ; BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
  (#xCF #x00A4) ; CURRENCY SIGN
  (#xD0 #x00F0) ; LATIN SMALL LETTER ETH
  (#xD1 #x00D0) ; LATIN CAPITAL LETTER ETH
  (#xD2 #x00CA) ; LATIN CAPITAL LETTER E WITH CIRCUMFLEX
  (#xD3 #x00CB) ; LATIN CAPITAL LETTER E WITH DIAERESIS
  (#xD4 #x00C8) ; LATIN CAPITAL LETTER E WITH GRAVE
  (#xD5 #x0131) ; LATIN SMALL LETTER DOTLESS I
  (#xD6 #x00CD) ; LATIN CAPITAL LETTER I WITH ACUTE
  (#xD7 #x00CE) ; LATIN CAPITAL LETTER I WITH CIRCUMFLEX
  (#xD8 #x00CF) ; LATIN CAPITAL LETTER I WITH DIAERESIS
  (#xD9 #x2518) ; BOX DRAWINGS LIGHT UP AND LEFT
  (#xDA #x250C) ; BOX DRAWINGS LIGHT DOWN AND RIGHT
  (#xDB #x2588) ; FULL BLOCK
  (#xDC #x2584) ; LOWER HALF BLOCK
  (#xDD #x00A6) ; BROKEN BAR
  (#xDE #x00CC) ; LATIN CAPITAL LETTER I WITH GRAVE
  (#xDF #x2580) ; UPPER HALF BLOCK
  (#xE0 #x00D3) ; LATIN CAPITAL LETTER O WITH ACUTE
  (#xE1 #x00DF) ; LATIN SMALL LETTER SHARP S
  (#xE2 #x00D4) ; LATIN CAPITAL LETTER O WITH CIRCUMFLEX
  (#xE3 #x00D2) ; LATIN CAPITAL LETTER O WITH GRAVE
  (#xE4 #x00F5) ; LATIN SMALL LETTER O WITH TILDE
  (#xE5 #x00D5) ; LATIN CAPITAL LETTER O WITH TILDE
  (#xE6 #x00B5) ; MICRO SIGN
  (#xE7 #x00FE) ; LATIN SMALL LETTER THORN
  (#xE8 #x00DE) ; LATIN CAPITAL LETTER THORN
  (#xE9 #x00DA) ; LATIN CAPITAL LETTER U WITH ACUTE
  (#xEA #x00DB) ; LATIN CAPITAL LETTER U WITH CIRCUMFLEX
  (#xEB #x00D9) ; LATIN CAPITAL LETTER U WITH GRAVE
  (#xEC #x00FD) ; LATIN SMALL LETTER Y WITH ACUTE
  (#xED #x00DD) ; LATIN CAPITAL LETTER Y WITH ACUTE
  (#xEE #x00AF) ; MACRON
  (#xEF #x00B4) ; ACUTE ACCENT
  (#xF0 #x00AD) ; SOFT HYPHEN
  (#xF1 #x00B1) ; PLUS-MINUS SIGN
  (#xF2 #x2017) ; DOUBLE LOW LINE
  (#xF3 #x00BE) ; VULGAR FRACTION THREE QUARTERS
  (#xF4 #x00B6) ; PILCROW SIGN
  (#xF5 #x00A7) ; SECTION SIGN
  (#xF6 #x00F7) ; DIVISION SIGN
  (#xF7 #x00B8) ; CEDILLA
  (#xF8 #x00B0) ; DEGREE SIGN
  (#xF9 #x00A8) ; DIAERESIS
  (#xFA #x00B7) ; MIDDLE DOT
  (#xFB #x00B9) ; SUPERSCRIPT ONE
  (#xFC #x00B3) ; SUPERSCRIPT THREE
  (#xFD #x00B2) ; SUPERSCRIPT TWO
  (#xFE #x25A0) ; BLACK SQUARE
  (#xFF #x00A0) ; NO-BREAK SPACE
)

(declaim (inline get-cp850-bytes))
(defun get-cp850-bytes (string pos)
  (declare (optimize speed (safety 0))
           (type simple-string string)
           (type array-range pos))
  (get-latin-bytes #'code->cp850-mapper :cp850 string pos))

(defun string->cp850 (string sstart send null-padding)
  (declare (optimize speed (safety 0))
           (type simple-string string)
           (type array-range sstart send))
  (values (string->latin% string sstart send #'get-cp850-bytes null-padding)))

(defmacro define-cp850->string* (accessor type)
  (declare (ignore type))
  (let ((name (make-od-name 'cp850->string* accessor)))
    `(progn
      (defun ,name (string sstart send array astart aend)
        (,(make-od-name 'latin->string* accessor) string sstart send array astart aend #'cp850->code-mapper)))))

(instantiate-octets-definition define-cp850->string*)

(defmacro define-cp850->string (accessor type)
  (declare (ignore type))
  `(defun ,(make-od-name 'cp850->string accessor) (array astart aend)
    (,(make-od-name 'latin->string accessor) array astart aend #'cp850->code-mapper)))

(instantiate-octets-definition define-cp850->string)

(add-external-format-funs '(:cp850 :|cp850|)
                          '(cp850->string-aref string->cp850))

(define-external-format (:cp850 :|cp850|)
    1 t
    (let ((cp850-byte (code->cp850-mapper bits)))
      (if cp850-byte
          (setf (sap-ref-8 sap tail) cp850-byte)
          (external-format-encoding-error stream bits)))
    (let ((code (cp850->code-mapper byte)))
      (if code
          (code-char code)
          (external-format-decoding-error stream byte)))) ;; TODO -- error check

(define-unibyte-mapper cp852->code-mapper code->cp852-mapper
  (#x80 #x00C7) ; LATIN CAPITAL LETTER C WITH CEDILLA
  (#x81 #x00FC) ; LATIN SMALL LETTER U WITH DIAERESIS
  (#x82 #x00E9) ; LATIN SMALL LETTER E WITH ACUTE
  (#x83 #x00E2) ; LATIN SMALL LETTER A WITH CIRCUMFLEX
  (#x84 #x00E4) ; LATIN SMALL LETTER A WITH DIAERESIS
  (#x85 #x016F) ; LATIN SMALL LETTER U WITH RING ABOVE
  (#x86 #x0107) ; LATIN SMALL LETTER C WITH ACUTE
  (#x87 #x00E7) ; LATIN SMALL LETTER C WITH CEDILLA
  (#x88 #x0142) ; LATIN SMALL LETTER L WITH STROKE
  (#x89 #x00EB) ; LATIN SMALL LETTER E WITH DIAERESIS
  (#x8A #x0150) ; LATIN CAPITAL LETTER O WITH DOUBLE ACUTE
  (#x8B #x0151) ; LATIN SMALL LETTER O WITH DOUBLE ACUTE
  (#x8C #x00EE) ; LATIN SMALL LETTER I WITH CIRCUMFLEX
  (#x8D #x0179) ; LATIN CAPITAL LETTER Z WITH ACUTE
  (#x8E #x00C4) ; LATIN CAPITAL LETTER A WITH DIAERESIS
  (#x8F #x0106) ; LATIN CAPITAL LETTER C WITH ACUTE
  (#x90 #x00C9) ; LATIN CAPITAL LETTER E WITH ACUTE
  (#x91 #x0139) ; LATIN CAPITAL LETTER L WITH ACUTE
  (#x92 #x013A) ; LATIN SMALL LETTER L WITH ACUTE
  (#x93 #x00F4) ; LATIN SMALL LETTER O WITH CIRCUMFLEX
  (#x94 #x00F6) ; LATIN SMALL LETTER O WITH DIAERESIS
  (#x95 #x013D) ; LATIN CAPITAL LETTER L WITH CARON
  (#x96 #x013E) ; LATIN SMALL LETTER L WITH CARON
  (#x97 #x015A) ; LATIN CAPITAL LETTER S WITH ACUTE
  (#x98 #x015B) ; LATIN SMALL LETTER S WITH ACUTE
  (#x99 #x00D6) ; LATIN CAPITAL LETTER O WITH DIAERESIS
  (#x9A #x00DC) ; LATIN CAPITAL LETTER U WITH DIAERESIS
  (#x9B #x0164) ; LATIN CAPITAL LETTER T WITH CARON
  (#x9C #x0165) ; LATIN SMALL LETTER T WITH CARON
  (#x9D #x0141) ; LATIN CAPITAL LETTER L WITH STROKE
  (#x9E #x00D7) ; MULTIPLICATION SIGN
  (#x9F #x010D) ; LATIN SMALL LETTER C WITH CARON
  (#xA0 #x00E1) ; LATIN SMALL LETTER A WITH ACUTE
  (#xA1 #x00ED) ; LATIN SMALL LETTER I WITH ACUTE
  (#xA2 #x00F3) ; LATIN SMALL LETTER O WITH ACUTE
  (#xA3 #x00FA) ; LATIN SMALL LETTER U WITH ACUTE
  (#xA4 #x0104) ; LATIN CAPITAL LETTER A WITH OGONEK
  (#xA5 #x0105) ; LATIN SMALL LETTER A WITH OGONEK
  (#xA6 #x017D) ; LATIN CAPITAL LETTER Z WITH CARON
  (#xA7 #x017E) ; LATIN SMALL LETTER Z WITH CARON
  (#xA8 #x0118) ; LATIN CAPITAL LETTER E WITH OGONEK
  (#xA9 #x0119) ; LATIN SMALL LETTER E WITH OGONEK
  (#xAA #x00AC) ; NOT SIGN
  (#xAB #x017A) ; LATIN SMALL LETTER Z WITH ACUTE
  (#xAC #x010C) ; LATIN CAPITAL LETTER C WITH CARON
  (#xAD #x015F) ; LATIN SMALL LETTER S WITH CEDILLA
  (#xAE #x00AB) ; LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
  (#xAF #x00BB) ; RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
  (#xB0 #x2591) ; LIGHT SHADE
  (#xB1 #x2592) ; MEDIUM SHADE
  (#xB2 #x2593) ; DARK SHADE
  (#xB3 #x2502) ; BOX DRAWINGS LIGHT VERTICAL
  (#xB4 #x2524) ; BOX DRAWINGS LIGHT VERTICAL AND LEFT
  (#xB5 #x00C1) ; LATIN CAPITAL LETTER A WITH ACUTE
  (#xB6 #x00C2) ; LATIN CAPITAL LETTER A WITH CIRCUMFLEX
  (#xB7 #x011A) ; LATIN CAPITAL LETTER E WITH CARON
  (#xB8 #x015E) ; LATIN CAPITAL LETTER S WITH CEDILLA
  (#xB9 #x2563) ; BOX DRAWINGS DOUBLE VERTICAL AND LEFT
  (#xBA #x2551) ; BOX DRAWINGS DOUBLE VERTICAL
  (#xBB #x2557) ; BOX DRAWINGS DOUBLE DOWN AND LEFT
  (#xBC #x255D) ; BOX DRAWINGS DOUBLE UP AND LEFT
  (#xBD #x017B) ; LATIN CAPITAL LETTER Z WITH DOT ABOVE
  (#xBE #x017C) ; LATIN SMALL LETTER Z WITH DOT ABOVE
  (#xBF #x2510) ; BOX DRAWINGS LIGHT DOWN AND LEFT
  (#xC0 #x2514) ; BOX DRAWINGS LIGHT UP AND RIGHT
  (#xC1 #x2534) ; BOX DRAWINGS LIGHT UP AND HORIZONTAL
  (#xC2 #x252C) ; BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
  (#xC3 #x251C) ; BOX DRAWINGS LIGHT VERTICAL AND RIGHT
  (#xC4 #x2500) ; BOX DRAWINGS LIGHT HORIZONTAL
  (#xC5 #x253C) ; BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
  (#xC6 #x0102) ; LATIN CAPITAL LETTER A WITH BREVE
  (#xC7 #x0103) ; LATIN SMALL LETTER A WITH BREVE
  (#xC8 #x255A) ; BOX DRAWINGS DOUBLE UP AND RIGHT
  (#xC9 #x2554) ; BOX DRAWINGS DOUBLE DOWN AND RIGHT
  (#xCA #x2569) ; BOX DRAWINGS DOUBLE UP AND HORIZONTAL
  (#xCB #x2566) ; BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
  (#xCC #x2560) ; BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
  (#xCD #x2550) ; BOX DRAWINGS DOUBLE HORIZONTAL
  (#xCE #x256C) ; BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
  (#xCF #x00A4) ; CURRENCY SIGN
  (#xD0 #x0111) ; LATIN SMALL LETTER D WITH STROKE
  (#xD1 #x0110) ; LATIN CAPITAL LETTER D WITH STROKE
  (#xD2 #x010E) ; LATIN CAPITAL LETTER D WITH CARON
  (#xD3 #x00CB) ; LATIN CAPITAL LETTER E WITH DIAERESIS
  (#xD4 #x010F) ; LATIN SMALL LETTER D WITH CARON
  (#xD5 #x0147) ; LATIN CAPITAL LETTER N WITH CARON
  (#xD6 #x00CD) ; LATIN CAPITAL LETTER I WITH ACUTE
  (#xD7 #x00CE) ; LATIN CAPITAL LETTER I WITH CIRCUMFLEX
  (#xD8 #x011B) ; LATIN SMALL LETTER E WITH CARON
  (#xD9 #x2518) ; BOX DRAWINGS LIGHT UP AND LEFT
  (#xDA #x250C) ; BOX DRAWINGS LIGHT DOWN AND RIGHT
  (#xDB #x2588) ; FULL BLOCK
  (#xDC #x2584) ; LOWER HALF BLOCK
  (#xDD #x0162) ; LATIN CAPITAL LETTER T WITH CEDILLA
  (#xDE #x016E) ; LATIN CAPITAL LETTER U WITH RING ABOVE
  (#xDF #x2580) ; UPPER HALF BLOCK
  (#xE0 #x00D3) ; LATIN CAPITAL LETTER O WITH ACUTE
  (#xE1 #x00DF) ; LATIN SMALL LETTER SHARP S
  (#xE2 #x00D4) ; LATIN CAPITAL LETTER O WITH CIRCUMFLEX
  (#xE3 #x0143) ; LATIN CAPITAL LETTER N WITH ACUTE
  (#xE4 #x0144) ; LATIN SMALL LETTER N WITH ACUTE
  (#xE5 #x0148) ; LATIN SMALL LETTER N WITH CARON
  (#xE6 #x0160) ; LATIN CAPITAL LETTER S WITH CARON
  (#xE7 #x0161) ; LATIN SMALL LETTER S WITH CARON
  (#xE8 #x0154) ; LATIN CAPITAL LETTER R WITH ACUTE
  (#xE9 #x00DA) ; LATIN CAPITAL LETTER U WITH ACUTE
  (#xEA #x0155) ; LATIN SMALL LETTER R WITH ACUTE
  (#xEB #x0170) ; LATIN CAPITAL LETTER U WITH DOUBLE ACUTE
  (#xEC #x00FD) ; LATIN SMALL LETTER Y WITH ACUTE
  (#xED #x00DD) ; LATIN CAPITAL LETTER Y WITH ACUTE
  (#xEE #x0163) ; LATIN SMALL LETTER T WITH CEDILLA
  (#xEF #x00B4) ; ACUTE ACCENT
  (#xF0 #x00AD) ; SOFT HYPHEN
  (#xF1 #x02DD) ; DOUBLE ACUTE ACCENT
  (#xF2 #x02DB) ; OGONEK
  (#xF3 #x02C7) ; CARON
  (#xF4 #x02D8) ; BREVE
  (#xF5 #x00A7) ; SECTION SIGN
  (#xF6 #x00F7) ; DIVISION SIGN
  (#xF7 #x00B8) ; CEDILLA
  (#xF8 #x00B0) ; DEGREE SIGN
  (#xF9 #x00A8) ; DIAERESIS
  (#xFA #x02D9) ; DOT ABOVE
  (#xFB #x0171) ; LATIN SMALL LETTER U WITH DOUBLE ACUTE
  (#xFC #x0158) ; LATIN CAPITAL LETTER R WITH CARON
  (#xFD #x0159) ; LATIN SMALL LETTER R WITH CARON
  (#xFE #x25A0) ; BLACK SQUARE
  (#xFF #x00A0) ; NO-BREAK SPACE
)

(declaim (inline get-cp852-bytes))
(defun get-cp852-bytes (string pos)
  (declare (optimize speed (safety 0))
           (type simple-string string)
           (type array-range pos))
  (get-latin-bytes #'code->cp852-mapper :cp852 string pos))

(defun string->cp852 (string sstart send null-padding)
  (declare (optimize speed (safety 0))
           (type simple-string string)
           (type array-range sstart send))
  (values (string->latin% string sstart send #'get-cp852-bytes null-padding)))

(defmacro define-cp852->string* (accessor type)
  (declare (ignore type))
  (let ((name (make-od-name 'cp852->string* accessor)))
    `(progn
      (defun ,name (string sstart send array astart aend)
        (,(make-od-name 'latin->string* accessor) string sstart send array astart aend #'cp852->code-mapper)))))

(instantiate-octets-definition define-cp852->string*)

(defmacro define-cp852->string (accessor type)
  (declare (ignore type))
  `(defun ,(make-od-name 'cp852->string accessor) (array astart aend)
    (,(make-od-name 'latin->string accessor) array astart aend #'cp852->code-mapper)))

(instantiate-octets-definition define-cp852->string)

(add-external-format-funs '(:cp852 :|cp852|)
                          '(cp852->string-aref string->cp852))

(define-external-format (:cp852 :|cp852|)
    1 t
    (let ((cp852-byte (code->cp852-mapper bits)))
      (if cp852-byte
          (setf (sap-ref-8 sap tail) cp852-byte)
          (external-format-encoding-error stream bits)))
    (let ((code (cp852->code-mapper byte)))
      (if code
          (code-char code)
          (external-format-decoding-error stream byte)))) ;; TODO -- error check

(define-unibyte-mapper cp855->code-mapper code->cp855-mapper
  (#x80 #x0452) ; CYRILLIC SMALL LETTER DJE
  (#x81 #x0402) ; CYRILLIC CAPITAL LETTER DJE
  (#x82 #x0453) ; CYRILLIC SMALL LETTER GJE
  (#x83 #x0403) ; CYRILLIC CAPITAL LETTER GJE
  (#x84 #x0451) ; CYRILLIC SMALL LETTER IO
  (#x85 #x0401) ; CYRILLIC CAPITAL LETTER IO
  (#x86 #x0454) ; CYRILLIC SMALL LETTER UKRAINIAN IE
  (#x87 #x0404) ; CYRILLIC CAPITAL LETTER UKRAINIAN IE
  (#x88 #x0455) ; CYRILLIC SMALL LETTER DZE
  (#x89 #x0405) ; CYRILLIC CAPITAL LETTER DZE
  (#x8A #x0456) ; CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I
  (#x8B #x0406) ; CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I
  (#x8C #x0457) ; CYRILLIC SMALL LETTER YI
  (#x8D #x0407) ; CYRILLIC CAPITAL LETTER YI
  (#x8E #x0458) ; CYRILLIC SMALL LETTER JE
  (#x8F #x0408) ; CYRILLIC CAPITAL LETTER JE
  (#x90 #x0459) ; CYRILLIC SMALL LETTER LJE
  (#x91 #x0409) ; CYRILLIC CAPITAL LETTER LJE
  (#x92 #x045A) ; CYRILLIC SMALL LETTER NJE
  (#x93 #x040A) ; CYRILLIC CAPITAL LETTER NJE
  (#x94 #x045B) ; CYRILLIC SMALL LETTER TSHE
  (#x95 #x040B) ; CYRILLIC CAPITAL LETTER TSHE
  (#x96 #x045C) ; CYRILLIC SMALL LETTER KJE
  (#x97 #x040C) ; CYRILLIC CAPITAL LETTER KJE
  (#x98 #x045E) ; CYRILLIC SMALL LETTER SHORT U
  (#x99 #x040E) ; CYRILLIC CAPITAL LETTER SHORT U
  (#x9A #x045F) ; CYRILLIC SMALL LETTER DZHE
  (#x9B #x040F) ; CYRILLIC CAPITAL LETTER DZHE
  (#x9C #x044E) ; CYRILLIC SMALL LETTER YU
  (#x9D #x042E) ; CYRILLIC CAPITAL LETTER YU
  (#x9E #x044A) ; CYRILLIC SMALL LETTER HARD SIGN
  (#x9F #x042A) ; CYRILLIC CAPITAL LETTER HARD SIGN
  (#xA0 #x0430) ; CYRILLIC SMALL LETTER A
  (#xA1 #x0410) ; CYRILLIC CAPITAL LETTER A
  (#xA2 #x0431) ; CYRILLIC SMALL LETTER BE
  (#xA3 #x0411) ; CYRILLIC CAPITAL LETTER BE
  (#xA4 #x0446) ; CYRILLIC SMALL LETTER TSE
  (#xA5 #x0426) ; CYRILLIC CAPITAL LETTER TSE
  (#xA6 #x0434) ; CYRILLIC SMALL LETTER DE
  (#xA7 #x0414) ; CYRILLIC CAPITAL LETTER DE
  (#xA8 #x0435) ; CYRILLIC SMALL LETTER IE
  (#xA9 #x0415) ; CYRILLIC CAPITAL LETTER IE
  (#xAA #x0444) ; CYRILLIC SMALL LETTER EF
  (#xAB #x0424) ; CYRILLIC CAPITAL LETTER EF
  (#xAC #x0433) ; CYRILLIC SMALL LETTER GHE
  (#xAD #x0413) ; CYRILLIC CAPITAL LETTER GHE
  (#xAE #x00AB) ; LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
  (#xAF #x00BB) ; RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
  (#xB0 #x2591) ; LIGHT SHADE
  (#xB1 #x2592) ; MEDIUM SHADE
  (#xB2 #x2593) ; DARK SHADE
  (#xB3 #x2502) ; BOX DRAWINGS LIGHT VERTICAL
  (#xB4 #x2524) ; BOX DRAWINGS LIGHT VERTICAL AND LEFT
  (#xB5 #x0445) ; CYRILLIC SMALL LETTER HA
  (#xB6 #x0425) ; CYRILLIC CAPITAL LETTER HA
  (#xB7 #x0438) ; CYRILLIC SMALL LETTER I
  (#xB8 #x0418) ; CYRILLIC CAPITAL LETTER I
  (#xB9 #x2563) ; BOX DRAWINGS DOUBLE VERTICAL AND LEFT
  (#xBA #x2551) ; BOX DRAWINGS DOUBLE VERTICAL
  (#xBB #x2557) ; BOX DRAWINGS DOUBLE DOWN AND LEFT
  (#xBC #x255D) ; BOX DRAWINGS DOUBLE UP AND LEFT
  (#xBD #x0439) ; CYRILLIC SMALL LETTER SHORT I
  (#xBE #x0419) ; CYRILLIC CAPITAL LETTER SHORT I
  (#xBF #x2510) ; BOX DRAWINGS LIGHT DOWN AND LEFT
  (#xC0 #x2514) ; BOX DRAWINGS LIGHT UP AND RIGHT
  (#xC1 #x2534) ; BOX DRAWINGS LIGHT UP AND HORIZONTAL
  (#xC2 #x252C) ; BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
  (#xC3 #x251C) ; BOX DRAWINGS LIGHT VERTICAL AND RIGHT
  (#xC4 #x2500) ; BOX DRAWINGS LIGHT HORIZONTAL
  (#xC5 #x253C) ; BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
  (#xC6 #x043A) ; CYRILLIC SMALL LETTER KA
  (#xC7 #x041A) ; CYRILLIC CAPITAL LETTER KA
  (#xC8 #x255A) ; BOX DRAWINGS DOUBLE UP AND RIGHT
  (#xC9 #x2554) ; BOX DRAWINGS DOUBLE DOWN AND RIGHT
  (#xCA #x2569) ; BOX DRAWINGS DOUBLE UP AND HORIZONTAL
  (#xCB #x2566) ; BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
  (#xCC #x2560) ; BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
  (#xCD #x2550) ; BOX DRAWINGS DOUBLE HORIZONTAL
  (#xCE #x256C) ; BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
  (#xCF #x00A4) ; CURRENCY SIGN
  (#xD0 #x043B) ; CYRILLIC SMALL LETTER EL
  (#xD1 #x041B) ; CYRILLIC CAPITAL LETTER EL
  (#xD2 #x043C) ; CYRILLIC SMALL LETTER EM
  (#xD3 #x041C) ; CYRILLIC CAPITAL LETTER EM
  (#xD4 #x043D) ; CYRILLIC SMALL LETTER EN
  (#xD5 #x041D) ; CYRILLIC CAPITAL LETTER EN
  (#xD6 #x043E) ; CYRILLIC SMALL LETTER O
  (#xD7 #x041E) ; CYRILLIC CAPITAL LETTER O
  (#xD8 #x043F) ; CYRILLIC SMALL LETTER PE
  (#xD9 #x2518) ; BOX DRAWINGS LIGHT UP AND LEFT
  (#xDA #x250C) ; BOX DRAWINGS LIGHT DOWN AND RIGHT
  (#xDB #x2588) ; FULL BLOCK
  (#xDC #x2584) ; LOWER HALF BLOCK
  (#xDD #x041F) ; CYRILLIC CAPITAL LETTER PE
  (#xDE #x044F) ; CYRILLIC SMALL LETTER YA
  (#xDF #x2580) ; UPPER HALF BLOCK
  (#xE0 #x042F) ; CYRILLIC CAPITAL LETTER YA
  (#xE1 #x0440) ; CYRILLIC SMALL LETTER ER
  (#xE2 #x0420) ; CYRILLIC CAPITAL LETTER ER
  (#xE3 #x0441) ; CYRILLIC SMALL LETTER ES
  (#xE4 #x0421) ; CYRILLIC CAPITAL LETTER ES
  (#xE5 #x0442) ; CYRILLIC SMALL LETTER TE
  (#xE6 #x0422) ; CYRILLIC CAPITAL LETTER TE
  (#xE7 #x0443) ; CYRILLIC SMALL LETTER U
  (#xE8 #x0423) ; CYRILLIC CAPITAL LETTER U
  (#xE9 #x0436) ; CYRILLIC SMALL LETTER ZHE
  (#xEA #x0416) ; CYRILLIC CAPITAL LETTER ZHE
  (#xEB #x0432) ; CYRILLIC SMALL LETTER VE
  (#xEC #x0412) ; CYRILLIC CAPITAL LETTER VE
  (#xED #x044C) ; CYRILLIC SMALL LETTER SOFT SIGN
  (#xEE #x042C) ; CYRILLIC CAPITAL LETTER SOFT SIGN
  (#xEF #x2116) ; NUMERO SIGN
  (#xF0 #x00AD) ; SOFT HYPHEN
  (#xF1 #x044B) ; CYRILLIC SMALL LETTER YERU
  (#xF2 #x042B) ; CYRILLIC CAPITAL LETTER YERU
  (#xF3 #x0437) ; CYRILLIC SMALL LETTER ZE
  (#xF4 #x0417) ; CYRILLIC CAPITAL LETTER ZE
  (#xF5 #x0448) ; CYRILLIC SMALL LETTER SHA
  (#xF6 #x0428) ; CYRILLIC CAPITAL LETTER SHA
  (#xF7 #x044D) ; CYRILLIC SMALL LETTER E
  (#xF8 #x042D) ; CYRILLIC CAPITAL LETTER E
  (#xF9 #x0449) ; CYRILLIC SMALL LETTER SHCHA
  (#xFA #x0429) ; CYRILLIC CAPITAL LETTER SHCHA
  (#xFB #x0447) ; CYRILLIC SMALL LETTER CHE
  (#xFC #x0427) ; CYRILLIC CAPITAL LETTER CHE
  (#xFD #x00A7) ; SECTION SIGN
  (#xFE #x25A0) ; BLACK SQUARE
  (#xFF #x00A0) ; NO-BREAK SPACE
)

(declaim (inline get-cp855-bytes))
(defun get-cp855-bytes (string pos)
  (declare (optimize speed (safety 0))
           (type simple-string string)
           (type array-range pos))
  (get-latin-bytes #'code->cp855-mapper :cp855 string pos))

(defun string->cp855 (string sstart send null-padding)
  (declare (optimize speed (safety 0))
           (type simple-string string)
           (type array-range sstart send))
  (values (string->latin% string sstart send #'get-cp855-bytes null-padding)))

(defmacro define-cp855->string* (accessor type)
  (declare (ignore type))
  (let ((name (make-od-name 'cp855->string* accessor)))
    `(progn
      (defun ,name (string sstart send array astart aend)
        (,(make-od-name 'latin->string* accessor) string sstart send array astart aend #'cp855->code-mapper)))))

(instantiate-octets-definition define-cp855->string*)

(defmacro define-cp855->string (accessor type)
  (declare (ignore type))
  `(defun ,(make-od-name 'cp855->string accessor) (array astart aend)
    (,(make-od-name 'latin->string accessor) array astart aend #'cp855->code-mapper)))

(instantiate-octets-definition define-cp855->string)

(add-external-format-funs '(:cp855 :|cp855|)
                          '(cp855->string-aref string->cp855))

(define-external-format (:cp855 :|cp855|)
    1 t
    (let ((cp855-byte (code->cp855-mapper bits)))
      (if cp855-byte
          (setf (sap-ref-8 sap tail) cp855-byte)
          (external-format-encoding-error stream bits)))
    (let ((code (cp855->code-mapper byte)))
      (if code
          (code-char code)
          (external-format-decoding-error stream byte)))) ;; TODO -- error check

(define-unibyte-mapper cp857->code-mapper code->cp857-mapper
  (#x80 #x00C7) ; LATIN CAPITAL LETTER C WITH CEDILLA
  (#x81 #x00FC) ; LATIN SMALL LETTER U WITH DIAERESIS
  (#x82 #x00E9) ; LATIN SMALL LETTER E WITH ACUTE
  (#x83 #x00E2) ; LATIN SMALL LETTER A WITH CIRCUMFLEX
  (#x84 #x00E4) ; LATIN SMALL LETTER A WITH DIAERESIS
  (#x85 #x00E0) ; LATIN SMALL LETTER A WITH GRAVE
  (#x86 #x00E5) ; LATIN SMALL LETTER A WITH RING ABOVE
  (#x87 #x00E7) ; LATIN SMALL LETTER C WITH CEDILLA
  (#x88 #x00EA) ; LATIN SMALL LETTER E WITH CIRCUMFLEX
  (#x89 #x00EB) ; LATIN SMALL LETTER E WITH DIAERESIS
  (#x8A #x00E8) ; LATIN SMALL LETTER E WITH GRAVE
  (#x8B #x00EF) ; LATIN SMALL LETTER I WITH DIAERESIS
  (#x8C #x00EE) ; LATIN SMALL LETTER I WITH CIRCUMFLEX
  (#x8D #x0131) ; LATIN SMALL LETTER DOTLESS I
  (#x8E #x00C4) ; LATIN CAPITAL LETTER A WITH DIAERESIS
  (#x8F #x00C5) ; LATIN CAPITAL LETTER A WITH RING ABOVE
  (#x90 #x00C9) ; LATIN CAPITAL LETTER E WITH ACUTE
  (#x91 #x00E6) ; LATIN SMALL LIGATURE AE
  (#x92 #x00C6) ; LATIN CAPITAL LIGATURE AE
  (#x93 #x00F4) ; LATIN SMALL LETTER O WITH CIRCUMFLEX
  (#x94 #x00F6) ; LATIN SMALL LETTER O WITH DIAERESIS
  (#x95 #x00F2) ; LATIN SMALL LETTER O WITH GRAVE
  (#x96 #x00FB) ; LATIN SMALL LETTER U WITH CIRCUMFLEX
  (#x97 #x00F9) ; LATIN SMALL LETTER U WITH GRAVE
  (#x98 #x0130) ; LATIN CAPITAL LETTER I WITH DOT ABOVE
  (#x99 #x00D6) ; LATIN CAPITAL LETTER O WITH DIAERESIS
  (#x9A #x00DC) ; LATIN CAPITAL LETTER U WITH DIAERESIS
  (#x9B #x00F8) ; LATIN SMALL LETTER O WITH STROKE
  (#x9C #x00A3) ; POUND SIGN
  (#x9D #x00D8) ; LATIN CAPITAL LETTER O WITH STROKE
  (#x9E #x015E) ; LATIN CAPITAL LETTER S WITH CEDILLA
  (#x9F #x015F) ; LATIN SMALL LETTER S WITH CEDILLA
  (#xA0 #x00E1) ; LATIN SMALL LETTER A WITH ACUTE
  (#xA1 #x00ED) ; LATIN SMALL LETTER I WITH ACUTE
  (#xA2 #x00F3) ; LATIN SMALL LETTER O WITH ACUTE
  (#xA3 #x00FA) ; LATIN SMALL LETTER U WITH ACUTE
  (#xA4 #x00F1) ; LATIN SMALL LETTER N WITH TILDE
  (#xA5 #x00D1) ; LATIN CAPITAL LETTER N WITH TILDE
  (#xA6 #x011E) ; LATIN CAPITAL LETTER G WITH BREVE
  (#xA7 #x011F) ; LATIN SMALL LETTER G WITH BREVE
  (#xA8 #x00BF) ; INVERTED QUESTION MARK
  (#xA9 #x00AE) ; REGISTERED SIGN
  (#xAA #x00AC) ; NOT SIGN
  (#xAB #x00BD) ; VULGAR FRACTION ONE HALF
  (#xAC #x00BC) ; VULGAR FRACTION ONE QUARTER
  (#xAD #x00A1) ; INVERTED EXCLAMATION MARK
  (#xAE #x00AB) ; LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
  (#xAF #x00BB) ; RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
  (#xB0 #x2591) ; LIGHT SHADE
  (#xB1 #x2592) ; MEDIUM SHADE
  (#xB2 #x2593) ; DARK SHADE
  (#xB3 #x2502) ; BOX DRAWINGS LIGHT VERTICAL
  (#xB4 #x2524) ; BOX DRAWINGS LIGHT VERTICAL AND LEFT
  (#xB5 #x00C1) ; LATIN CAPITAL LETTER A WITH ACUTE
  (#xB6 #x00C2) ; LATIN CAPITAL LETTER A WITH CIRCUMFLEX
  (#xB7 #x00C0) ; LATIN CAPITAL LETTER A WITH GRAVE
  (#xB8 #x00A9) ; COPYRIGHT SIGN
  (#xB9 #x2563) ; BOX DRAWINGS DOUBLE VERTICAL AND LEFT
  (#xBA #x2551) ; BOX DRAWINGS DOUBLE VERTICAL
  (#xBB #x2557) ; BOX DRAWINGS DOUBLE DOWN AND LEFT
  (#xBC #x255D) ; BOX DRAWINGS DOUBLE UP AND LEFT
  (#xBD #x00A2) ; CENT SIGN
  (#xBE #x00A5) ; YEN SIGN
  (#xBF #x2510) ; BOX DRAWINGS LIGHT DOWN AND LEFT
  (#xC0 #x2514) ; BOX DRAWINGS LIGHT UP AND RIGHT
  (#xC1 #x2534) ; BOX DRAWINGS LIGHT UP AND HORIZONTAL
  (#xC2 #x252C) ; BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
  (#xC3 #x251C) ; BOX DRAWINGS LIGHT VERTICAL AND RIGHT
  (#xC4 #x2500) ; BOX DRAWINGS LIGHT HORIZONTAL
  (#xC5 #x253C) ; BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
  (#xC6 #x00E3) ; LATIN SMALL LETTER A WITH TILDE
  (#xC7 #x00C3) ; LATIN CAPITAL LETTER A WITH TILDE
  (#xC8 #x255A) ; BOX DRAWINGS DOUBLE UP AND RIGHT
  (#xC9 #x2554) ; BOX DRAWINGS DOUBLE DOWN AND RIGHT
  (#xCA #x2569) ; BOX DRAWINGS DOUBLE UP AND HORIZONTAL
  (#xCB #x2566) ; BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
  (#xCC #x2560) ; BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
  (#xCD #x2550) ; BOX DRAWINGS DOUBLE HORIZONTAL
  (#xCE #x256C) ; BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
  (#xCF #x00A4) ; CURRENCY SIGN
  (#xD0 #x00BA) ; MASCULINE ORDINAL INDICATOR
  (#xD1 #x00AA) ; FEMININE ORDINAL INDICATOR
  (#xD2 #x00CA) ; LATIN CAPITAL LETTER E WITH CIRCUMFLEX
  (#xD3 #x00CB) ; LATIN CAPITAL LETTER E WITH DIAERESIS
  (#xD4 #x00C8) ; LATIN CAPITAL LETTER E WITH GRAVE
  (#xD5 nil)
  (#xD6 #x00CD) ; LATIN CAPITAL LETTER I WITH ACUTE
  (#xD7 #x00CE) ; LATIN CAPITAL LETTER I WITH CIRCUMFLEX
  (#xD8 #x00CF) ; LATIN CAPITAL LETTER I WITH DIAERESIS
  (#xD9 #x2518) ; BOX DRAWINGS LIGHT UP AND LEFT
  (#xDA #x250C) ; BOX DRAWINGS LIGHT DOWN AND RIGHT
  (#xDB #x2588) ; FULL BLOCK
  (#xDC #x2584) ; LOWER HALF BLOCK
  (#xDD #x00A6) ; BROKEN BAR
  (#xDE #x00CC) ; LATIN CAPITAL LETTER I WITH GRAVE
  (#xDF #x2580) ; UPPER HALF BLOCK
  (#xE0 #x00D3) ; LATIN CAPITAL LETTER O WITH ACUTE
  (#xE1 #x00DF) ; LATIN SMALL LETTER SHARP S
  (#xE2 #x00D4) ; LATIN CAPITAL LETTER O WITH CIRCUMFLEX
  (#xE3 #x00D2) ; LATIN CAPITAL LETTER O WITH GRAVE
  (#xE4 #x00F5) ; LATIN SMALL LETTER O WITH TILDE
  (#xE5 #x00D5) ; LATIN CAPITAL LETTER O WITH TILDE
  (#xE6 #x00B5) ; MICRO SIGN
  (#xE7 nil)
  (#xE8 #x00D7) ; MULTIPLICATION SIGN
  (#xE9 #x00DA) ; LATIN CAPITAL LETTER U WITH ACUTE
  (#xEA #x00DB) ; LATIN CAPITAL LETTER U WITH CIRCUMFLEX
  (#xEB #x00D9) ; LATIN CAPITAL LETTER U WITH GRAVE
  (#xED #x00FF) ; LATIN SMALL LETTER Y WITH DIAERESIS
  (#xEE #x00AF) ; MACRON
  (#xEF #x00B4) ; ACUTE ACCENT
  (#xF0 #x00AD) ; SOFT HYPHEN
  (#xF1 #x00B1) ; PLUS-MINUS SIGN
  (#xF2 nil)
  (#xF3 #x00BE) ; VULGAR FRACTION THREE QUARTERS
  (#xF4 #x00B6) ; PILCROW SIGN
  (#xF5 #x00A7) ; SECTION SIGN
  (#xF6 #x00F7) ; DIVISION SIGN
  (#xF7 #x00B8) ; CEDILLA
  (#xF8 #x00B0) ; DEGREE SIGN
  (#xF9 #x00A8) ; DIAERESIS
  (#xFA #x00B7) ; MIDDLE DOT
  (#xFB #x00B9) ; SUPERSCRIPT ONE
  (#xFC #x00B3) ; SUPERSCRIPT THREE
  (#xFD #x00B2) ; SUPERSCRIPT TWO
  (#xFE #x25A0) ; BLACK SQUARE
  (#xFF #x00A0) ; NO-BREAK SPACE
)

(declaim (inline get-cp857-bytes))
(defun get-cp857-bytes (string pos)
  (declare (optimize speed (safety 0))
           (type simple-string string)
           (type array-range pos))
  (get-latin-bytes #'code->cp857-mapper :cp857 string pos))

(defun string->cp857 (string sstart send null-padding)
  (declare (optimize speed (safety 0))
           (type simple-string string)
           (type array-range sstart send))
  (values (string->latin% string sstart send #'get-cp857-bytes null-padding)))

(defmacro define-cp857->string* (accessor type)
  (declare (ignore type))
  (let ((name (make-od-name 'cp857->string* accessor)))
    `(progn
      (defun ,name (string sstart send array astart aend)
        (,(make-od-name 'latin->string* accessor) string sstart send array astart aend #'cp857->code-mapper)))))

(instantiate-octets-definition define-cp857->string*)

(defmacro define-cp857->string (accessor type)
  (declare (ignore type))
  `(defun ,(make-od-name 'cp857->string accessor) (array astart aend)
    (,(make-od-name 'latin->string accessor) array astart aend #'cp857->code-mapper)))

(instantiate-octets-definition define-cp857->string)

(add-external-format-funs '(:cp857 :|cp857|)
                          '(cp857->string-aref string->cp857))

(define-external-format (:cp857 :|cp857|)
    1 t
    (let ((cp857-byte (code->cp857-mapper bits)))
      (if cp857-byte
          (setf (sap-ref-8 sap tail) cp857-byte)
          (external-format-encoding-error stream bits)))
    (let ((code (cp857->code-mapper byte)))
      (if code
          (code-char code)
          (external-format-decoding-error stream byte)))) ;; TODO -- error check

(define-unibyte-mapper cp860->code-mapper code->cp860-mapper
  (#x80 #x00C7) ; LATIN CAPITAL LETTER C WITH CEDILLA
  (#x81 #x00FC) ; LATIN SMALL LETTER U WITH DIAERESIS
  (#x82 #x00E9) ; LATIN SMALL LETTER E WITH ACUTE
  (#x83 #x00E2) ; LATIN SMALL LETTER A WITH CIRCUMFLEX
  (#x84 #x00E3) ; LATIN SMALL LETTER A WITH TILDE
  (#x85 #x00E0) ; LATIN SMALL LETTER A WITH GRAVE
  (#x86 #x00C1) ; LATIN CAPITAL LETTER A WITH ACUTE
  (#x87 #x00E7) ; LATIN SMALL LETTER C WITH CEDILLA
  (#x88 #x00EA) ; LATIN SMALL LETTER E WITH CIRCUMFLEX
  (#x89 #x00CA) ; LATIN CAPITAL LETTER E WITH CIRCUMFLEX
  (#x8A #x00E8) ; LATIN SMALL LETTER E WITH GRAVE
  (#x8B #x00CD) ; LATIN CAPITAL LETTER I WITH ACUTE
  (#x8C #x00D4) ; LATIN CAPITAL LETTER O WITH CIRCUMFLEX
  (#x8D #x00EC) ; LATIN SMALL LETTER I WITH GRAVE
  (#x8E #x00C3) ; LATIN CAPITAL LETTER A WITH TILDE
  (#x8F #x00C2) ; LATIN CAPITAL LETTER A WITH CIRCUMFLEX
  (#x90 #x00C9) ; LATIN CAPITAL LETTER E WITH ACUTE
  (#x91 #x00C0) ; LATIN CAPITAL LETTER A WITH GRAVE
  (#x92 #x00C8) ; LATIN CAPITAL LETTER E WITH GRAVE
  (#x93 #x00F4) ; LATIN SMALL LETTER O WITH CIRCUMFLEX
  (#x94 #x00F5) ; LATIN SMALL LETTER O WITH TILDE
  (#x95 #x00F2) ; LATIN SMALL LETTER O WITH GRAVE
  (#x96 #x00DA) ; LATIN CAPITAL LETTER U WITH ACUTE
  (#x97 #x00F9) ; LATIN SMALL LETTER U WITH GRAVE
  (#x98 #x00CC) ; LATIN CAPITAL LETTER I WITH GRAVE
  (#x99 #x00D5) ; LATIN CAPITAL LETTER O WITH TILDE
  (#x9A #x00DC) ; LATIN CAPITAL LETTER U WITH DIAERESIS
  (#x9B #x00A2) ; CENT SIGN
  (#x9C #x00A3) ; POUND SIGN
  (#x9D #x00D9) ; LATIN CAPITAL LETTER U WITH GRAVE
  (#x9E #x20A7) ; PESETA SIGN
  (#x9F #x00D3) ; LATIN CAPITAL LETTER O WITH ACUTE
  (#xA0 #x00E1) ; LATIN SMALL LETTER A WITH ACUTE
  (#xA1 #x00ED) ; LATIN SMALL LETTER I WITH ACUTE
  (#xA2 #x00F3) ; LATIN SMALL LETTER O WITH ACUTE
  (#xA3 #x00FA) ; LATIN SMALL LETTER U WITH ACUTE
  (#xA4 #x00F1) ; LATIN SMALL LETTER N WITH TILDE
  (#xA5 #x00D1) ; LATIN CAPITAL LETTER N WITH TILDE
  (#xA6 #x00AA) ; FEMININE ORDINAL INDICATOR
  (#xA7 #x00BA) ; MASCULINE ORDINAL INDICATOR
  (#xA8 #x00BF) ; INVERTED QUESTION MARK
  (#xA9 #x00D2) ; LATIN CAPITAL LETTER O WITH GRAVE
  (#xAA #x00AC) ; NOT SIGN
  (#xAB #x00BD) ; VULGAR FRACTION ONE HALF
  (#xAC #x00BC) ; VULGAR FRACTION ONE QUARTER
  (#xAD #x00A1) ; INVERTED EXCLAMATION MARK
  (#xAE #x00AB) ; LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
  (#xAF #x00BB) ; RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
  (#xB0 #x2591) ; LIGHT SHADE
  (#xB1 #x2592) ; MEDIUM SHADE
  (#xB2 #x2593) ; DARK SHADE
  (#xB3 #x2502) ; BOX DRAWINGS LIGHT VERTICAL
  (#xB4 #x2524) ; BOX DRAWINGS LIGHT VERTICAL AND LEFT
  (#xB5 #x2561) ; BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE
  (#xB6 #x2562) ; BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE
  (#xB7 #x2556) ; BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE
  (#xB8 #x2555) ; BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE
  (#xB9 #x2563) ; BOX DRAWINGS DOUBLE VERTICAL AND LEFT
  (#xBA #x2551) ; BOX DRAWINGS DOUBLE VERTICAL
  (#xBB #x2557) ; BOX DRAWINGS DOUBLE DOWN AND LEFT
  (#xBC #x255D) ; BOX DRAWINGS DOUBLE UP AND LEFT
  (#xBD #x255C) ; BOX DRAWINGS UP DOUBLE AND LEFT SINGLE
  (#xBE #x255B) ; BOX DRAWINGS UP SINGLE AND LEFT DOUBLE
  (#xBF #x2510) ; BOX DRAWINGS LIGHT DOWN AND LEFT
  (#xC0 #x2514) ; BOX DRAWINGS LIGHT UP AND RIGHT
  (#xC1 #x2534) ; BOX DRAWINGS LIGHT UP AND HORIZONTAL
  (#xC2 #x252C) ; BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
  (#xC3 #x251C) ; BOX DRAWINGS LIGHT VERTICAL AND RIGHT
  (#xC4 #x2500) ; BOX DRAWINGS LIGHT HORIZONTAL
  (#xC5 #x253C) ; BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
  (#xC6 #x255E) ; BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE
  (#xC7 #x255F) ; BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE
  (#xC8 #x255A) ; BOX DRAWINGS DOUBLE UP AND RIGHT
  (#xC9 #x2554) ; BOX DRAWINGS DOUBLE DOWN AND RIGHT
  (#xCA #x2569) ; BOX DRAWINGS DOUBLE UP AND HORIZONTAL
  (#xCB #x2566) ; BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
  (#xCC #x2560) ; BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
  (#xCD #x2550) ; BOX DRAWINGS DOUBLE HORIZONTAL
  (#xCE #x256C) ; BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
  (#xCF #x2567) ; BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE
  (#xD0 #x2568) ; BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE
  (#xD1 #x2564) ; BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE
  (#xD2 #x2565) ; BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE
  (#xD3 #x2559) ; BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE
  (#xD4 #x2558) ; BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE
  (#xD5 #x2552) ; BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE
  (#xD6 #x2553) ; BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE
  (#xD7 #x256B) ; BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE
  (#xD8 #x256A) ; BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE
  (#xD9 #x2518) ; BOX DRAWINGS LIGHT UP AND LEFT
  (#xDA #x250C) ; BOX DRAWINGS LIGHT DOWN AND RIGHT
  (#xDB #x2588) ; FULL BLOCK
  (#xDC #x2584) ; LOWER HALF BLOCK
  (#xDD #x258C) ; LEFT HALF BLOCK
  (#xDE #x2590) ; RIGHT HALF BLOCK
  (#xDF #x2580) ; UPPER HALF BLOCK
  (#xE0 #x03B1) ; GREEK SMALL LETTER ALPHA
  (#xE1 #x00DF) ; LATIN SMALL LETTER SHARP S
  (#xE2 #x0393) ; GREEK CAPITAL LETTER GAMMA
  (#xE3 #x03C0) ; GREEK SMALL LETTER PI
  (#xE4 #x03A3) ; GREEK CAPITAL LETTER SIGMA
  (#xE5 #x03C3) ; GREEK SMALL LETTER SIGMA
  (#xE6 #x00B5) ; MICRO SIGN
  (#xE7 #x03C4) ; GREEK SMALL LETTER TAU
  (#xE8 #x03A6) ; GREEK CAPITAL LETTER PHI
  (#xE9 #x0398) ; GREEK CAPITAL LETTER THETA
  (#xEA #x03A9) ; GREEK CAPITAL LETTER OMEGA
  (#xEB #x03B4) ; GREEK SMALL LETTER DELTA
  (#xEC #x221E) ; INFINITY
  (#xED #x03C6) ; GREEK SMALL LETTER PHI
  (#xEE #x03B5) ; GREEK SMALL LETTER EPSILON
  (#xEF #x2229) ; INTERSECTION
  (#xF0 #x2261) ; IDENTICAL TO
  (#xF1 #x00B1) ; PLUS-MINUS SIGN
  (#xF2 #x2265) ; GREATER-THAN OR EQUAL TO
  (#xF3 #x2264) ; LESS-THAN OR EQUAL TO
  (#xF4 #x2320) ; TOP HALF INTEGRAL
  (#xF5 #x2321) ; BOTTOM HALF INTEGRAL
  (#xF6 #x00F7) ; DIVISION SIGN
  (#xF7 #x2248) ; ALMOST EQUAL TO
  (#xF8 #x00B0) ; DEGREE SIGN
  (#xF9 #x2219) ; BULLET OPERATOR
  (#xFA #x00B7) ; MIDDLE DOT
  (#xFB #x221A) ; SQUARE ROOT
  (#xFC #x207F) ; SUPERSCRIPT LATIN SMALL LETTER N
  (#xFD #x00B2) ; SUPERSCRIPT TWO
  (#xFE #x25A0) ; BLACK SQUARE
  (#xFF #x00A0) ; NO-BREAK SPACE
)

(declaim (inline get-cp860-bytes))
(defun get-cp860-bytes (string pos)
  (declare (optimize speed (safety 0))
           (type simple-string string)
           (type array-range pos))
  (get-latin-bytes #'code->cp860-mapper :cp860 string pos))

(defun string->cp860 (string sstart send null-padding)
  (declare (optimize speed (safety 0))
           (type simple-string string)
           (type array-range sstart send))
  (values (string->latin% string sstart send #'get-cp860-bytes null-padding)))

(defmacro define-cp860->string* (accessor type)
  (declare (ignore type))
  (let ((name (make-od-name 'cp860->string* accessor)))
    `(progn
      (defun ,name (string sstart send array astart aend)
        (,(make-od-name 'latin->string* accessor) string sstart send array astart aend #'cp860->code-mapper)))))

(instantiate-octets-definition define-cp860->string*)

(defmacro define-cp860->string (accessor type)
  (declare (ignore type))
  `(defun ,(make-od-name 'cp860->string accessor) (array astart aend)
    (,(make-od-name 'latin->string accessor) array astart aend #'cp860->code-mapper)))

(instantiate-octets-definition define-cp860->string)

(add-external-format-funs '(:cp860 :|cp860|)
                          '(cp860->string-aref string->cp860))

(define-external-format (:cp860 :|cp860|)
    1 t
    (let ((cp860-byte (code->cp860-mapper bits)))
      (if cp860-byte
          (setf (sap-ref-8 sap tail) cp860-byte)
          (external-format-encoding-error stream bits)))
    (let ((code (cp860->code-mapper byte)))
      (if code
          (code-char code)
          (external-format-decoding-error stream byte)))) ;; TODO -- error check

(define-unibyte-mapper cp861->code-mapper code->cp861-mapper
  (#x80 #x00C7) ; LATIN CAPITAL LETTER C WITH CEDILLA
  (#x81 #x00FC) ; LATIN SMALL LETTER U WITH DIAERESIS
  (#x82 #x00E9) ; LATIN SMALL LETTER E WITH ACUTE
  (#x83 #x00E2) ; LATIN SMALL LETTER A WITH CIRCUMFLEX
  (#x84 #x00E4) ; LATIN SMALL LETTER A WITH DIAERESIS
  (#x85 #x00E0) ; LATIN SMALL LETTER A WITH GRAVE
  (#x86 #x00E5) ; LATIN SMALL LETTER A WITH RING ABOVE
  (#x87 #x00E7) ; LATIN SMALL LETTER C WITH CEDILLA
  (#x88 #x00EA) ; LATIN SMALL LETTER E WITH CIRCUMFLEX
  (#x89 #x00EB) ; LATIN SMALL LETTER E WITH DIAERESIS
  (#x8A #x00E8) ; LATIN SMALL LETTER E WITH GRAVE
  (#x8B #x00D0) ; LATIN CAPITAL LETTER ETH
  (#x8C #x00F0) ; LATIN SMALL LETTER ETH
  (#x8D #x00DE) ; LATIN CAPITAL LETTER THORN
  (#x8E #x00C4) ; LATIN CAPITAL LETTER A WITH DIAERESIS
  (#x8F #x00C5) ; LATIN CAPITAL LETTER A WITH RING ABOVE
  (#x90 #x00C9) ; LATIN CAPITAL LETTER E WITH ACUTE
  (#x91 #x00E6) ; LATIN SMALL LIGATURE AE
  (#x92 #x00C6) ; LATIN CAPITAL LIGATURE AE
  (#x93 #x00F4) ; LATIN SMALL LETTER O WITH CIRCUMFLEX
  (#x94 #x00F6) ; LATIN SMALL LETTER O WITH DIAERESIS
  (#x95 #x00FE) ; LATIN SMALL LETTER THORN
  (#x96 #x00FB) ; LATIN SMALL LETTER U WITH CIRCUMFLEX
  (#x97 #x00DD) ; LATIN CAPITAL LETTER Y WITH ACUTE
  (#x98 #x00FD) ; LATIN SMALL LETTER Y WITH ACUTE
  (#x99 #x00D6) ; LATIN CAPITAL LETTER O WITH DIAERESIS
  (#x9A #x00DC) ; LATIN CAPITAL LETTER U WITH DIAERESIS
  (#x9B #x00F8) ; LATIN SMALL LETTER O WITH STROKE
  (#x9C #x00A3) ; POUND SIGN
  (#x9D #x00D8) ; LATIN CAPITAL LETTER O WITH STROKE
  (#x9E #x20A7) ; PESETA SIGN
  (#x9F #x0192) ; LATIN SMALL LETTER F WITH HOOK
  (#xA0 #x00E1) ; LATIN SMALL LETTER A WITH ACUTE
  (#xA1 #x00ED) ; LATIN SMALL LETTER I WITH ACUTE
  (#xA2 #x00F3) ; LATIN SMALL LETTER O WITH ACUTE
  (#xA3 #x00FA) ; LATIN SMALL LETTER U WITH ACUTE
  (#xA4 #x00C1) ; LATIN CAPITAL LETTER A WITH ACUTE
  (#xA5 #x00CD) ; LATIN CAPITAL LETTER I WITH ACUTE
  (#xA6 #x00D3) ; LATIN CAPITAL LETTER O WITH ACUTE
  (#xA7 #x00DA) ; LATIN CAPITAL LETTER U WITH ACUTE
  (#xA8 #x00BF) ; INVERTED QUESTION MARK
  (#xA9 #x2310) ; REVERSED NOT SIGN
  (#xAA #x00AC) ; NOT SIGN
  (#xAB #x00BD) ; VULGAR FRACTION ONE HALF
  (#xAC #x00BC) ; VULGAR FRACTION ONE QUARTER
  (#xAD #x00A1) ; INVERTED EXCLAMATION MARK
  (#xAE #x00AB) ; LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
  (#xAF #x00BB) ; RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
  (#xB0 #x2591) ; LIGHT SHADE
  (#xB1 #x2592) ; MEDIUM SHADE
  (#xB2 #x2593) ; DARK SHADE
  (#xB3 #x2502) ; BOX DRAWINGS LIGHT VERTICAL
  (#xB4 #x2524) ; BOX DRAWINGS LIGHT VERTICAL AND LEFT
  (#xB5 #x2561) ; BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE
  (#xB6 #x2562) ; BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE
  (#xB7 #x2556) ; BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE
  (#xB8 #x2555) ; BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE
  (#xB9 #x2563) ; BOX DRAWINGS DOUBLE VERTICAL AND LEFT
  (#xBA #x2551) ; BOX DRAWINGS DOUBLE VERTICAL
  (#xBB #x2557) ; BOX DRAWINGS DOUBLE DOWN AND LEFT
  (#xBC #x255D) ; BOX DRAWINGS DOUBLE UP AND LEFT
  (#xBD #x255C) ; BOX DRAWINGS UP DOUBLE AND LEFT SINGLE
  (#xBE #x255B) ; BOX DRAWINGS UP SINGLE AND LEFT DOUBLE
  (#xBF #x2510) ; BOX DRAWINGS LIGHT DOWN AND LEFT
  (#xC0 #x2514) ; BOX DRAWINGS LIGHT UP AND RIGHT
  (#xC1 #x2534) ; BOX DRAWINGS LIGHT UP AND HORIZONTAL
  (#xC2 #x252C) ; BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
  (#xC3 #x251C) ; BOX DRAWINGS LIGHT VERTICAL AND RIGHT
  (#xC4 #x2500) ; BOX DRAWINGS LIGHT HORIZONTAL
  (#xC5 #x253C) ; BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
  (#xC6 #x255E) ; BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE
  (#xC7 #x255F) ; BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE
  (#xC8 #x255A) ; BOX DRAWINGS DOUBLE UP AND RIGHT
  (#xC9 #x2554) ; BOX DRAWINGS DOUBLE DOWN AND RIGHT
  (#xCA #x2569) ; BOX DRAWINGS DOUBLE UP AND HORIZONTAL
  (#xCB #x2566) ; BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
  (#xCC #x2560) ; BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
  (#xCD #x2550) ; BOX DRAWINGS DOUBLE HORIZONTAL
  (#xCE #x256C) ; BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
  (#xCF #x2567) ; BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE
  (#xD0 #x2568) ; BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE
  (#xD1 #x2564) ; BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE
  (#xD2 #x2565) ; BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE
  (#xD3 #x2559) ; BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE
  (#xD4 #x2558) ; BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE
  (#xD5 #x2552) ; BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE
  (#xD6 #x2553) ; BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE
  (#xD7 #x256B) ; BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE
  (#xD8 #x256A) ; BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE
  (#xD9 #x2518) ; BOX DRAWINGS LIGHT UP AND LEFT
  (#xDA #x250C) ; BOX DRAWINGS LIGHT DOWN AND RIGHT
  (#xDB #x2588) ; FULL BLOCK
  (#xDC #x2584) ; LOWER HALF BLOCK
  (#xDD #x258C) ; LEFT HALF BLOCK
  (#xDE #x2590) ; RIGHT HALF BLOCK
  (#xDF #x2580) ; UPPER HALF BLOCK
  (#xE0 #x03B1) ; GREEK SMALL LETTER ALPHA
  (#xE1 #x00DF) ; LATIN SMALL LETTER SHARP S
  (#xE2 #x0393) ; GREEK CAPITAL LETTER GAMMA
  (#xE3 #x03C0) ; GREEK SMALL LETTER PI
  (#xE4 #x03A3) ; GREEK CAPITAL LETTER SIGMA
  (#xE5 #x03C3) ; GREEK SMALL LETTER SIGMA
  (#xE6 #x00B5) ; MICRO SIGN
  (#xE7 #x03C4) ; GREEK SMALL LETTER TAU
  (#xE8 #x03A6) ; GREEK CAPITAL LETTER PHI
  (#xE9 #x0398) ; GREEK CAPITAL LETTER THETA
  (#xEA #x03A9) ; GREEK CAPITAL LETTER OMEGA
  (#xEB #x03B4) ; GREEK SMALL LETTER DELTA
  (#xEC #x221E) ; INFINITY
  (#xED #x03C6) ; GREEK SMALL LETTER PHI
  (#xEE #x03B5) ; GREEK SMALL LETTER EPSILON
  (#xEF #x2229) ; INTERSECTION
  (#xF0 #x2261) ; IDENTICAL TO
  (#xF1 #x00B1) ; PLUS-MINUS SIGN
  (#xF2 #x2265) ; GREATER-THAN OR EQUAL TO
  (#xF3 #x2264) ; LESS-THAN OR EQUAL TO
  (#xF4 #x2320) ; TOP HALF INTEGRAL
  (#xF5 #x2321) ; BOTTOM HALF INTEGRAL
  (#xF6 #x00F7) ; DIVISION SIGN
  (#xF7 #x2248) ; ALMOST EQUAL TO
  (#xF8 #x00B0) ; DEGREE SIGN
  (#xF9 #x2219) ; BULLET OPERATOR
  (#xFA #x00B7) ; MIDDLE DOT
  (#xFB #x221A) ; SQUARE ROOT
  (#xFC #x207F) ; SUPERSCRIPT LATIN SMALL LETTER N
  (#xFD #x00B2) ; SUPERSCRIPT TWO
  (#xFE #x25A0) ; BLACK SQUARE
  (#xFF #x00A0) ; NO-BREAK SPACE
)

(declaim (inline get-cp861-bytes))
(defun get-cp861-bytes (string pos)
  (declare (optimize speed (safety 0))
           (type simple-string string)
           (type array-range pos))
  (get-latin-bytes #'code->cp861-mapper :cp861 string pos))

(defun string->cp861 (string sstart send null-padding)
  (declare (optimize speed (safety 0))
           (type simple-string string)
           (type array-range sstart send))
  (values (string->latin% string sstart send #'get-cp861-bytes null-padding)))

(defmacro define-cp861->string* (accessor type)
  (declare (ignore type))
  (let ((name (make-od-name 'cp861->string* accessor)))
    `(progn
      (defun ,name (string sstart send array astart aend)
        (,(make-od-name 'latin->string* accessor) string sstart send array astart aend #'cp861->code-mapper)))))

(instantiate-octets-definition define-cp861->string*)

(defmacro define-cp861->string (accessor type)
  (declare (ignore type))
  `(defun ,(make-od-name 'cp861->string accessor) (array astart aend)
    (,(make-od-name 'latin->string accessor) array astart aend #'cp861->code-mapper)))

(instantiate-octets-definition define-cp861->string)

(add-external-format-funs '(:cp861 :|cp861|)
                          '(cp861->string-aref string->cp861))

(define-external-format (:cp861 :|cp861|)
    1 t
    (let ((cp861-byte (code->cp861-mapper bits)))
      (if cp861-byte
          (setf (sap-ref-8 sap tail) cp861-byte)
          (external-format-encoding-error stream bits)))
    (let ((code (cp861->code-mapper byte)))
      (if code
          (code-char code)
          (external-format-decoding-error stream byte)))) ;; TODO -- error check

(define-unibyte-mapper cp862->code-mapper code->cp862-mapper
  (#x80 #x05D0) ; HEBREW LETTER ALEF
  (#x81 #x05D1) ; HEBREW LETTER BET
  (#x82 #x05D2) ; HEBREW LETTER GIMEL
  (#x83 #x05D3) ; HEBREW LETTER DALET
  (#x84 #x05D4) ; HEBREW LETTER HE
  (#x85 #x05D5) ; HEBREW LETTER VAV
  (#x86 #x05D6) ; HEBREW LETTER ZAYIN
  (#x87 #x05D7) ; HEBREW LETTER HET
  (#x88 #x05D8) ; HEBREW LETTER TET
  (#x89 #x05D9) ; HEBREW LETTER YOD
  (#x8A #x05DA) ; HEBREW LETTER FINAL KAF
  (#x8B #x05DB) ; HEBREW LETTER KAF
  (#x8C #x05DC) ; HEBREW LETTER LAMED
  (#x8D #x05DD) ; HEBREW LETTER FINAL MEM
  (#x8E #x05DE) ; HEBREW LETTER MEM
  (#x8F #x05DF) ; HEBREW LETTER FINAL NUN
  (#x90 #x05E0) ; HEBREW LETTER NUN
  (#x91 #x05E1) ; HEBREW LETTER SAMEKH
  (#x92 #x05E2) ; HEBREW LETTER AYIN
  (#x93 #x05E3) ; HEBREW LETTER FINAL PE
  (#x94 #x05E4) ; HEBREW LETTER PE
  (#x95 #x05E5) ; HEBREW LETTER FINAL TSADI
  (#x96 #x05E6) ; HEBREW LETTER TSADI
  (#x97 #x05E7) ; HEBREW LETTER QOF
  (#x98 #x05E8) ; HEBREW LETTER RESH
  (#x99 #x05E9) ; HEBREW LETTER SHIN
  (#x9A #x05EA) ; HEBREW LETTER TAV
  (#x9B #x00A2) ; CENT SIGN
  (#x9C #x00A3) ; POUND SIGN
  (#x9D #x00A5) ; YEN SIGN
  (#x9E #x20A7) ; PESETA SIGN
  (#x9F #x0192) ; LATIN SMALL LETTER F WITH HOOK
  (#xA0 #x00E1) ; LATIN SMALL LETTER A WITH ACUTE
  (#xA1 #x00ED) ; LATIN SMALL LETTER I WITH ACUTE
  (#xA2 #x00F3) ; LATIN SMALL LETTER O WITH ACUTE
  (#xA3 #x00FA) ; LATIN SMALL LETTER U WITH ACUTE
  (#xA4 #x00F1) ; LATIN SMALL LETTER N WITH TILDE
  (#xA5 #x00D1) ; LATIN CAPITAL LETTER N WITH TILDE
  (#xA6 #x00AA) ; FEMININE ORDINAL INDICATOR
  (#xA7 #x00BA) ; MASCULINE ORDINAL INDICATOR
  (#xA8 #x00BF) ; INVERTED QUESTION MARK
  (#xA9 #x2310) ; REVERSED NOT SIGN
  (#xAA #x00AC) ; NOT SIGN
  (#xAB #x00BD) ; VULGAR FRACTION ONE HALF
  (#xAC #x00BC) ; VULGAR FRACTION ONE QUARTER
  (#xAD #x00A1) ; INVERTED EXCLAMATION MARK
  (#xAE #x00AB) ; LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
  (#xAF #x00BB) ; RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
  (#xB0 #x2591) ; LIGHT SHADE
  (#xB1 #x2592) ; MEDIUM SHADE
  (#xB2 #x2593) ; DARK SHADE
  (#xB3 #x2502) ; BOX DRAWINGS LIGHT VERTICAL
  (#xB4 #x2524) ; BOX DRAWINGS LIGHT VERTICAL AND LEFT
  (#xB5 #x2561) ; BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE
  (#xB6 #x2562) ; BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE
  (#xB7 #x2556) ; BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE
  (#xB8 #x2555) ; BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE
  (#xB9 #x2563) ; BOX DRAWINGS DOUBLE VERTICAL AND LEFT
  (#xBA #x2551) ; BOX DRAWINGS DOUBLE VERTICAL
  (#xBB #x2557) ; BOX DRAWINGS DOUBLE DOWN AND LEFT
  (#xBC #x255D) ; BOX DRAWINGS DOUBLE UP AND LEFT
  (#xBD #x255C) ; BOX DRAWINGS UP DOUBLE AND LEFT SINGLE
  (#xBE #x255B) ; BOX DRAWINGS UP SINGLE AND LEFT DOUBLE
  (#xBF #x2510) ; BOX DRAWINGS LIGHT DOWN AND LEFT
  (#xC0 #x2514) ; BOX DRAWINGS LIGHT UP AND RIGHT
  (#xC1 #x2534) ; BOX DRAWINGS LIGHT UP AND HORIZONTAL
  (#xC2 #x252C) ; BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
  (#xC3 #x251C) ; BOX DRAWINGS LIGHT VERTICAL AND RIGHT
  (#xC4 #x2500) ; BOX DRAWINGS LIGHT HORIZONTAL
  (#xC5 #x253C) ; BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
  (#xC6 #x255E) ; BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE
  (#xC7 #x255F) ; BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE
  (#xC8 #x255A) ; BOX DRAWINGS DOUBLE UP AND RIGHT
  (#xC9 #x2554) ; BOX DRAWINGS DOUBLE DOWN AND RIGHT
  (#xCA #x2569) ; BOX DRAWINGS DOUBLE UP AND HORIZONTAL
  (#xCB #x2566) ; BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
  (#xCC #x2560) ; BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
  (#xCD #x2550) ; BOX DRAWINGS DOUBLE HORIZONTAL
  (#xCE #x256C) ; BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
  (#xCF #x2567) ; BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE
  (#xD0 #x2568) ; BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE
  (#xD1 #x2564) ; BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE
  (#xD2 #x2565) ; BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE
  (#xD3 #x2559) ; BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE
  (#xD4 #x2558) ; BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE
  (#xD5 #x2552) ; BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE
  (#xD6 #x2553) ; BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE
  (#xD7 #x256B) ; BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE
  (#xD8 #x256A) ; BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE
  (#xD9 #x2518) ; BOX DRAWINGS LIGHT UP AND LEFT
  (#xDA #x250C) ; BOX DRAWINGS LIGHT DOWN AND RIGHT
  (#xDB #x2588) ; FULL BLOCK
  (#xDC #x2584) ; LOWER HALF BLOCK
  (#xDD #x258C) ; LEFT HALF BLOCK
  (#xDE #x2590) ; RIGHT HALF BLOCK
  (#xDF #x2580) ; UPPER HALF BLOCK
  (#xE0 #x03B1) ; GREEK SMALL LETTER ALPHA
  (#xE1 #x00DF) ; LATIN SMALL LETTER SHARP S (GERMAN)
  (#xE2 #x0393) ; GREEK CAPITAL LETTER GAMMA
  (#xE3 #x03C0) ; GREEK SMALL LETTER PI
  (#xE4 #x03A3) ; GREEK CAPITAL LETTER SIGMA
  (#xE5 #x03C3) ; GREEK SMALL LETTER SIGMA
  (#xE6 #x00B5) ; MICRO SIGN
  (#xE7 #x03C4) ; GREEK SMALL LETTER TAU
  (#xE8 #x03A6) ; GREEK CAPITAL LETTER PHI
  (#xE9 #x0398) ; GREEK CAPITAL LETTER THETA
  (#xEA #x03A9) ; GREEK CAPITAL LETTER OMEGA
  (#xEB #x03B4) ; GREEK SMALL LETTER DELTA
  (#xEC #x221E) ; INFINITY
  (#xED #x03C6) ; GREEK SMALL LETTER PHI
  (#xEE #x03B5) ; GREEK SMALL LETTER EPSILON
  (#xEF #x2229) ; INTERSECTION
  (#xF0 #x2261) ; IDENTICAL TO
  (#xF1 #x00B1) ; PLUS-MINUS SIGN
  (#xF2 #x2265) ; GREATER-THAN OR EQUAL TO
  (#xF3 #x2264) ; LESS-THAN OR EQUAL TO
  (#xF4 #x2320) ; TOP HALF INTEGRAL
  (#xF5 #x2321) ; BOTTOM HALF INTEGRAL
  (#xF6 #x00F7) ; DIVISION SIGN
  (#xF7 #x2248) ; ALMOST EQUAL TO
  (#xF8 #x00B0) ; DEGREE SIGN
  (#xF9 #x2219) ; BULLET OPERATOR
  (#xFA #x00B7) ; MIDDLE DOT
  (#xFB #x221A) ; SQUARE ROOT
  (#xFC #x207F) ; SUPERSCRIPT LATIN SMALL LETTER N
  (#xFD #x00B2) ; SUPERSCRIPT TWO
  (#xFE #x25A0) ; BLACK SQUARE
  (#xFF #x00A0) ; NO-BREAK SPACE
)

(declaim (inline get-cp862-bytes))
(defun get-cp862-bytes (string pos)
  (declare (optimize speed (safety 0))
           (type simple-string string)
           (type array-range pos))
  (get-latin-bytes #'code->cp862-mapper :cp862 string pos))

(defun string->cp862 (string sstart send null-padding)
  (declare (optimize speed (safety 0))
           (type simple-string string)
           (type array-range sstart send))
  (values (string->latin% string sstart send #'get-cp862-bytes null-padding)))

(defmacro define-cp862->string* (accessor type)
  (declare (ignore type))
  (let ((name (make-od-name 'cp862->string* accessor)))
    `(progn
      (defun ,name (string sstart send array astart aend)
        (,(make-od-name 'latin->string* accessor) string sstart send array astart aend #'cp862->code-mapper)))))

(instantiate-octets-definition define-cp862->string*)

(defmacro define-cp862->string (accessor type)
  (declare (ignore type))
  `(defun ,(make-od-name 'cp862->string accessor) (array astart aend)
    (,(make-od-name 'latin->string accessor) array astart aend #'cp862->code-mapper)))

(instantiate-octets-definition define-cp862->string)

(add-external-format-funs '(:cp862 :|cp862|)
                          '(cp862->string-aref string->cp862))

(define-external-format (:cp862 :|cp862|)
    1 t
    (let ((cp862-byte (code->cp862-mapper bits)))
      (if cp862-byte
          (setf (sap-ref-8 sap tail) cp862-byte)
          (external-format-encoding-error stream bits)))
    (let ((code (cp862->code-mapper byte)))
      (if code
          (code-char code)
          (external-format-decoding-error stream byte)))) ;; TODO -- error check

(define-unibyte-mapper cp863->code-mapper code->cp863-mapper
  (#x80 #x00C7) ; LATIN CAPITAL LETTER C WITH CEDILLA
  (#x81 #x00FC) ; LATIN SMALL LETTER U WITH DIAERESIS
  (#x82 #x00E9) ; LATIN SMALL LETTER E WITH ACUTE
  (#x83 #x00E2) ; LATIN SMALL LETTER A WITH CIRCUMFLEX
  (#x84 #x00C2) ; LATIN CAPITAL LETTER A WITH CIRCUMFLEX
  (#x85 #x00E0) ; LATIN SMALL LETTER A WITH GRAVE
  (#x86 #x00B6) ; PILCROW SIGN
  (#x87 #x00E7) ; LATIN SMALL LETTER C WITH CEDILLA
  (#x88 #x00EA) ; LATIN SMALL LETTER E WITH CIRCUMFLEX
  (#x89 #x00EB) ; LATIN SMALL LETTER E WITH DIAERESIS
  (#x8A #x00E8) ; LATIN SMALL LETTER E WITH GRAVE
  (#x8B #x00EF) ; LATIN SMALL LETTER I WITH DIAERESIS
  (#x8C #x00EE) ; LATIN SMALL LETTER I WITH CIRCUMFLEX
  (#x8D #x2017) ; DOUBLE LOW LINE
  (#x8E #x00C0) ; LATIN CAPITAL LETTER A WITH GRAVE
  (#x8F #x00A7) ; SECTION SIGN
  (#x90 #x00C9) ; LATIN CAPITAL LETTER E WITH ACUTE
  (#x91 #x00C8) ; LATIN CAPITAL LETTER E WITH GRAVE
  (#x92 #x00CA) ; LATIN CAPITAL LETTER E WITH CIRCUMFLEX
  (#x93 #x00F4) ; LATIN SMALL LETTER O WITH CIRCUMFLEX
  (#x94 #x00CB) ; LATIN CAPITAL LETTER E WITH DIAERESIS
  (#x95 #x00CF) ; LATIN CAPITAL LETTER I WITH DIAERESIS
  (#x96 #x00FB) ; LATIN SMALL LETTER U WITH CIRCUMFLEX
  (#x97 #x00F9) ; LATIN SMALL LETTER U WITH GRAVE
  (#x98 #x00A4) ; CURRENCY SIGN
  (#x99 #x00D4) ; LATIN CAPITAL LETTER O WITH CIRCUMFLEX
  (#x9A #x00DC) ; LATIN CAPITAL LETTER U WITH DIAERESIS
  (#x9B #x00A2) ; CENT SIGN
  (#x9C #x00A3) ; POUND SIGN
  (#x9D #x00D9) ; LATIN CAPITAL LETTER U WITH GRAVE
  (#x9E #x00DB) ; LATIN CAPITAL LETTER U WITH CIRCUMFLEX
  (#x9F #x0192) ; LATIN SMALL LETTER F WITH HOOK
  (#xA0 #x00A6) ; BROKEN BAR
  (#xA1 #x00B4) ; ACUTE ACCENT
  (#xA2 #x00F3) ; LATIN SMALL LETTER O WITH ACUTE
  (#xA3 #x00FA) ; LATIN SMALL LETTER U WITH ACUTE
  (#xA4 #x00A8) ; DIAERESIS
  (#xA5 #x00B8) ; CEDILLA
  (#xA6 #x00B3) ; SUPERSCRIPT THREE
  (#xA7 #x00AF) ; MACRON
  (#xA8 #x00CE) ; LATIN CAPITAL LETTER I WITH CIRCUMFLEX
  (#xA9 #x2310) ; REVERSED NOT SIGN
  (#xAA #x00AC) ; NOT SIGN
  (#xAB #x00BD) ; VULGAR FRACTION ONE HALF
  (#xAC #x00BC) ; VULGAR FRACTION ONE QUARTER
  (#xAD #x00BE) ; VULGAR FRACTION THREE QUARTERS
  (#xAE #x00AB) ; LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
  (#xAF #x00BB) ; RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
  (#xB0 #x2591) ; LIGHT SHADE
  (#xB1 #x2592) ; MEDIUM SHADE
  (#xB2 #x2593) ; DARK SHADE
  (#xB3 #x2502) ; BOX DRAWINGS LIGHT VERTICAL
  (#xB4 #x2524) ; BOX DRAWINGS LIGHT VERTICAL AND LEFT
  (#xB5 #x2561) ; BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE
  (#xB6 #x2562) ; BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE
  (#xB7 #x2556) ; BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE
  (#xB8 #x2555) ; BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE
  (#xB9 #x2563) ; BOX DRAWINGS DOUBLE VERTICAL AND LEFT
  (#xBA #x2551) ; BOX DRAWINGS DOUBLE VERTICAL
  (#xBB #x2557) ; BOX DRAWINGS DOUBLE DOWN AND LEFT
  (#xBC #x255D) ; BOX DRAWINGS DOUBLE UP AND LEFT
  (#xBD #x255C) ; BOX DRAWINGS UP DOUBLE AND LEFT SINGLE
  (#xBE #x255B) ; BOX DRAWINGS UP SINGLE AND LEFT DOUBLE
  (#xBF #x2510) ; BOX DRAWINGS LIGHT DOWN AND LEFT
  (#xC0 #x2514) ; BOX DRAWINGS LIGHT UP AND RIGHT
  (#xC1 #x2534) ; BOX DRAWINGS LIGHT UP AND HORIZONTAL
  (#xC2 #x252C) ; BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
  (#xC3 #x251C) ; BOX DRAWINGS LIGHT VERTICAL AND RIGHT
  (#xC4 #x2500) ; BOX DRAWINGS LIGHT HORIZONTAL
  (#xC5 #x253C) ; BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
  (#xC6 #x255E) ; BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE
  (#xC7 #x255F) ; BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE
  (#xC8 #x255A) ; BOX DRAWINGS DOUBLE UP AND RIGHT
  (#xC9 #x2554) ; BOX DRAWINGS DOUBLE DOWN AND RIGHT
  (#xCA #x2569) ; BOX DRAWINGS DOUBLE UP AND HORIZONTAL
  (#xCB #x2566) ; BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
  (#xCC #x2560) ; BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
  (#xCD #x2550) ; BOX DRAWINGS DOUBLE HORIZONTAL
  (#xCE #x256C) ; BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
  (#xCF #x2567) ; BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE
  (#xD0 #x2568) ; BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE
  (#xD1 #x2564) ; BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE
  (#xD2 #x2565) ; BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE
  (#xD3 #x2559) ; BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE
  (#xD4 #x2558) ; BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE
  (#xD5 #x2552) ; BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE
  (#xD6 #x2553) ; BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE
  (#xD7 #x256B) ; BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE
  (#xD8 #x256A) ; BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE
  (#xD9 #x2518) ; BOX DRAWINGS LIGHT UP AND LEFT
  (#xDA #x250C) ; BOX DRAWINGS LIGHT DOWN AND RIGHT
  (#xDB #x2588) ; FULL BLOCK
  (#xDC #x2584) ; LOWER HALF BLOCK
  (#xDD #x258C) ; LEFT HALF BLOCK
  (#xDE #x2590) ; RIGHT HALF BLOCK
  (#xDF #x2580) ; UPPER HALF BLOCK
  (#xE0 #x03B1) ; GREEK SMALL LETTER ALPHA
  (#xE1 #x00DF) ; LATIN SMALL LETTER SHARP S
  (#xE2 #x0393) ; GREEK CAPITAL LETTER GAMMA
  (#xE3 #x03C0) ; GREEK SMALL LETTER PI
  (#xE4 #x03A3) ; GREEK CAPITAL LETTER SIGMA
  (#xE5 #x03C3) ; GREEK SMALL LETTER SIGMA
  (#xE6 #x00B5) ; MICRO SIGN
  (#xE7 #x03C4) ; GREEK SMALL LETTER TAU
  (#xE8 #x03A6) ; GREEK CAPITAL LETTER PHI
  (#xE9 #x0398) ; GREEK CAPITAL LETTER THETA
  (#xEA #x03A9) ; GREEK CAPITAL LETTER OMEGA
  (#xEB #x03B4) ; GREEK SMALL LETTER DELTA
  (#xEC #x221E) ; INFINITY
  (#xED #x03C6) ; GREEK SMALL LETTER PHI
  (#xEE #x03B5) ; GREEK SMALL LETTER EPSILON
  (#xEF #x2229) ; INTERSECTION
  (#xF0 #x2261) ; IDENTICAL TO
  (#xF1 #x00B1) ; PLUS-MINUS SIGN
  (#xF2 #x2265) ; GREATER-THAN OR EQUAL TO
  (#xF3 #x2264) ; LESS-THAN OR EQUAL TO
  (#xF4 #x2320) ; TOP HALF INTEGRAL
  (#xF5 #x2321) ; BOTTOM HALF INTEGRAL
  (#xF6 #x00F7) ; DIVISION SIGN
  (#xF7 #x2248) ; ALMOST EQUAL TO
  (#xF8 #x00B0) ; DEGREE SIGN
  (#xF9 #x2219) ; BULLET OPERATOR
  (#xFA #x00B7) ; MIDDLE DOT
  (#xFB #x221A) ; SQUARE ROOT
  (#xFC #x207F) ; SUPERSCRIPT LATIN SMALL LETTER N
  (#xFD #x00B2) ; SUPERSCRIPT TWO
  (#xFE #x25A0) ; BLACK SQUARE
  (#xFF #x00A0) ; NO-BREAK SPACE
)

(declaim (inline get-cp863-bytes))
(defun get-cp863-bytes (string pos)
  (declare (optimize speed (safety 0))
           (type simple-string string)
           (type array-range pos))
  (get-latin-bytes #'code->cp863-mapper :cp863 string pos))

(defun string->cp863 (string sstart send null-padding)
  (declare (optimize speed (safety 0))
           (type simple-string string)
           (type array-range sstart send))
  (values (string->latin% string sstart send #'get-cp863-bytes null-padding)))

(defmacro define-cp863->string* (accessor type)
  (declare (ignore type))
  (let ((name (make-od-name 'cp863->string* accessor)))
    `(progn
      (defun ,name (string sstart send array astart aend)
        (,(make-od-name 'latin->string* accessor) string sstart send array astart aend #'cp863->code-mapper)))))

(instantiate-octets-definition define-cp863->string*)

(defmacro define-cp863->string (accessor type)
  (declare (ignore type))
  `(defun ,(make-od-name 'cp863->string accessor) (array astart aend)
    (,(make-od-name 'latin->string accessor) array astart aend #'cp863->code-mapper)))

(instantiate-octets-definition define-cp863->string)

(add-external-format-funs '(:cp863 :|cp863|)
                          '(cp863->string-aref string->cp863))

(define-external-format (:cp863 :|cp863|)
    1 t
    (let ((cp863-byte (code->cp863-mapper bits)))
      (if cp863-byte
          (setf (sap-ref-8 sap tail) cp863-byte)
          (external-format-encoding-error stream bits)))
    (let ((code (cp863->code-mapper byte)))
      (if code
          (code-char code)
          (external-format-decoding-error stream byte)))) ;; TODO -- error check

(define-unibyte-mapper cp864->code-mapper code->cp864-mapper
  (#x80 #x00B0) ; DEGREE SIGN
  (#x81 #x00B7) ; MIDDLE DOT
  (#x82 #x2219) ; BULLET OPERATOR
  (#x83 #x221A) ; SQUARE ROOT
  (#x84 #x2592) ; MEDIUM SHADE
  (#x85 #x2500) ; FORMS LIGHT HORIZONTAL
  (#x86 #x2502) ; FORMS LIGHT VERTICAL
  (#x87 #x253C) ; FORMS LIGHT VERTICAL AND HORIZONTAL
  (#x88 #x2524) ; FORMS LIGHT VERTICAL AND LEFT
  (#x89 #x252C) ; FORMS LIGHT DOWN AND HORIZONTAL
  (#x8A #x251C) ; FORMS LIGHT VERTICAL AND RIGHT
  (#x8B #x2534) ; FORMS LIGHT UP AND HORIZONTAL
  (#x8C #x2510) ; FORMS LIGHT DOWN AND LEFT
  (#x8D #x250C) ; FORMS LIGHT DOWN AND RIGHT
  (#x8E #x2514) ; FORMS LIGHT UP AND RIGHT
  (#x8F #x2518) ; FORMS LIGHT UP AND LEFT
  (#x90 #x03B2) ; GREEK SMALL BETA
  (#x91 #x221E) ; INFINITY
  (#x92 #x03C6) ; GREEK SMALL PHI
  (#x93 #x00B1) ; PLUS-OR-MINUS SIGN
  (#x94 #x00BD) ; FRACTION 1/2
  (#x95 #x00BC) ; FRACTION 1/4
  (#x96 #x2248) ; ALMOST EQUAL TO
  (#x97 #x00AB) ; LEFT POINTING GUILLEMET
  (#x98 #x00BB) ; RIGHT POINTING GUILLEMET
  (#x99 #xFEF7) ; ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE ISOLATED FORM
  (#x9A #xFEF8) ; ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE FINAL FORM
  (#x9B nil)
  (#x9C nil)
  (#x9D #xFEFB) ; ARABIC LIGATURE LAM WITH ALEF ISOLATED FORM
  (#x9E #xFEFC) ; ARABIC LIGATURE LAM WITH ALEF FINAL FORM
  (#x9F nil)
  (#xA1 #x00AD) ; SOFT HYPHEN
  (#xA2 #xFE82) ; ARABIC LETTER ALEF WITH MADDA ABOVE FINAL FORM
  (#xA5 #xFE84) ; ARABIC LETTER ALEF WITH HAMZA ABOVE FINAL FORM
  (#xA6 nil)
  (#xA7 nil)
  (#xA8 #xFE8E) ; ARABIC LETTER ALEF FINAL FORM
  (#xA9 #xFE8F) ; ARABIC LETTER BEH ISOLATED FORM
  (#xAA #xFE95) ; ARABIC LETTER TEH ISOLATED FORM
  (#xAB #xFE99) ; ARABIC LETTER THEH ISOLATED FORM
  (#xAC #x060C) ; ARABIC COMMA
  (#xAD #xFE9D) ; ARABIC LETTER JEEM ISOLATED FORM
  (#xAE #xFEA1) ; ARABIC LETTER HAH ISOLATED FORM
  (#xAF #xFEA5) ; ARABIC LETTER KHAH ISOLATED FORM
  (#xB0 #x0660) ; ARABIC-INDIC DIGIT ZERO
  (#xB1 #x0661) ; ARABIC-INDIC DIGIT ONE
  (#xB2 #x0662) ; ARABIC-INDIC DIGIT TWO
  (#xB3 #x0663) ; ARABIC-INDIC DIGIT THREE
  (#xB4 #x0664) ; ARABIC-INDIC DIGIT FOUR
  (#xB5 #x0665) ; ARABIC-INDIC DIGIT FIVE
  (#xB6 #x0666) ; ARABIC-INDIC DIGIT SIX
  (#xB7 #x0667) ; ARABIC-INDIC DIGIT SEVEN
  (#xB8 #x0668) ; ARABIC-INDIC DIGIT EIGHT
  (#xB9 #x0669) ; ARABIC-INDIC DIGIT NINE
  (#xBA #xFED1) ; ARABIC LETTER FEH ISOLATED FORM
  (#xBB #x061B) ; ARABIC SEMICOLON
  (#xBC #xFEB1) ; ARABIC LETTER SEEN ISOLATED FORM
  (#xBD #xFEB5) ; ARABIC LETTER SHEEN ISOLATED FORM
  (#xBE #xFEB9) ; ARABIC LETTER SAD ISOLATED FORM
  (#xBF #x061F) ; ARABIC QUESTION MARK
  (#xC0 #x00A2) ; CENT SIGN
  (#xC1 #xFE80) ; ARABIC LETTER HAMZA ISOLATED FORM
  (#xC2 #xFE81) ; ARABIC LETTER ALEF WITH MADDA ABOVE ISOLATED FORM
  (#xC3 #xFE83) ; ARABIC LETTER ALEF WITH HAMZA ABOVE ISOLATED FORM
  (#xC4 #xFE85) ; ARABIC LETTER WAW WITH HAMZA ABOVE ISOLATED FORM
  (#xC5 #xFECA) ; ARABIC LETTER AIN FINAL FORM
  (#xC6 #xFE8B) ; ARABIC LETTER YEH WITH HAMZA ABOVE INITIAL FORM
  (#xC7 #xFE8D) ; ARABIC LETTER ALEF ISOLATED FORM
  (#xC8 #xFE91) ; ARABIC LETTER BEH INITIAL FORM
  (#xC9 #xFE93) ; ARABIC LETTER TEH MARBUTA ISOLATED FORM
  (#xCA #xFE97) ; ARABIC LETTER TEH INITIAL FORM
  (#xCB #xFE9B) ; ARABIC LETTER THEH INITIAL FORM
  (#xCC #xFE9F) ; ARABIC LETTER JEEM INITIAL FORM
  (#xCD #xFEA3) ; ARABIC LETTER HAH INITIAL FORM
  (#xCE #xFEA7) ; ARABIC LETTER KHAH INITIAL FORM
  (#xCF #xFEA9) ; ARABIC LETTER DAL ISOLATED FORM
  (#xD0 #xFEAB) ; ARABIC LETTER THAL ISOLATED FORM
  (#xD1 #xFEAD) ; ARABIC LETTER REH ISOLATED FORM
  (#xD2 #xFEAF) ; ARABIC LETTER ZAIN ISOLATED FORM
  (#xD3 #xFEB3) ; ARABIC LETTER SEEN INITIAL FORM
  (#xD4 #xFEB7) ; ARABIC LETTER SHEEN INITIAL FORM
  (#xD5 #xFEBB) ; ARABIC LETTER SAD INITIAL FORM
  (#xD6 #xFEBF) ; ARABIC LETTER DAD INITIAL FORM
  (#xD7 #xFEC1) ; ARABIC LETTER TAH ISOLATED FORM
  (#xD8 #xFEC5) ; ARABIC LETTER ZAH ISOLATED FORM
  (#xD9 #xFECB) ; ARABIC LETTER AIN INITIAL FORM
  (#xDA #xFECF) ; ARABIC LETTER GHAIN INITIAL FORM
  (#xDB #x00A6) ; BROKEN VERTICAL BAR
  (#xDC #x00AC) ; NOT SIGN
  (#xDD #x00F7) ; DIVISION SIGN
  (#xDE #x00D7) ; MULTIPLICATION SIGN
  (#xDF #xFEC9) ; ARABIC LETTER AIN ISOLATED FORM
  (#xE0 #x0640) ; ARABIC TATWEEL
  (#xE1 #xFED3) ; ARABIC LETTER FEH INITIAL FORM
  (#xE2 #xFED7) ; ARABIC LETTER QAF INITIAL FORM
  (#xE3 #xFEDB) ; ARABIC LETTER KAF INITIAL FORM
  (#xE4 #xFEDF) ; ARABIC LETTER LAM INITIAL FORM
  (#xE5 #xFEE3) ; ARABIC LETTER MEEM INITIAL FORM
  (#xE6 #xFEE7) ; ARABIC LETTER NOON INITIAL FORM
  (#xE7 #xFEEB) ; ARABIC LETTER HEH INITIAL FORM
  (#xE8 #xFEED) ; ARABIC LETTER WAW ISOLATED FORM
  (#xE9 #xFEEF) ; ARABIC LETTER ALEF MAKSURA ISOLATED FORM
  (#xEA #xFEF3) ; ARABIC LETTER YEH INITIAL FORM
  (#xEB #xFEBD) ; ARABIC LETTER DAD ISOLATED FORM
  (#xEC #xFECC) ; ARABIC LETTER AIN MEDIAL FORM
  (#xED #xFECE) ; ARABIC LETTER GHAIN FINAL FORM
  (#xEE #xFECD) ; ARABIC LETTER GHAIN ISOLATED FORM
  (#xEF #xFEE1) ; ARABIC LETTER MEEM ISOLATED FORM
  (#xF0 #xFE7D) ; ARABIC SHADDA MEDIAL FORM
  (#xF1 #x0651) ; ARABIC SHADDAH
  (#xF2 #xFEE5) ; ARABIC LETTER NOON ISOLATED FORM
  (#xF3 #xFEE9) ; ARABIC LETTER HEH ISOLATED FORM
  (#xF4 #xFEEC) ; ARABIC LETTER HEH MEDIAL FORM
  (#xF5 #xFEF0) ; ARABIC LETTER ALEF MAKSURA FINAL FORM
  (#xF6 #xFEF2) ; ARABIC LETTER YEH FINAL FORM
  (#xF7 #xFED0) ; ARABIC LETTER GHAIN MEDIAL FORM
  (#xF8 #xFED5) ; ARABIC LETTER QAF ISOLATED FORM
  (#xF9 #xFEF5) ; ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE ISOLATED FORM
  (#xFA #xFEF6) ; ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE FINAL FORM
  (#xFB #xFEDD) ; ARABIC LETTER LAM ISOLATED FORM
  (#xFC #xFED9) ; ARABIC LETTER KAF ISOLATED FORM
  (#xFD #xFEF1) ; ARABIC LETTER YEH ISOLATED FORM
  (#xFE #x25A0) ; BLACK SQUARE
  (#xFF nil)
)

(declaim (inline get-cp864-bytes))
(defun get-cp864-bytes (string pos)
  (declare (optimize speed (safety 0))
           (type simple-string string)
           (type array-range pos))
  (get-latin-bytes #'code->cp864-mapper :cp864 string pos))

(defun string->cp864 (string sstart send null-padding)
  (declare (optimize speed (safety 0))
           (type simple-string string)
           (type array-range sstart send))
  (values (string->latin% string sstart send #'get-cp864-bytes null-padding)))

(defmacro define-cp864->string* (accessor type)
  (declare (ignore type))
  (let ((name (make-od-name 'cp864->string* accessor)))
    `(progn
      (defun ,name (string sstart send array astart aend)
        (,(make-od-name 'latin->string* accessor) string sstart send array astart aend #'cp864->code-mapper)))))

(instantiate-octets-definition define-cp864->string*)

(defmacro define-cp864->string (accessor type)
  (declare (ignore type))
  `(defun ,(make-od-name 'cp864->string accessor) (array astart aend)
    (,(make-od-name 'latin->string accessor) array astart aend #'cp864->code-mapper)))

(instantiate-octets-definition define-cp864->string)

(add-external-format-funs '(:cp864 :|cp864|)
                          '(cp864->string-aref string->cp864))

(define-external-format (:cp864 :|cp864|)
    1 t
    (let ((cp864-byte (code->cp864-mapper bits)))
      (if cp864-byte
          (setf (sap-ref-8 sap tail) cp864-byte)
          (external-format-encoding-error stream bits)))
    (let ((code (cp864->code-mapper byte)))
      (if code
          (code-char code)
          (external-format-decoding-error stream byte)))) ;; TODO -- error check

(define-unibyte-mapper cp865->code-mapper code->cp865-mapper
  (#x80 #x00C7) ; LATIN CAPITAL LETTER C WITH CEDILLA
  (#x81 #x00FC) ; LATIN SMALL LETTER U WITH DIAERESIS
  (#x82 #x00E9) ; LATIN SMALL LETTER E WITH ACUTE
  (#x83 #x00E2) ; LATIN SMALL LETTER A WITH CIRCUMFLEX
  (#x84 #x00E4) ; LATIN SMALL LETTER A WITH DIAERESIS
  (#x85 #x00E0) ; LATIN SMALL LETTER A WITH GRAVE
  (#x86 #x00E5) ; LATIN SMALL LETTER A WITH RING ABOVE
  (#x87 #x00E7) ; LATIN SMALL LETTER C WITH CEDILLA
  (#x88 #x00EA) ; LATIN SMALL LETTER E WITH CIRCUMFLEX
  (#x89 #x00EB) ; LATIN SMALL LETTER E WITH DIAERESIS
  (#x8A #x00E8) ; LATIN SMALL LETTER E WITH GRAVE
  (#x8B #x00EF) ; LATIN SMALL LETTER I WITH DIAERESIS
  (#x8C #x00EE) ; LATIN SMALL LETTER I WITH CIRCUMFLEX
  (#x8D #x00EC) ; LATIN SMALL LETTER I WITH GRAVE
  (#x8E #x00C4) ; LATIN CAPITAL LETTER A WITH DIAERESIS
  (#x8F #x00C5) ; LATIN CAPITAL LETTER A WITH RING ABOVE
  (#x90 #x00C9) ; LATIN CAPITAL LETTER E WITH ACUTE
  (#x91 #x00E6) ; LATIN SMALL LIGATURE AE
  (#x92 #x00C6) ; LATIN CAPITAL LIGATURE AE
  (#x93 #x00F4) ; LATIN SMALL LETTER O WITH CIRCUMFLEX
  (#x94 #x00F6) ; LATIN SMALL LETTER O WITH DIAERESIS
  (#x95 #x00F2) ; LATIN SMALL LETTER O WITH GRAVE
  (#x96 #x00FB) ; LATIN SMALL LETTER U WITH CIRCUMFLEX
  (#x97 #x00F9) ; LATIN SMALL LETTER U WITH GRAVE
  (#x98 #x00FF) ; LATIN SMALL LETTER Y WITH DIAERESIS
  (#x99 #x00D6) ; LATIN CAPITAL LETTER O WITH DIAERESIS
  (#x9A #x00DC) ; LATIN CAPITAL LETTER U WITH DIAERESIS
  (#x9B #x00F8) ; LATIN SMALL LETTER O WITH STROKE
  (#x9C #x00A3) ; POUND SIGN
  (#x9D #x00D8) ; LATIN CAPITAL LETTER O WITH STROKE
  (#x9E #x20A7) ; PESETA SIGN
  (#x9F #x0192) ; LATIN SMALL LETTER F WITH HOOK
  (#xA0 #x00E1) ; LATIN SMALL LETTER A WITH ACUTE
  (#xA1 #x00ED) ; LATIN SMALL LETTER I WITH ACUTE
  (#xA2 #x00F3) ; LATIN SMALL LETTER O WITH ACUTE
  (#xA3 #x00FA) ; LATIN SMALL LETTER U WITH ACUTE
  (#xA4 #x00F1) ; LATIN SMALL LETTER N WITH TILDE
  (#xA5 #x00D1) ; LATIN CAPITAL LETTER N WITH TILDE
  (#xA6 #x00AA) ; FEMININE ORDINAL INDICATOR
  (#xA7 #x00BA) ; MASCULINE ORDINAL INDICATOR
  (#xA8 #x00BF) ; INVERTED QUESTION MARK
  (#xA9 #x2310) ; REVERSED NOT SIGN
  (#xAA #x00AC) ; NOT SIGN
  (#xAB #x00BD) ; VULGAR FRACTION ONE HALF
  (#xAC #x00BC) ; VULGAR FRACTION ONE QUARTER
  (#xAD #x00A1) ; INVERTED EXCLAMATION MARK
  (#xAE #x00AB) ; LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
  (#xAF #x00A4) ; CURRENCY SIGN
  (#xB0 #x2591) ; LIGHT SHADE
  (#xB1 #x2592) ; MEDIUM SHADE
  (#xB2 #x2593) ; DARK SHADE
  (#xB3 #x2502) ; BOX DRAWINGS LIGHT VERTICAL
  (#xB4 #x2524) ; BOX DRAWINGS LIGHT VERTICAL AND LEFT
  (#xB5 #x2561) ; BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE
  (#xB6 #x2562) ; BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE
  (#xB7 #x2556) ; BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE
  (#xB8 #x2555) ; BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE
  (#xB9 #x2563) ; BOX DRAWINGS DOUBLE VERTICAL AND LEFT
  (#xBA #x2551) ; BOX DRAWINGS DOUBLE VERTICAL
  (#xBB #x2557) ; BOX DRAWINGS DOUBLE DOWN AND LEFT
  (#xBC #x255D) ; BOX DRAWINGS DOUBLE UP AND LEFT
  (#xBD #x255C) ; BOX DRAWINGS UP DOUBLE AND LEFT SINGLE
  (#xBE #x255B) ; BOX DRAWINGS UP SINGLE AND LEFT DOUBLE
  (#xBF #x2510) ; BOX DRAWINGS LIGHT DOWN AND LEFT
  (#xC0 #x2514) ; BOX DRAWINGS LIGHT UP AND RIGHT
  (#xC1 #x2534) ; BOX DRAWINGS LIGHT UP AND HORIZONTAL
  (#xC2 #x252C) ; BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
  (#xC3 #x251C) ; BOX DRAWINGS LIGHT VERTICAL AND RIGHT
  (#xC4 #x2500) ; BOX DRAWINGS LIGHT HORIZONTAL
  (#xC5 #x253C) ; BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
  (#xC6 #x255E) ; BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE
  (#xC7 #x255F) ; BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE
  (#xC8 #x255A) ; BOX DRAWINGS DOUBLE UP AND RIGHT
  (#xC9 #x2554) ; BOX DRAWINGS DOUBLE DOWN AND RIGHT
  (#xCA #x2569) ; BOX DRAWINGS DOUBLE UP AND HORIZONTAL
  (#xCB #x2566) ; BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
  (#xCC #x2560) ; BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
  (#xCD #x2550) ; BOX DRAWINGS DOUBLE HORIZONTAL
  (#xCE #x256C) ; BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
  (#xCF #x2567) ; BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE
  (#xD0 #x2568) ; BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE
  (#xD1 #x2564) ; BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE
  (#xD2 #x2565) ; BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE
  (#xD3 #x2559) ; BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE
  (#xD4 #x2558) ; BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE
  (#xD5 #x2552) ; BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE
  (#xD6 #x2553) ; BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE
  (#xD7 #x256B) ; BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE
  (#xD8 #x256A) ; BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE
  (#xD9 #x2518) ; BOX DRAWINGS LIGHT UP AND LEFT
  (#xDA #x250C) ; BOX DRAWINGS LIGHT DOWN AND RIGHT
  (#xDB #x2588) ; FULL BLOCK
  (#xDC #x2584) ; LOWER HALF BLOCK
  (#xDD #x258C) ; LEFT HALF BLOCK
  (#xDE #x2590) ; RIGHT HALF BLOCK
  (#xDF #x2580) ; UPPER HALF BLOCK
  (#xE0 #x03B1) ; GREEK SMALL LETTER ALPHA
  (#xE1 #x00DF) ; LATIN SMALL LETTER SHARP S
  (#xE2 #x0393) ; GREEK CAPITAL LETTER GAMMA
  (#xE3 #x03C0) ; GREEK SMALL LETTER PI
  (#xE4 #x03A3) ; GREEK CAPITAL LETTER SIGMA
  (#xE5 #x03C3) ; GREEK SMALL LETTER SIGMA
  (#xE6 #x00B5) ; MICRO SIGN
  (#xE7 #x03C4) ; GREEK SMALL LETTER TAU
  (#xE8 #x03A6) ; GREEK CAPITAL LETTER PHI
  (#xE9 #x0398) ; GREEK CAPITAL LETTER THETA
  (#xEA #x03A9) ; GREEK CAPITAL LETTER OMEGA
  (#xEB #x03B4) ; GREEK SMALL LETTER DELTA
  (#xEC #x221E) ; INFINITY
  (#xED #x03C6) ; GREEK SMALL LETTER PHI
  (#xEE #x03B5) ; GREEK SMALL LETTER EPSILON
  (#xEF #x2229) ; INTERSECTION
  (#xF0 #x2261) ; IDENTICAL TO
  (#xF1 #x00B1) ; PLUS-MINUS SIGN
  (#xF2 #x2265) ; GREATER-THAN OR EQUAL TO
  (#xF3 #x2264) ; LESS-THAN OR EQUAL TO
  (#xF4 #x2320) ; TOP HALF INTEGRAL
  (#xF5 #x2321) ; BOTTOM HALF INTEGRAL
  (#xF6 #x00F7) ; DIVISION SIGN
  (#xF7 #x2248) ; ALMOST EQUAL TO
  (#xF8 #x00B0) ; DEGREE SIGN
  (#xF9 #x2219) ; BULLET OPERATOR
  (#xFA #x00B7) ; MIDDLE DOT
  (#xFB #x221A) ; SQUARE ROOT
  (#xFC #x207F) ; SUPERSCRIPT LATIN SMALL LETTER N
  (#xFD #x00B2) ; SUPERSCRIPT TWO
  (#xFE #x25A0) ; BLACK SQUARE
  (#xFF #x00A0) ; NO-BREAK SPACE
)

(declaim (inline get-cp865-bytes))
(defun get-cp865-bytes (string pos)
  (declare (optimize speed (safety 0))
           (type simple-string string)
           (type array-range pos))
  (get-latin-bytes #'code->cp865-mapper :cp865 string pos))

(defun string->cp865 (string sstart send null-padding)
  (declare (optimize speed (safety 0))
           (type simple-string string)
           (type array-range sstart send))
  (values (string->latin% string sstart send #'get-cp865-bytes null-padding)))

(defmacro define-cp865->string* (accessor type)
  (declare (ignore type))
  (let ((name (make-od-name 'cp865->string* accessor)))
    `(progn
      (defun ,name (string sstart send array astart aend)
        (,(make-od-name 'latin->string* accessor) string sstart send array astart aend #'cp865->code-mapper)))))

(instantiate-octets-definition define-cp865->string*)

(defmacro define-cp865->string (accessor type)
  (declare (ignore type))
  `(defun ,(make-od-name 'cp865->string accessor) (array astart aend)
    (,(make-od-name 'latin->string accessor) array astart aend #'cp865->code-mapper)))

(instantiate-octets-definition define-cp865->string)

(add-external-format-funs '(:cp865 :|cp865|)
                          '(cp865->string-aref string->cp865))

(define-external-format (:cp865 :|cp865|)
    1 t
    (let ((cp865-byte (code->cp865-mapper bits)))
      (if cp865-byte
          (setf (sap-ref-8 sap tail) cp865-byte)
          (external-format-encoding-error stream bits)))
    (let ((code (cp865->code-mapper byte)))
      (if code
          (code-char code)
          (external-format-decoding-error stream byte)))) ;; TODO -- error check

(define-unibyte-mapper cp866->code-mapper code->cp866-mapper
  (#x80 #x0410) ; CYRILLIC CAPITAL LETTER A
  (#x81 #x0411) ; CYRILLIC CAPITAL LETTER BE
  (#x82 #x0412) ; CYRILLIC CAPITAL LETTER VE
  (#x83 #x0413) ; CYRILLIC CAPITAL LETTER GHE
  (#x84 #x0414) ; CYRILLIC CAPITAL LETTER DE
  (#x85 #x0415) ; CYRILLIC CAPITAL LETTER IE
  (#x86 #x0416) ; CYRILLIC CAPITAL LETTER ZHE
  (#x87 #x0417) ; CYRILLIC CAPITAL LETTER ZE
  (#x88 #x0418) ; CYRILLIC CAPITAL LETTER I
  (#x89 #x0419) ; CYRILLIC CAPITAL LETTER SHORT I
  (#x8A #x041A) ; CYRILLIC CAPITAL LETTER KA
  (#x8B #x041B) ; CYRILLIC CAPITAL LETTER EL
  (#x8C #x041C) ; CYRILLIC CAPITAL LETTER EM
  (#x8D #x041D) ; CYRILLIC CAPITAL LETTER EN
  (#x8E #x041E) ; CYRILLIC CAPITAL LETTER O
  (#x8F #x041F) ; CYRILLIC CAPITAL LETTER PE
  (#x90 #x0420) ; CYRILLIC CAPITAL LETTER ER
  (#x91 #x0421) ; CYRILLIC CAPITAL LETTER ES
  (#x92 #x0422) ; CYRILLIC CAPITAL LETTER TE
  (#x93 #x0423) ; CYRILLIC CAPITAL LETTER U
  (#x94 #x0424) ; CYRILLIC CAPITAL LETTER EF
  (#x95 #x0425) ; CYRILLIC CAPITAL LETTER HA
  (#x96 #x0426) ; CYRILLIC CAPITAL LETTER TSE
  (#x97 #x0427) ; CYRILLIC CAPITAL LETTER CHE
  (#x98 #x0428) ; CYRILLIC CAPITAL LETTER SHA
  (#x99 #x0429) ; CYRILLIC CAPITAL LETTER SHCHA
  (#x9A #x042A) ; CYRILLIC CAPITAL LETTER HARD SIGN
  (#x9B #x042B) ; CYRILLIC CAPITAL LETTER YERU
  (#x9C #x042C) ; CYRILLIC CAPITAL LETTER SOFT SIGN
  (#x9D #x042D) ; CYRILLIC CAPITAL LETTER E
  (#x9E #x042E) ; CYRILLIC CAPITAL LETTER YU
  (#x9F #x042F) ; CYRILLIC CAPITAL LETTER YA
  (#xA0 #x0430) ; CYRILLIC SMALL LETTER A
  (#xA1 #x0431) ; CYRILLIC SMALL LETTER BE
  (#xA2 #x0432) ; CYRILLIC SMALL LETTER VE
  (#xA3 #x0433) ; CYRILLIC SMALL LETTER GHE
  (#xA4 #x0434) ; CYRILLIC SMALL LETTER DE
  (#xA5 #x0435) ; CYRILLIC SMALL LETTER IE
  (#xA6 #x0436) ; CYRILLIC SMALL LETTER ZHE
  (#xA7 #x0437) ; CYRILLIC SMALL LETTER ZE
  (#xA8 #x0438) ; CYRILLIC SMALL LETTER I
  (#xA9 #x0439) ; CYRILLIC SMALL LETTER SHORT I
  (#xAA #x043A) ; CYRILLIC SMALL LETTER KA
  (#xAB #x043B) ; CYRILLIC SMALL LETTER EL
  (#xAC #x043C) ; CYRILLIC SMALL LETTER EM
  (#xAD #x043D) ; CYRILLIC SMALL LETTER EN
  (#xAE #x043E) ; CYRILLIC SMALL LETTER O
  (#xAF #x043F) ; CYRILLIC SMALL LETTER PE
  (#xB0 #x2591) ; LIGHT SHADE
  (#xB1 #x2592) ; MEDIUM SHADE
  (#xB2 #x2593) ; DARK SHADE
  (#xB3 #x2502) ; BOX DRAWINGS LIGHT VERTICAL
  (#xB4 #x2524) ; BOX DRAWINGS LIGHT VERTICAL AND LEFT
  (#xB5 #x2561) ; BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE
  (#xB6 #x2562) ; BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE
  (#xB7 #x2556) ; BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE
  (#xB8 #x2555) ; BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE
  (#xB9 #x2563) ; BOX DRAWINGS DOUBLE VERTICAL AND LEFT
  (#xBA #x2551) ; BOX DRAWINGS DOUBLE VERTICAL
  (#xBB #x2557) ; BOX DRAWINGS DOUBLE DOWN AND LEFT
  (#xBC #x255D) ; BOX DRAWINGS DOUBLE UP AND LEFT
  (#xBD #x255C) ; BOX DRAWINGS UP DOUBLE AND LEFT SINGLE
  (#xBE #x255B) ; BOX DRAWINGS UP SINGLE AND LEFT DOUBLE
  (#xBF #x2510) ; BOX DRAWINGS LIGHT DOWN AND LEFT
  (#xC0 #x2514) ; BOX DRAWINGS LIGHT UP AND RIGHT
  (#xC1 #x2534) ; BOX DRAWINGS LIGHT UP AND HORIZONTAL
  (#xC2 #x252C) ; BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
  (#xC3 #x251C) ; BOX DRAWINGS LIGHT VERTICAL AND RIGHT
  (#xC4 #x2500) ; BOX DRAWINGS LIGHT HORIZONTAL
  (#xC5 #x253C) ; BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
  (#xC6 #x255E) ; BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE
  (#xC7 #x255F) ; BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE
  (#xC8 #x255A) ; BOX DRAWINGS DOUBLE UP AND RIGHT
  (#xC9 #x2554) ; BOX DRAWINGS DOUBLE DOWN AND RIGHT
  (#xCA #x2569) ; BOX DRAWINGS DOUBLE UP AND HORIZONTAL
  (#xCB #x2566) ; BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
  (#xCC #x2560) ; BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
  (#xCD #x2550) ; BOX DRAWINGS DOUBLE HORIZONTAL
  (#xCE #x256C) ; BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
  (#xCF #x2567) ; BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE
  (#xD0 #x2568) ; BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE
  (#xD1 #x2564) ; BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE
  (#xD2 #x2565) ; BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE
  (#xD3 #x2559) ; BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE
  (#xD4 #x2558) ; BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE
  (#xD5 #x2552) ; BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE
  (#xD6 #x2553) ; BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE
  (#xD7 #x256B) ; BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE
  (#xD8 #x256A) ; BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE
  (#xD9 #x2518) ; BOX DRAWINGS LIGHT UP AND LEFT
  (#xDA #x250C) ; BOX DRAWINGS LIGHT DOWN AND RIGHT
  (#xDB #x2588) ; FULL BLOCK
  (#xDC #x2584) ; LOWER HALF BLOCK
  (#xDD #x258C) ; LEFT HALF BLOCK
  (#xDE #x2590) ; RIGHT HALF BLOCK
  (#xDF #x2580) ; UPPER HALF BLOCK
  (#xE0 #x0440) ; CYRILLIC SMALL LETTER ER
  (#xE1 #x0441) ; CYRILLIC SMALL LETTER ES
  (#xE2 #x0442) ; CYRILLIC SMALL LETTER TE
  (#xE3 #x0443) ; CYRILLIC SMALL LETTER U
  (#xE4 #x0444) ; CYRILLIC SMALL LETTER EF
  (#xE5 #x0445) ; CYRILLIC SMALL LETTER HA
  (#xE6 #x0446) ; CYRILLIC SMALL LETTER TSE
  (#xE7 #x0447) ; CYRILLIC SMALL LETTER CHE
  (#xE8 #x0448) ; CYRILLIC SMALL LETTER SHA
  (#xE9 #x0449) ; CYRILLIC SMALL LETTER SHCHA
  (#xEA #x044A) ; CYRILLIC SMALL LETTER HARD SIGN
  (#xEB #x044B) ; CYRILLIC SMALL LETTER YERU
  (#xEC #x044C) ; CYRILLIC SMALL LETTER SOFT SIGN
  (#xED #x044D) ; CYRILLIC SMALL LETTER E
  (#xEE #x044E) ; CYRILLIC SMALL LETTER YU
  (#xEF #x044F) ; CYRILLIC SMALL LETTER YA
  (#xF0 #x0401) ; CYRILLIC CAPITAL LETTER IO
  (#xF1 #x0451) ; CYRILLIC SMALL LETTER IO
  (#xF2 #x0404) ; CYRILLIC CAPITAL LETTER UKRAINIAN IE
  (#xF3 #x0454) ; CYRILLIC SMALL LETTER UKRAINIAN IE
  (#xF4 #x0407) ; CYRILLIC CAPITAL LETTER YI
  (#xF5 #x0457) ; CYRILLIC SMALL LETTER YI
  (#xF6 #x040E) ; CYRILLIC CAPITAL LETTER SHORT U
  (#xF7 #x045E) ; CYRILLIC SMALL LETTER SHORT U
  (#xF8 #x00B0) ; DEGREE SIGN
  (#xF9 #x2219) ; BULLET OPERATOR
  (#xFA #x00B7) ; MIDDLE DOT
  (#xFB #x221A) ; SQUARE ROOT
  (#xFC #x2116) ; NUMERO SIGN
  (#xFD #x00A4) ; CURRENCY SIGN
  (#xFE #x25A0) ; BLACK SQUARE
  (#xFF #x00A0) ; NO-BREAK SPACE
)

(declaim (inline get-cp866-bytes))
(defun get-cp866-bytes (string pos)
  (declare (optimize speed (safety 0))
           (type simple-string string)
           (type array-range pos))
  (get-latin-bytes #'code->cp866-mapper :cp866 string pos))

(defun string->cp866 (string sstart send null-padding)
  (declare (optimize speed (safety 0))
           (type simple-string string)
           (type array-range sstart send))
  (values (string->latin% string sstart send #'get-cp866-bytes null-padding)))

(defmacro define-cp866->string* (accessor type)
  (declare (ignore type))
  (let ((name (make-od-name 'cp866->string* accessor)))
    `(progn
      (defun ,name (string sstart send array astart aend)
        (,(make-od-name 'latin->string* accessor) string sstart send array astart aend #'cp866->code-mapper)))))

(instantiate-octets-definition define-cp866->string*)

(defmacro define-cp866->string (accessor type)
  (declare (ignore type))
  `(defun ,(make-od-name 'cp866->string accessor) (array astart aend)
    (,(make-od-name 'latin->string accessor) array astart aend #'cp866->code-mapper)))

(instantiate-octets-definition define-cp866->string)

(add-external-format-funs '(:cp866 :|cp866|)
                          '(cp866->string-aref string->cp866))

(define-external-format (:cp866 :|cp866|)
    1 t
    (let ((cp866-byte (code->cp866-mapper bits)))
      (if cp866-byte
          (setf (sap-ref-8 sap tail) cp866-byte)
          (external-format-encoding-error stream bits)))
    (let ((code (cp866->code-mapper byte)))
      (if code
          (code-char code)
          (external-format-decoding-error stream byte)))) ;; TODO -- error check

(define-unibyte-mapper cp869->code-mapper code->cp869-mapper
  (#x80 nil)
  (#x81 nil)
  (#x82 nil)
  (#x83 nil)
  (#x84 nil)
  (#x85 nil)
  (#x86 #x0386) ; GREEK CAPITAL LETTER ALPHA WITH TONOS
  (#x87 nil)
  (#x88 #x00B7) ; MIDDLE DOT
  (#x89 #x00AC) ; NOT SIGN
  (#x8A #x00A6) ; BROKEN BAR
  (#x8B #x2018) ; LEFT SINGLE QUOTATION MARK
  (#x8C #x2019) ; RIGHT SINGLE QUOTATION MARK
  (#x8D #x0388) ; GREEK CAPITAL LETTER EPSILON WITH TONOS
  (#x8E #x2015) ; HORIZONTAL BAR
  (#x8F #x0389) ; GREEK CAPITAL LETTER ETA WITH TONOS
  (#x90 #x038A) ; GREEK CAPITAL LETTER IOTA WITH TONOS
  (#x91 #x03AA) ; GREEK CAPITAL LETTER IOTA WITH DIALYTIKA
  (#x92 #x038C) ; GREEK CAPITAL LETTER OMICRON WITH TONOS
  (#x93 nil)
  (#x94 nil)
  (#x95 #x038E) ; GREEK CAPITAL LETTER UPSILON WITH TONOS
  (#x96 #x03AB) ; GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA
  (#x97 #x00A9) ; COPYRIGHT SIGN
  (#x98 #x038F) ; GREEK CAPITAL LETTER OMEGA WITH TONOS
  (#x99 #x00B2) ; SUPERSCRIPT TWO
  (#x9A #x00B3) ; SUPERSCRIPT THREE
  (#x9B #x03AC) ; GREEK SMALL LETTER ALPHA WITH TONOS
  (#x9C #x00A3) ; POUND SIGN
  (#x9D #x03AD) ; GREEK SMALL LETTER EPSILON WITH TONOS
  (#x9E #x03AE) ; GREEK SMALL LETTER ETA WITH TONOS
  (#x9F #x03AF) ; GREEK SMALL LETTER IOTA WITH TONOS
  (#xA0 #x03CA) ; GREEK SMALL LETTER IOTA WITH DIALYTIKA
  (#xA1 #x0390) ; GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS
  (#xA2 #x03CC) ; GREEK SMALL LETTER OMICRON WITH TONOS
  (#xA3 #x03CD) ; GREEK SMALL LETTER UPSILON WITH TONOS
  (#xA4 #x0391) ; GREEK CAPITAL LETTER ALPHA
  (#xA5 #x0392) ; GREEK CAPITAL LETTER BETA
  (#xA6 #x0393) ; GREEK CAPITAL LETTER GAMMA
  (#xA7 #x0394) ; GREEK CAPITAL LETTER DELTA
  (#xA8 #x0395) ; GREEK CAPITAL LETTER EPSILON
  (#xA9 #x0396) ; GREEK CAPITAL LETTER ZETA
  (#xAA #x0397) ; GREEK CAPITAL LETTER ETA
  (#xAB #x00BD) ; VULGAR FRACTION ONE HALF
  (#xAC #x0398) ; GREEK CAPITAL LETTER THETA
  (#xAD #x0399) ; GREEK CAPITAL LETTER IOTA
  (#xAE #x00AB) ; LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
  (#xAF #x00BB) ; RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
  (#xB0 #x2591) ; LIGHT SHADE
  (#xB1 #x2592) ; MEDIUM SHADE
  (#xB2 #x2593) ; DARK SHADE
  (#xB3 #x2502) ; BOX DRAWINGS LIGHT VERTICAL
  (#xB4 #x2524) ; BOX DRAWINGS LIGHT VERTICAL AND LEFT
  (#xB5 #x039A) ; GREEK CAPITAL LETTER KAPPA
  (#xB6 #x039B) ; GREEK CAPITAL LETTER LAMDA
  (#xB7 #x039C) ; GREEK CAPITAL LETTER MU
  (#xB8 #x039D) ; GREEK CAPITAL LETTER NU
  (#xB9 #x2563) ; BOX DRAWINGS DOUBLE VERTICAL AND LEFT
  (#xBA #x2551) ; BOX DRAWINGS DOUBLE VERTICAL
  (#xBB #x2557) ; BOX DRAWINGS DOUBLE DOWN AND LEFT
  (#xBC #x255D) ; BOX DRAWINGS DOUBLE UP AND LEFT
  (#xBD #x039E) ; GREEK CAPITAL LETTER XI
  (#xBE #x039F) ; GREEK CAPITAL LETTER OMICRON
  (#xBF #x2510) ; BOX DRAWINGS LIGHT DOWN AND LEFT
  (#xC0 #x2514) ; BOX DRAWINGS LIGHT UP AND RIGHT
  (#xC1 #x2534) ; BOX DRAWINGS LIGHT UP AND HORIZONTAL
  (#xC2 #x252C) ; BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
  (#xC3 #x251C) ; BOX DRAWINGS LIGHT VERTICAL AND RIGHT
  (#xC4 #x2500) ; BOX DRAWINGS LIGHT HORIZONTAL
  (#xC5 #x253C) ; BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
  (#xC6 #x03A0) ; GREEK CAPITAL LETTER PI
  (#xC7 #x03A1) ; GREEK CAPITAL LETTER RHO
  (#xC8 #x255A) ; BOX DRAWINGS DOUBLE UP AND RIGHT
  (#xC9 #x2554) ; BOX DRAWINGS DOUBLE DOWN AND RIGHT
  (#xCA #x2569) ; BOX DRAWINGS DOUBLE UP AND HORIZONTAL
  (#xCB #x2566) ; BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
  (#xCC #x2560) ; BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
  (#xCD #x2550) ; BOX DRAWINGS DOUBLE HORIZONTAL
  (#xCE #x256C) ; BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
  (#xCF #x03A3) ; GREEK CAPITAL LETTER SIGMA
  (#xD0 #x03A4) ; GREEK CAPITAL LETTER TAU
  (#xD1 #x03A5) ; GREEK CAPITAL LETTER UPSILON
  (#xD2 #x03A6) ; GREEK CAPITAL LETTER PHI
  (#xD3 #x03A7) ; GREEK CAPITAL LETTER CHI
  (#xD4 #x03A8) ; GREEK CAPITAL LETTER PSI
  (#xD5 #x03A9) ; GREEK CAPITAL LETTER OMEGA
  (#xD6 #x03B1) ; GREEK SMALL LETTER ALPHA
  (#xD7 #x03B2) ; GREEK SMALL LETTER BETA
  (#xD8 #x03B3) ; GREEK SMALL LETTER GAMMA
  (#xD9 #x2518) ; BOX DRAWINGS LIGHT UP AND LEFT
  (#xDA #x250C) ; BOX DRAWINGS LIGHT DOWN AND RIGHT
  (#xDB #x2588) ; FULL BLOCK
  (#xDC #x2584) ; LOWER HALF BLOCK
  (#xDD #x03B4) ; GREEK SMALL LETTER DELTA
  (#xDE #x03B5) ; GREEK SMALL LETTER EPSILON
  (#xDF #x2580) ; UPPER HALF BLOCK
  (#xE0 #x03B6) ; GREEK SMALL LETTER ZETA
  (#xE1 #x03B7) ; GREEK SMALL LETTER ETA
  (#xE2 #x03B8) ; GREEK SMALL LETTER THETA
  (#xE3 #x03B9) ; GREEK SMALL LETTER IOTA
  (#xE4 #x03BA) ; GREEK SMALL LETTER KAPPA
  (#xE5 #x03BB) ; GREEK SMALL LETTER LAMDA
  (#xE6 #x03BC) ; GREEK SMALL LETTER MU
  (#xE7 #x03BD) ; GREEK SMALL LETTER NU
  (#xE8 #x03BE) ; GREEK SMALL LETTER XI
  (#xE9 #x03BF) ; GREEK SMALL LETTER OMICRON
  (#xEA #x03C0) ; GREEK SMALL LETTER PI
  (#xEB #x03C1) ; GREEK SMALL LETTER RHO
  (#xEC #x03C3) ; GREEK SMALL LETTER SIGMA
  (#xED #x03C2) ; GREEK SMALL LETTER FINAL SIGMA
  (#xEE #x03C4) ; GREEK SMALL LETTER TAU
  (#xEF #x0384) ; GREEK TONOS
  (#xF0 #x00AD) ; SOFT HYPHEN
  (#xF1 #x00B1) ; PLUS-MINUS SIGN
  (#xF2 #x03C5) ; GREEK SMALL LETTER UPSILON
  (#xF3 #x03C6) ; GREEK SMALL LETTER PHI
  (#xF4 #x03C7) ; GREEK SMALL LETTER CHI
  (#xF5 #x00A7) ; SECTION SIGN
  (#xF6 #x03C8) ; GREEK SMALL LETTER PSI
  (#xF7 #x0385) ; GREEK DIALYTIKA TONOS
  (#xF8 #x00B0) ; DEGREE SIGN
  (#xF9 #x00A8) ; DIAERESIS
  (#xFA #x03C9) ; GREEK SMALL LETTER OMEGA
  (#xFB #x03CB) ; GREEK SMALL LETTER UPSILON WITH DIALYTIKA
  (#xFC #x03B0) ; GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS
  (#xFD #x03CE) ; GREEK SMALL LETTER OMEGA WITH TONOS
  (#xFE #x25A0) ; BLACK SQUARE
  (#xFF #x00A0) ; NO-BREAK SPACE
)

(declaim (inline get-cp869-bytes))
(defun get-cp869-bytes (string pos)
  (declare (optimize speed (safety 0))
           (type simple-string string)
           (type array-range pos))
  (get-latin-bytes #'code->cp869-mapper :cp869 string pos))

(defun string->cp869 (string sstart send null-padding)
  (declare (optimize speed (safety 0))
           (type simple-string string)
           (type array-range sstart send))
  (values (string->latin% string sstart send #'get-cp869-bytes null-padding)))

(defmacro define-cp869->string* (accessor type)
  (declare (ignore type))
  (let ((name (make-od-name 'cp869->string* accessor)))
    `(progn
      (defun ,name (string sstart send array astart aend)
        (,(make-od-name 'latin->string* accessor) string sstart send array astart aend #'cp869->code-mapper)))))

(instantiate-octets-definition define-cp869->string*)

(defmacro define-cp869->string (accessor type)
  (declare (ignore type))
  `(defun ,(make-od-name 'cp869->string accessor) (array astart aend)
    (,(make-od-name 'latin->string accessor) array astart aend #'cp869->code-mapper)))

(instantiate-octets-definition define-cp869->string)

(add-external-format-funs '(:cp869 :|cp869|)
                          '(cp869->string-aref string->cp869))

(define-external-format (:cp869 :|cp869|)
    1 t
    (let ((cp869-byte (code->cp869-mapper bits)))
      (if cp869-byte
          (setf (sap-ref-8 sap tail) cp869-byte)
          (external-format-encoding-error stream bits)))
    (let ((code (cp869->code-mapper byte)))
      (if code
          (code-char code)
          (external-format-decoding-error stream byte)))) ;; TODO -- error check

(define-unibyte-mapper cp874->code-mapper code->cp874-mapper
  (#x80 #x20AC) ; EURO SIGN
  (#x81 nil)
  (#x82 nil)
  (#x83 nil)
  (#x84 nil)
  (#x85 #x2026) ; HORIZONTAL ELLIPSIS
  (#x86 nil)
  (#x87 nil)
  (#x88 nil)
  (#x89 nil)
  (#x8A nil)
  (#x8B nil)
  (#x8C nil)
  (#x8D nil)
  (#x8E nil)
  (#x8F nil)
  (#x90 nil)
  (#x91 #x2018) ; LEFT SINGLE QUOTATION MARK
  (#x92 #x2019) ; RIGHT SINGLE QUOTATION MARK
  (#x93 #x201C) ; LEFT DOUBLE QUOTATION MARK
  (#x94 #x201D) ; RIGHT DOUBLE QUOTATION MARK
  (#x95 #x2022) ; BULLET
  (#x96 #x2013) ; EN DASH
  (#x97 #x2014) ; EM DASH
  (#x98 nil)
  (#x99 nil)
  (#x9A nil)
  (#x9B nil)
  (#x9C nil)
  (#x9D nil)
  (#x9E nil)
  (#x9F nil)
  (#xA1 #x0E01) ; THAI CHARACTER KO KAI
  (#xA2 #x0E02) ; THAI CHARACTER KHO KHAI
  (#xA3 #x0E03) ; THAI CHARACTER KHO KHUAT
  (#xA4 #x0E04) ; THAI CHARACTER KHO KHWAI
  (#xA5 #x0E05) ; THAI CHARACTER KHO KHON
  (#xA6 #x0E06) ; THAI CHARACTER KHO RAKHANG
  (#xA7 #x0E07) ; THAI CHARACTER NGO NGU
  (#xA8 #x0E08) ; THAI CHARACTER CHO CHAN
  (#xA9 #x0E09) ; THAI CHARACTER CHO CHING
  (#xAA #x0E0A) ; THAI CHARACTER CHO CHANG
  (#xAB #x0E0B) ; THAI CHARACTER SO SO
  (#xAC #x0E0C) ; THAI CHARACTER CHO CHOE
  (#xAD #x0E0D) ; THAI CHARACTER YO YING
  (#xAE #x0E0E) ; THAI CHARACTER DO CHADA
  (#xAF #x0E0F) ; THAI CHARACTER TO PATAK
  (#xB0 #x0E10) ; THAI CHARACTER THO THAN
  (#xB1 #x0E11) ; THAI CHARACTER THO NANGMONTHO
  (#xB2 #x0E12) ; THAI CHARACTER THO PHUTHAO
  (#xB3 #x0E13) ; THAI CHARACTER NO NEN
  (#xB4 #x0E14) ; THAI CHARACTER DO DEK
  (#xB5 #x0E15) ; THAI CHARACTER TO TAO
  (#xB6 #x0E16) ; THAI CHARACTER THO THUNG
  (#xB7 #x0E17) ; THAI CHARACTER THO THAHAN
  (#xB8 #x0E18) ; THAI CHARACTER THO THONG
  (#xB9 #x0E19) ; THAI CHARACTER NO NU
  (#xBA #x0E1A) ; THAI CHARACTER BO BAIMAI
  (#xBB #x0E1B) ; THAI CHARACTER PO PLA
  (#xBC #x0E1C) ; THAI CHARACTER PHO PHUNG
  (#xBD #x0E1D) ; THAI CHARACTER FO FA
  (#xBE #x0E1E) ; THAI CHARACTER PHO PHAN
  (#xBF #x0E1F) ; THAI CHARACTER FO FAN
  (#xC0 #x0E20) ; THAI CHARACTER PHO SAMPHAO
  (#xC1 #x0E21) ; THAI CHARACTER MO MA
  (#xC2 #x0E22) ; THAI CHARACTER YO YAK
  (#xC3 #x0E23) ; THAI CHARACTER RO RUA
  (#xC4 #x0E24) ; THAI CHARACTER RU
  (#xC5 #x0E25) ; THAI CHARACTER LO LING
  (#xC6 #x0E26) ; THAI CHARACTER LU
  (#xC7 #x0E27) ; THAI CHARACTER WO WAEN
  (#xC8 #x0E28) ; THAI CHARACTER SO SALA
  (#xC9 #x0E29) ; THAI CHARACTER SO RUSI
  (#xCA #x0E2A) ; THAI CHARACTER SO SUA
  (#xCB #x0E2B) ; THAI CHARACTER HO HIP
  (#xCC #x0E2C) ; THAI CHARACTER LO CHULA
  (#xCD #x0E2D) ; THAI CHARACTER O ANG
  (#xCE #x0E2E) ; THAI CHARACTER HO NOKHUK
  (#xCF #x0E2F) ; THAI CHARACTER PAIYANNOI
  (#xD0 #x0E30) ; THAI CHARACTER SARA A
  (#xD1 #x0E31) ; THAI CHARACTER MAI HAN-AKAT
  (#xD2 #x0E32) ; THAI CHARACTER SARA AA
  (#xD3 #x0E33) ; THAI CHARACTER SARA AM
  (#xD4 #x0E34) ; THAI CHARACTER SARA I
  (#xD5 #x0E35) ; THAI CHARACTER SARA II
  (#xD6 #x0E36) ; THAI CHARACTER SARA UE
  (#xD7 #x0E37) ; THAI CHARACTER SARA UEE
  (#xD8 #x0E38) ; THAI CHARACTER SARA U
  (#xD9 #x0E39) ; THAI CHARACTER SARA UU
  (#xDA #x0E3A) ; THAI CHARACTER PHINTHU
  (#xDB nil)
  (#xDC nil)
  (#xDD nil)
  (#xDE nil)
  (#xDF #x0E3F) ; THAI CURRENCY SYMBOL BAHT
  (#xE0 #x0E40) ; THAI CHARACTER SARA E
  (#xE1 #x0E41) ; THAI CHARACTER SARA AE
  (#xE2 #x0E42) ; THAI CHARACTER SARA O
  (#xE3 #x0E43) ; THAI CHARACTER SARA AI MAIMUAN
  (#xE4 #x0E44) ; THAI CHARACTER SARA AI MAIMALAI
  (#xE5 #x0E45) ; THAI CHARACTER LAKKHANGYAO
  (#xE6 #x0E46) ; THAI CHARACTER MAIYAMOK
  (#xE7 #x0E47) ; THAI CHARACTER MAITAIKHU
  (#xE8 #x0E48) ; THAI CHARACTER MAI EK
  (#xE9 #x0E49) ; THAI CHARACTER MAI THO
  (#xEA #x0E4A) ; THAI CHARACTER MAI TRI
  (#xEB #x0E4B) ; THAI CHARACTER MAI CHATTAWA
  (#xEC #x0E4C) ; THAI CHARACTER THANTHAKHAT
  (#xED #x0E4D) ; THAI CHARACTER NIKHAHIT
  (#xEE #x0E4E) ; THAI CHARACTER YAMAKKAN
  (#xEF #x0E4F) ; THAI CHARACTER FONGMAN
  (#xF0 #x0E50) ; THAI DIGIT ZERO
  (#xF1 #x0E51) ; THAI DIGIT ONE
  (#xF2 #x0E52) ; THAI DIGIT TWO
  (#xF3 #x0E53) ; THAI DIGIT THREE
  (#xF4 #x0E54) ; THAI DIGIT FOUR
  (#xF5 #x0E55) ; THAI DIGIT FIVE
  (#xF6 #x0E56) ; THAI DIGIT SIX
  (#xF7 #x0E57) ; THAI DIGIT SEVEN
  (#xF8 #x0E58) ; THAI DIGIT EIGHT
  (#xF9 #x0E59) ; THAI DIGIT NINE
  (#xFA #x0E5A) ; THAI CHARACTER ANGKHANKHU
  (#xFB #x0E5B) ; THAI CHARACTER KHOMUT
  (#xFC nil)
  (#xFD nil)
  (#xFE nil)
  (#xFF nil)
)

(declaim (inline get-cp874-bytes))
(defun get-cp874-bytes (string pos)
  (declare (optimize speed (safety 0))
           (type simple-string string)
           (type array-range pos))
  (get-latin-bytes #'code->cp874-mapper :cp874 string pos))

(defun string->cp874 (string sstart send null-padding)
  (declare (optimize speed (safety 0))
           (type simple-string string)
           (type array-range sstart send))
  (values (string->latin% string sstart send #'get-cp874-bytes null-padding)))

(defmacro define-cp874->string* (accessor type)
  (declare (ignore type))
  (let ((name (make-od-name 'cp874->string* accessor)))
    `(progn
      (defun ,name (string sstart send array astart aend)
        (,(make-od-name 'latin->string* accessor) string sstart send array astart aend #'cp874->code-mapper)))))

(instantiate-octets-definition define-cp874->string*)

(defmacro define-cp874->string (accessor type)
  (declare (ignore type))
  `(defun ,(make-od-name 'cp874->string accessor) (array astart aend)
    (,(make-od-name 'latin->string accessor) array astart aend #'cp874->code-mapper)))

(instantiate-octets-definition define-cp874->string)

(add-external-format-funs '(:cp874 :|cp874|)
                          '(cp874->string-aref string->cp874))

(define-external-format (:cp874 :|cp874|)
    1 t
    (let ((cp874-byte (code->cp874-mapper bits)))
      (if cp874-byte
          (setf (sap-ref-8 sap tail) cp874-byte)
          (external-format-encoding-error stream bits)))
    (let ((code (cp874->code-mapper byte)))
      (if code
          (code-char code)
          (external-format-decoding-error stream byte)))) ;; TODO -- error check
