summaryrefslogblamecommitdiffstats
path: root/cpukit/libfs/src/dosfs/msdos_conv_default.c
blob: a3f6b835ee0934626cb4c015073e6d4e7584c200 (plain) (tree)


















                                                                 
                                        

   
                   





































































































































































                                                                          
/**
 * @file
 *
 * @ingroup DOSFS
 *
 * @brief Default Converter
 */

/*
 * Copyright (c) 2013 embedded brains GmbH.  All rights reserved.
 *
 *  embedded brains GmbH
 *  Dornierstr. 4
 *  82178 Puchheim
 *  Germany
 *  <rtems@embedded-brains.de>
 *
 * The license and distribution terms for this file may be
 * found in the file LICENSE in this distribution or at
 * http://www.rtems.org/license/LICENSE.
 */

#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
#include <assert.h>
#include <rtems/endian.h>
#include <rtems/dosfs.h>
#include "fat.h"
#include "msdos.h"

static int msdos_default_utf8_to_codepage(
  rtems_dosfs_convert_control *super,
  const uint8_t               *src,
  const size_t                 src_size,
  char                        *dst,
  size_t                      *dst_size
)
{
  int    eno = 0;
  size_t bytes_to_copy = MIN( src_size, *dst_size );

  (void) super;

  *dst_size = bytes_to_copy;

  memcpy( dst, src, bytes_to_copy );

  return eno;
}

static int msdos_default_codepage_to_utf8(
  rtems_dosfs_convert_control *super,
  const char                  *src,
  const size_t                 src_size,
  uint8_t                     *dst,
  size_t                      *dst_size
)
{
  int    eno = 0;
  size_t bytes_to_copy = MIN( src_size, *dst_size );

  (void) super;

  *dst_size = bytes_to_copy;

  memcpy( dst, src, bytes_to_copy );

  return eno;
}

static int msdos_default_utf8_to_utf16(
  rtems_dosfs_convert_control *super,
  const uint8_t               *src,
  const size_t                 src_size,
  uint16_t                    *dst,
  size_t                      *dst_size
)
{
  int    eno = 0;
  size_t bytes_to_copy = MIN( src_size, *dst_size / 2);
  size_t i;

  (void) super;

  *dst_size = 2 * bytes_to_copy;

  for ( i = 0; eno == 0 && i < bytes_to_copy; ++i ) {
    uint16_t utf16_native = src[i];

    if ( utf16_native <= 127 ) {
      dst[i] = CT_LE_W( utf16_native );
    } else {
      eno = EINVAL;
    }
  }

  return eno;
}

static int msdos_default_utf16_to_utf8(
  rtems_dosfs_convert_control *super,
  const uint16_t              *src,
  const size_t                 src_size,
  uint8_t                     *dst,
  size_t                      *dst_size
)
{
  int    eno = 0;
  size_t bytes_to_copy = MIN( src_size / 2, *dst_size );
  size_t i;

  (void) super;

  *dst_size = bytes_to_copy;

  for ( i = 0; eno == 0 && i < bytes_to_copy; ++i ) {
    uint16_t utf16_le = src[i];
    uint16_t utf16_native  = CF_LE_W( utf16_le );

    if ( utf16_native <= 127 ) {
      dst[i] = (uint8_t) utf16_native;
    } else {
      eno = EINVAL;
    }
  }

  return eno;
}

static int msdos_default_normalize_and_fold(
  rtems_dosfs_convert_control *super,
  const uint8_t               *src,
  const size_t                 src_size,
  uint8_t                     *dst,
  size_t                      *dst_size
)
{
  int    eno = 0;
  size_t bytes_to_copy = MIN( src_size, *dst_size );
  size_t i;

  (void) super;

  *dst_size = bytes_to_copy;

  for ( i = 0; i < bytes_to_copy; ++i ) {
    dst[i] = tolower( src[i] );
  }

  return eno;
}

static void msdos_default_destroy(
  rtems_dosfs_convert_control *super
)
{
  free( super );
}

static const rtems_dosfs_convert_handler msdos_default_convert_handler = {
  .utf8_to_codepage = msdos_default_utf8_to_codepage,
  .codepage_to_utf8 = msdos_default_codepage_to_utf8,
  .utf8_to_utf16 = msdos_default_utf8_to_utf16,
  .utf16_to_utf8 = msdos_default_utf16_to_utf8,
  .utf8_normalize_and_fold = msdos_default_normalize_and_fold,
  .destroy = msdos_default_destroy
};

typedef struct {
  rtems_dosfs_convert_control super;
  uint8_t buffer[MSDOS_NAME_MAX_LFN_BYTES];
} msdos_default_convert_control;

rtems_dosfs_convert_control *rtems_dosfs_create_default_converter(void)
{
  msdos_default_convert_control *self = malloc( sizeof( *self ) );

  if ( self != NULL ) {
    rtems_dosfs_convert_control *super = &self->super;

    super->handler = &msdos_default_convert_handler;
    super->buffer.data = &self->buffer;
    super->buffer.size = sizeof( self->buffer );
  }

  return &self->super;
}