/*!
  \file
  \brief mot ファイルの解析を行う

  \author Satofumi KAMIMURA

  $Id: mot_handler.c 1811 2010-04-30 16:12:05Z satofumi $
*/

#include "mot_handler.h"


static unsigned long hex2int(const char* str)
{
    unsigned long value = 0;
    const char *p;

    for (p = str; *p != '\0'; ++p) {
        value <<= 4;

        if (*p >= 'A') {
            value += *p - 'A' + 10;
        } else {
            value += *p - '0';
        }
    }

    return value;
}


int mot_parse(mot_t* mot, const char* line)
{
    int i;
    char type;
    char size_bytes[3];
    int byte_size;
    char address_bytes[9];
    int address_size;
    char *p;
    int data_size;

    if (line[0] != 'S') {
        // S-format 形式でなければ戻る
        return -1;
    }

    type = line[1] - '0';
    if (type <= 0) {
        // 何も格納せずに返す
        return type;
    }

    size_bytes[0] = line[2];
    size_bytes[1] = line[3];
    size_bytes[2] = '\0';
    byte_size = hex2int(size_bytes);

    // アドレスの格納
    address_size = 2 + (((type >= 7) ? (10 - type) : type) * 2);
    for (i = 0; i < address_size; ++i) {
        address_bytes[i] = line[4 + i];
    }
    address_bytes[address_size] = '\0';
    mot->address = hex2int(address_bytes);

    if (type >= 7) {
        return type;
    }

    // データの格納
    p = mot->data;
    data_size = byte_size - (address_size / 2) - 1;
    mot->data_size = data_size;
    data_size *= 2;
    for (i = 0; i < data_size; i += 2) {
        char bytes[3];
        int index = 4 + address_size + i;
        bytes[0] = line[index];
        bytes[1] = line[index + 1];
        bytes[2] = '\0';

        *p++ = hex2int(bytes);
    }

    return type;
}


void mot_place(mot_t* mot)
{
    char *p = (char *)mot->address;
    char *q = mot->data;

    const char *last_p = p + mot->data_size;
    while (p < last_p) {
        *p++ = *q++;
    }
}
