Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset 171f9a1 in mainline


Ignore:
Timestamp:
2009-04-03T20:39:33Z (13 years ago)
Author:
Jiri Svoboda <jirik.svoboda@…>
Branches:
lfn, master
Children:
cb01e1e
Parents:
7a2c479
Message:

Character encoding/decoding un uspace. Partially fix klog application.

Files:
7 edited

Legend:

Unmodified
Added
Removed
  • kernel/generic/src/console/console.c

    r7a2c479 r171f9a1  
    5454
    5555#define KLOG_SIZE     PAGE_SIZE
     56#define KLOG_LENGTH   (KLOG_SIZE / sizeof(wchar_t))
    5657#define KLOG_LATENCY  8
    5758
    5859/** Kernel log cyclic buffer */
    59 static wchar_t klog[KLOG_SIZE] __attribute__ ((aligned (PAGE_SIZE)));
     60static wchar_t klog[KLOG_LENGTH] __attribute__ ((aligned (PAGE_SIZE)));
    6061
    6162/** Kernel log initialized */
     
    258259                index_t i;
    259260                for (i = klog_len - klog_stored; i < klog_len; i++)
    260                         stdout->op->write(stdout, klog[(klog_start + i) % KLOG_SIZE], silent);
     261                        stdout->op->write(stdout, klog[(klog_start + i) % KLOG_LENGTH], silent);
    261262                klog_stored = 0;
    262263        }
    263264       
    264265        /* Store character in the cyclic kernel log */
    265         klog[(klog_start + klog_len) % KLOG_SIZE] = ch;
    266         if (klog_len < KLOG_SIZE)
     266        klog[(klog_start + klog_len) % KLOG_LENGTH] = ch;
     267        if (klog_len < KLOG_LENGTH)
    267268                klog_len++;
    268269        else
    269                 klog_start = (klog_start + 1) % KLOG_SIZE;
     270                klog_start = (klog_start + 1) % KLOG_LENGTH;
    270271       
    271272        if ((stdout) && (stdout->op->write))
  • uspace/app/klog/klog.c

    r7a2c479 r171f9a1  
    4848#define NAME "klog"
    4949
    50 #define KLOG_SIZE PAGE_SIZE
     50#define KLOG_SIZE       PAGE_SIZE
     51#define KLOG_LENGTH     (KLOG_SIZE / sizeof(wchar_t))
    5152
    5253/* Pointer to klog area */
    53 static char *klog;
     54static wchar_t *klog;
    5455
    5556static void interrupt_received(ipc_callid_t callid, ipc_call_t *call)
     
    6263        size_t i;
    6364        for (i = klog_len - klog_stored; i < klog_len; i++)
    64                 putchar(klog[(klog_start + i) % KLOG_SIZE]);
     65                putchar(klog[(klog_start + i) % KLOG_LENGTH]);
    6566       
    6667        async_serialize_end();
  • uspace/lib/libc/generic/console.c

    r7a2c479 r171f9a1  
    6262static void cbuffer_flush(void);
    6363static void cbuffer_drain(void);
    64 static void cbuffer_putc(int c);
     64static inline void cbuffer_putc(int c);
    6565
    6666
  • uspace/lib/libc/generic/string.c

    r7a2c479 r171f9a1  
    3939#include <ctype.h>
    4040#include <malloc.h>
     41#include <errno.h>
     42#include <string.h>
     43
     44/** Byte mask consisting of lowest @n bits (out of 8) */
     45#define LO_MASK_8(n)  ((uint8_t) ((1 << (n)) - 1))
     46
     47/** Byte mask consisting of lowest @n bits (out of 32) */
     48#define LO_MASK_32(n)  ((uint32_t) ((1 << (n)) - 1))
     49
     50/** Byte mask consisting of highest @n bits (out of 8) */
     51#define HI_MASK_8(n)  (~LO_MASK_8(8 - (n)))
     52
     53/** Number of data bits in a UTF-8 continuation byte */
     54#define CONT_BITS  6
     55
     56/** Decode a single character from a string.
     57 *
     58 * Decode a single character from a string of size @a size. Decoding starts
     59 * at @a offset and this offset is moved to the beginning of the next
     60 * character. In case of decoding error, offset generally advances at least
     61 * by one. However, offset is never moved beyond size.
     62 *
     63 * @param str    String (not necessarily NULL-terminated).
     64 * @param offset Byte offset in string where to start decoding.
     65 * @param size   Size of the string (in bytes).
     66 *
     67 * @return Value of decoded character, U_SPECIAL on decoding error or
     68 *         NULL if attempt to decode beyond @a size.
     69 *
     70 */
     71wchar_t str_decode(const char *str, size_t *offset, size_t size)
     72{
     73        if (*offset + 1 > size)
     74                return 0;
     75       
     76        /* First byte read from string */
     77        uint8_t b0 = (uint8_t) str[(*offset)++];
     78       
     79        /* Determine code length */
     80       
     81        unsigned int b0_bits;  /* Data bits in first byte */
     82        unsigned int cbytes;   /* Number of continuation bytes */
     83       
     84        if ((b0 & 0x80) == 0) {
     85                /* 0xxxxxxx (Plain ASCII) */
     86                b0_bits = 7;
     87                cbytes = 0;
     88        } else if ((b0 & 0xe0) == 0xc0) {
     89                /* 110xxxxx 10xxxxxx */
     90                b0_bits = 5;
     91                cbytes = 1;
     92        } else if ((b0 & 0xf0) == 0xe0) {
     93                /* 1110xxxx 10xxxxxx 10xxxxxx */
     94                b0_bits = 4;
     95                cbytes = 2;
     96        } else if ((b0 & 0xf8) == 0xf0) {
     97                /* 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */
     98                b0_bits = 3;
     99                cbytes = 3;
     100        } else {
     101                /* 10xxxxxx -- unexpected continuation byte */
     102                return U_SPECIAL;
     103        }
     104       
     105        if (*offset + cbytes > size)
     106                return U_SPECIAL;
     107       
     108        wchar_t ch = b0 & LO_MASK_8(b0_bits);
     109       
     110        /* Decode continuation bytes */
     111        while (cbytes > 0) {
     112                uint8_t b = (uint8_t) str[(*offset)++];
     113               
     114                /* Must be 10xxxxxx */
     115                if ((b & 0xc0) != 0x80)
     116                        return U_SPECIAL;
     117               
     118                /* Shift data bits to ch */
     119                ch = (ch << CONT_BITS) | (wchar_t) (b & LO_MASK_8(CONT_BITS));
     120                cbytes--;
     121        }
     122       
     123        return ch;
     124}
     125
     126/** Encode a single character to string representation.
     127 *
     128 * Encode a single character to string representation (i.e. UTF-8) and store
     129 * it into a buffer at @a offset. Encoding starts at @a offset and this offset
     130 * is moved to the position where the next character can be written to.
     131 *
     132 * @param ch     Input character.
     133 * @param str    Output buffer.
     134 * @param offset Byte offset where to start writing.
     135 * @param size   Size of the output buffer (in bytes).
     136 *
     137 * @return EOK if the character was encoded successfully, EOVERFLOW if there
     138 *         was not enough space in the output buffer or EINVAL if the character
     139 *         code was invalid.
     140 */
     141int chr_encode(const wchar_t ch, char *str, size_t *offset, size_t size)
     142{
     143        if (*offset >= size)
     144                return EOVERFLOW;
     145       
     146        if (!chr_check(ch))
     147                return EINVAL;
     148       
     149        /* Unsigned version of ch (bit operations should only be done
     150           on unsigned types). */
     151        uint32_t cc = (uint32_t) ch;
     152       
     153        /* Determine how many continuation bytes are needed */
     154       
     155        unsigned int b0_bits;  /* Data bits in first byte */
     156        unsigned int cbytes;   /* Number of continuation bytes */
     157       
     158        if ((cc & ~LO_MASK_32(7)) == 0) {
     159                b0_bits = 7;
     160                cbytes = 0;
     161        } else if ((cc & ~LO_MASK_32(11)) == 0) {
     162                b0_bits = 5;
     163                cbytes = 1;
     164        } else if ((cc & ~LO_MASK_32(16)) == 0) {
     165                b0_bits = 4;
     166                cbytes = 2;
     167        } else if ((cc & ~LO_MASK_32(21)) == 0) {
     168                b0_bits = 3;
     169                cbytes = 3;
     170        } else {
     171                /* Codes longer than 21 bits are not supported */
     172                return EINVAL;
     173        }
     174       
     175        /* Check for available space in buffer */
     176        if (*offset + cbytes >= size)
     177                return EOVERFLOW;
     178       
     179        /* Encode continuation bytes */
     180        unsigned int i;
     181        for (i = cbytes; i > 0; i--) {
     182                str[*offset + i] = 0x80 | (cc & LO_MASK_32(CONT_BITS));
     183                cc = cc >> CONT_BITS;
     184        }
     185       
     186        /* Encode first byte */
     187        str[*offset] = (cc & LO_MASK_32(b0_bits)) | HI_MASK_8(8 - b0_bits - 1);
     188       
     189        /* Advance offset */
     190        *offset += cbytes + 1;
     191       
     192        return EOK;
     193}
     194
     195/** Check whether character is valid
     196 *
     197 * @return True if character is a valid Unicode code point.
     198 *
     199 */
     200bool chr_check(const wchar_t ch)
     201{
     202        if ((ch >= 0) && (ch <= 1114111))
     203                return true;
     204       
     205        return false;
     206}
    41207
    42208/** Count the number of characters in the string, not including terminating 0.
  • uspace/lib/libc/include/string.h

    r7a2c479 r171f9a1  
    3838#include <mem.h>
    3939#include <sys/types.h>
     40#include <bool.h>
     41
     42#define U_SPECIAL      '?'
     43
     44extern wchar_t str_decode(const char *str, size_t *offset, size_t sz);
     45extern int chr_encode(const wchar_t ch, char *str, size_t *offset, size_t sz);
     46
     47extern bool chr_check(const wchar_t ch);
    4048
    4149extern int strcmp(const char *, const char *);
  • uspace/srv/console/console.c

    r7a2c479 r171f9a1  
    4949#include <sys/mman.h>
    5050#include <stdio.h>
     51#include <string.h>
    5152#include <sysinfo.h>
    5253#include <event.h>
     
    466467{
    467468        ipc_callid_t callid;
    468         size_t len;
    469         size_t i;
    470 
    471         if (!ipc_data_write_receive(&callid, &len)) {
     469        size_t size;
     470        wchar_t ch;
     471        size_t off;
     472
     473        if (!ipc_data_write_receive(&callid, &size)) {
    472474                ipc_answer_0(callid, EINVAL);
    473475                ipc_answer_0(rid, EINVAL);
    474476        }
    475477
    476         if (len > CWRITE_BUF_SIZE)
    477                 len = CWRITE_BUF_SIZE;
    478 
    479         (void) ipc_data_write_finalize(callid, cwrite_buf, len);
    480 
    481         for (i = 0; i < len; i++) {
    482                 write_char(consnum, cwrite_buf[i]);
     478        if (size > CWRITE_BUF_SIZE)
     479                size = CWRITE_BUF_SIZE;
     480
     481        (void) ipc_data_write_finalize(callid, cwrite_buf, size);
     482
     483        off = 0;
     484        while (off < size) {
     485                ch = str_decode(cwrite_buf, &off, size);
     486                write_char(consnum, ch);
    483487        }
    484488
    485489        gcons_notify_char(consnum);
    486         ipc_answer_1(rid, EOK, len);
     490        ipc_answer_1(rid, EOK, size);
    487491}
    488492
  • uspace/srv/fb/fb.c

    r7a2c479 r171f9a1  
    6969#define DEFAULT_FGCOLOR  0x000000
    7070
     71#define GLYPH_UNAVAIL   '?'
     72
    7173#define MAX_ANIM_LEN     8
    7274#define MAX_ANIMATIONS   4
     
    7981/** Function to draw a glyph. */
    8082typedef void (*dg_t)(unsigned int x, unsigned int y, bool cursor,
    81     uint8_t *glyphs, uint8_t glyph, uint32_t fg_color, uint32_t bg_color);
     83    uint8_t *glyphs, uint32_t glyph, uint32_t fg_color, uint32_t bg_color);
    8284
    8385struct {
     
    670672        /* Check glyph range. */
    671673        if (glyph >= FONT_GLYPHS)
    672                 return;
     674                glyph = GLYPH_UNAVAIL;
    673675
    674676        /*
     
    734736        /* Check glyph range. */
    735737        if (glyph >= FONT_GLYPHS)
    736                 return;
     738                glyph = GLYPH_UNAVAIL;
    737739
    738740        /* Pre-render 1x the foreground and background color pixels. */
Note: See TracChangeset for help on using the changeset viewer.